在 Mandelbrot 集中使用鼠标平滑缩放 (C)
Smooth Zoom with mouse in Mandelbrot set (C)
过去几天我一直在研究 C Mandelbrot 集合程序,我设法让它工作得很好,但是,我的最终目标是能够用我的鼠标平滑地放大集合,那就是有些事情我还没有做到,所以我可能需要一些帮助!
这是我的部分代码(嗯,完整的 mandelbrot 函数):
//removed to free space
这是一张输出图片:
(抱歉,它不是很漂亮,颜色不是我的首要任务,但我一定会在弄清楚缩放后立即处理它们!)
Mandelbrot
我希望能够做什么 :
- 左键单击 -> 图像中心变为 mouse_x 和 mouse_y。然后,只要按住左键,它就会开始放大
- 右击 -> [...] 只要按住右击它就会开始缩小
- 移动鼠标 -> 如果当前正在缩放 in/out,图像的中心随之移动到鼠标坐标。否则什么也不会发生。
(已有获取鼠标位置和按键按下的功能)
非常感谢您的帮助!
可见区域是由(Re.min, Im.min)
和(Re.max, Im.max)
定义的矩形。当您单击特定点时,您可以将鼠标位置映射到一个点 (mouseRe, mouseIm)
,方法是使用与渲染时相同的映射:
double mouseRe = (double)mouse_x / (WIN_L / (e->Re.max - e->Re.min)) + e->Re.min;
double mouseIm = (double)mouse_y / (WIN_H / (e->Im.max - e->Im.min)) + e->Im.min;
放大,想象从(mouseRe, mouseIm)
缩放中心点到可见区域的每个角画一条线,形成一个不对称的X。根据缩放量,找到4个新点一定分数沿这些线的距离,这些点将为您提供新的矩形。例如,如果您要放大 3 倍,请在从中心点到角点的 1/3 处找到一个点。这将产生一个新的矩形,边长是原始矩形的 1/3,面积是原始矩形的 1/9。
为此,您可以定义一个简单的插值函数:
double interpolate(double start, double end, double interpolation)
{
return start + ((end - start) * interpolation);
}
然后使用函数找到你的新点:
void applyZoom(t_fractal* e, double mouseRe, double mouseIm, double zoomFactor)
{
double interpolation = 1.0 / zoomFactor;
e->Re.min = interpolate(mouseRe, e->Re.min, interpolation);
e->Im.min = interpolate(mouseIm, e->Im.min, interpolation);
e->Re.max = interpolate(mouseRe, e->Re.max, interpolation);
e->Im.max = interpolate(mouseIm, e->Im.max, interpolation);
}
根据我的描述,您可能认为您需要找到 8 个值(X 的 4 条腿的 4 个点,每个 2 维)但实际上只有 4 个唯一值,因为每条边都是轴对齐。
要平滑缩放,请使用略高于 1.0 的缩放系数调用它,例如1.01。要缩小,请传递倒数,例如1.0 / 1.01.
或者,如果你希望点击鼠标时视图的中心跳到某个位置,如上计算mouseRe
和mouseIm
,然后偏移视图矩形的角通过这些值与视图矩形中心之间的差异。您可以在第一次按下鼠标按钮时存储这些值,并在按住鼠标按钮时使用它们进行放大。
过去几天我一直在研究 C Mandelbrot 集合程序,我设法让它工作得很好,但是,我的最终目标是能够用我的鼠标平滑地放大集合,那就是有些事情我还没有做到,所以我可能需要一些帮助!
这是我的部分代码(嗯,完整的 mandelbrot 函数):
//removed to free space
这是一张输出图片: (抱歉,它不是很漂亮,颜色不是我的首要任务,但我一定会在弄清楚缩放后立即处理它们!)
Mandelbrot
我希望能够做什么 :
- 左键单击 -> 图像中心变为 mouse_x 和 mouse_y。然后,只要按住左键,它就会开始放大
- 右击 -> [...] 只要按住右击它就会开始缩小
- 移动鼠标 -> 如果当前正在缩放 in/out,图像的中心随之移动到鼠标坐标。否则什么也不会发生。
(已有获取鼠标位置和按键按下的功能)
非常感谢您的帮助!
可见区域是由(Re.min, Im.min)
和(Re.max, Im.max)
定义的矩形。当您单击特定点时,您可以将鼠标位置映射到一个点 (mouseRe, mouseIm)
,方法是使用与渲染时相同的映射:
double mouseRe = (double)mouse_x / (WIN_L / (e->Re.max - e->Re.min)) + e->Re.min;
double mouseIm = (double)mouse_y / (WIN_H / (e->Im.max - e->Im.min)) + e->Im.min;
放大,想象从(mouseRe, mouseIm)
缩放中心点到可见区域的每个角画一条线,形成一个不对称的X。根据缩放量,找到4个新点一定分数沿这些线的距离,这些点将为您提供新的矩形。例如,如果您要放大 3 倍,请在从中心点到角点的 1/3 处找到一个点。这将产生一个新的矩形,边长是原始矩形的 1/3,面积是原始矩形的 1/9。
为此,您可以定义一个简单的插值函数:
double interpolate(double start, double end, double interpolation)
{
return start + ((end - start) * interpolation);
}
然后使用函数找到你的新点:
void applyZoom(t_fractal* e, double mouseRe, double mouseIm, double zoomFactor)
{
double interpolation = 1.0 / zoomFactor;
e->Re.min = interpolate(mouseRe, e->Re.min, interpolation);
e->Im.min = interpolate(mouseIm, e->Im.min, interpolation);
e->Re.max = interpolate(mouseRe, e->Re.max, interpolation);
e->Im.max = interpolate(mouseIm, e->Im.max, interpolation);
}
根据我的描述,您可能认为您需要找到 8 个值(X 的 4 条腿的 4 个点,每个 2 维)但实际上只有 4 个唯一值,因为每条边都是轴对齐。
要平滑缩放,请使用略高于 1.0 的缩放系数调用它,例如1.01。要缩小,请传递倒数,例如1.0 / 1.01.
或者,如果你希望点击鼠标时视图的中心跳到某个位置,如上计算mouseRe
和mouseIm
,然后偏移视图矩形的角通过这些值与视图矩形中心之间的差异。您可以在第一次按下鼠标按钮时存储这些值,并在按住鼠标按钮时使用它们进行放大。