【问题标题】:How to zoom in on cursor point in Mandelbrot Set?如何放大 Mandelbrot Set 中的光标点?
【发布时间】:2019-04-22 01:19:07
【问题描述】:

我目前正在尝试为我一直在处理的 Mandelbrot Set 代码实现缩放功能。这个想法是放大/缩小我左/右键单击的位置。到目前为止,每当我单击屏幕时,分形确实被放大了。问题是分形不是在原点呈现的——换句话说,它没有在我想要的点上放大。我希望通过这里我可以对如何放大一个点进行代码审查和概念性理解。

这是我在使用转义算法之前转换像素坐标的方式:

MandelBrot.Frag

vec2 normalizedFragPos = (gl_FragCoord.xy/windowSize); //normalize fragment position

dvec2 scaledFragPos = normalizedFragPos*aspectRatio;

scaledFragPos -= aspectRatio/2; //Render the fractal at center of window

scaledFragPos /= scale; //Factor to zoom in or out coordinates.

scaledFragPos -= translation; //Translate coordinate
//Escape Algorithm Below

在我的左键单击手柄上,我认为我应该将光标位置转换为与 Mandelbrot Range 相同的坐标范围。所以我基本上做了和片段着色器一样的事情:

窗口.cpp

float x_coord{ float(GET_X_LPARAM(informaton_long))/size.x }; // normalized mouse x-coordinate
float y_coord{ float(GET_Y_LPARAM(informaton_long))/size.y }; // normalized mouse y-coordinate

x_coord *= aspectRatio[0]; //move point based of relative position to length of window.
y_coord *= aspectRatio[1]; //move point based of relative position to width of window.
x_coord /= scale; //Scale point to match previous zoom factor
y_coord /= scale; //Scale point to match previous zoom factor
translation[0] = x_coord;
translation[1] = y_coord;
//increment scale
scale += .15f;

【问题讨论】:

    标签: c++ opengl zooming translation


    【解决方案1】:

    让我们应用一些代数。您的着色器执行以下转换:

    mandelbrotCoord = aspectRatio * (gl_FragCoord / windowSize - 0.5) / scale - translation
    

    当我们放大mouseCoord时,我们想改变scale并调整translation,使鼠标下的madelbrotCoord保持不变。为此,我们首先使用旧比例计算鼠标下的mandelbrotCoord

    mandelbrotCoord = aspectRatio * (mouseCoord / windowSize - 0.5) / scale - translation
    

    然后改变比例(应该以指数方式改变 BTW):

    scale *= 1.1;
    

    然后求解新的翻译:

    translation = aspectRatio * (mouseCoord / windowSize - 0.5) / scale - mandelbrotCoord
    

    还请注意,您的系统可能报告鼠标坐标,y 坐标向下增加,而 OpenGL 的窗口y 坐标向上增加(除非您用glClipControl 覆盖它)。因此,您可能还需要翻转mouseCoordy 坐标。

    mouseCoord[1] = windowSize[1] - mouseCoord[1];
    

    为了获得最佳效果,我还将鼠标坐标调整到像素的中间(+0.5,+0.5)。

    把它们放在一起:

    float mouseCoord[] = {
        GET_X_LPARAM(informaton_long) + 0.5,
        GET_Y_LPARAM(informaton_long) + 0.5
    };
    mouseCoord[1] = size[1] - mouseCoord[1];
    
    float anchor[] = {
        aspectRatio[0] * (mouseCoord[0] / size[0] - 0.5) / scale - translation[0],
        aspectRatio[1] * (mouseCoord[1] / size[1] - 0.5) / scale - translation[1]
    };
    
    scale *= 1.1;
    
    translation[0] = aspectRatio[0] * (mouseCoord[0] / size[0] - 0.5) / scale - anchor[0];
    translation[1] = aspectRatio[1] * (mouseCoord[1] / size[1] - 0.5) / scale - anchor[1];
    

    注意:上面的一些数学运算可能会被取消。但是,如果您想实现适当的平移和缩放功能(当您可以在平移时使用鼠标滚轮进行缩放时),那么您需要存储平移开始位置的初始 mandelbrotCoord,然后在后续动作中重复使用它和滚轮事件,直到鼠标被释放。令人惊讶的是,大量的图像查看者都弄错了这部分!

    【讨论】:

    • 老兄,非常感谢您完美地解释它!虽然我知道缩放点在新的和旧的比例中都保持不变,但我无法拼凑出如何使用鼠标坐标来获得新的翻译。我简单地将鼠标指向的曼德布罗坐标也视为平移值。再次感谢,我已经为这个 smh 挠头 3 天了!
    猜你喜欢
    • 2023-03-03
    • 2019-05-08
    • 1970-01-01
    • 2011-08-08
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多