可见区域是一个由(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,然后将视图矩形的角偏移这些值之间的差值和视图矩形的中心。您可以在第一次按下鼠标按钮时存储这些值,并在按住鼠标按钮时使用它们进行放大。