如何在Mandelbrot集中放大光标点?

时间:2019-04-22 01:19:08

标签: c++ opengl zoom translation

我目前正在尝试为我一直在努力的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范围相同的坐标范围。因此,我基本上做了与片段着色器相同的操作:

Window.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;

1 个答案:

答案 0 :(得分:0)

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

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覆盖它)。因此,您可能还需要翻转y的{​​{1}}坐标。

mouseCoord

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

将它们放在一起:

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

注意:上面的一些数学运算可能会被取消。但是,如果您想实现适当的平移和缩放功能(在平移时可以使用鼠标滚轮进行缩放),则需要存储平移开始的位置的初始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]; ,然后在其上重新使用随后的运动和滚轮事件,直到释放鼠标为止。令人惊讶的是,大量的图像查看器弄错了这个部分!