在Mandelbrot中使用鼠标进行平滑缩放(C)

时间:2017-01-22 22:27:45

标签: c zoom fractals mandelbrot

过去几天我一直在制作C Mandelbrot套装程序,但我设法使其工作正常,但是,我的最终目标是能够使用我的鼠标平滑地放大设置。 #39;我尚未能做到的事情,所以我可能需要一些帮助!

这是我的代码的一部分(好吧,完整的mandelbrot函数):

<head>
  <base href="https://polygit.org/polymer+1.7.1/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>

<body>
  <div>See console log</div>
  <table-list url="http://httpbin.org/get"></table-list>

  <dom-module id="table-list">
    <link rel="stylesheet" href="table-list.css" />
    <template>
      <iron-ajax url=[[url]] last-response={{response}} params=[[params]]></iron-ajax>
      <template is="dom-repeat" items="{{response.data}}" as="item">
        <div>[[item.content]]</div>
      </template>

      <a-pagination url=[[url]]
                    pagination_options={{response.pagination}}></a-pagination>
    </template>
  </dom-module>

</body>

这是输出的图片: (对不起,它不是很漂亮,颜色不是我的首要任务,但是一旦我找到变焦,我就一定会对它们进行处理!

Mandelbrot

我希望能做什么

  • 左键单击 - &gt;图像的中心变为mouse_x和mouse_y。然后,只要保持左键单击,它就会开始放大
  • 右键单击 - &gt; [...]只要点击右键,它就会开始缩小
  • 移动鼠标 - &gt;如果当前放大/缩小,图像的中心会移动到鼠标的坐标。否则没有任何反应。

已经有一个功能,可以让鼠标的位置和按钮被按下

非常感谢你的帮助!

2 个答案:

答案 0 :(得分:2)

可见区域是由(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。

或者,如果您希望在单击鼠标时视图的中心跳转到某个位置,请如上所述计算mouseRemouseIm,然后将视图矩形的角偏移这些值与视图矩形的中心之间的差异。您可以在第一次按下鼠标按钮时存储这些值,并使用它们进行放大。

答案 1 :(得分:0)

最近我为此苦了一段时间。

一个伴侣告诉我的一个非常简单且可行的解决方案如下:

double tmp_zoom = info->zoom;
if (unzoom)
   info->zoom /= ZOOM_FACTOR;
else if (zoom)
   info->zoom *= ZOOM_FACTOR;
e->Re.min += (x / tmp_zoom) - (x / info->zoom);
e->Im.min += (y / tmp_zoom) - (y / info->zoom);

声明一个tmp_zoom等于缩放,然后再使用key / mouse事件对其进行修改。根据事件修改缩放。然后,是缩放还是取消缩放,请在tmp_zoom(以前的缩放值)之前加上x s减去当前缩放的x splat。 e-> Re.min在我的程序中为 x1 。对程序中的e-> Im.min, y1 执行相同的操作,但值y。