【问题标题】:How do I zoom on cursor position in mandelbrot or julia set?如何放大 mandelbrot 或 julia 集中的光标位置?
【发布时间】:2023-03-03 02:33:02
【问题描述】:

我现在正在编写一个分形探索器,但在放大场景中的某个点时卡住了。例如,我的 Julia 集的绘图函数如下所示:

void *julia_thread(void *param)
{
    int x, y, temp;
    long double re, aux, im;
    int start = ((int *)param)[0];
    int end = ((int *)param)[1];
    int iterations;


    for (x = start; x < end; x++)
        for (y = 0; y < WIN_SIZE; y++)
        {
            re = range_change(zoom_factor, x, mv_x);
            im = range_change(zoom_factor, y, mv_y);
            iterations = 0;
            while (!blowing_up(re, im) && iterations < max_iter)
            {
                aux = re;
                re = re * re - im * im + re_c;
                im = 2 * aux * im + im_c;
                iterations++;
            }
            put_pixel(img, x, y, color_table[iterations]);
        }
    return NULL;
}

计算 Z 的实部和虚部的初始值的函数是这样的:

long double range_change(long double zoom_factor, int value, long double mv)
{
    long double newmax = 2 / zoom_factor;
    long double newmin = -2 / zoom_factor;

    return ((long double)value * (newmax - newmin)) / WIN_SIZE + newmin + mv;
}

所以我得到一个按比例缩小的值,它是分形存在的区间的一部分,并根据迭代次数为该特定像素分配颜色。通过将两端除以一个因子,使实际间隔 (-2, 2) 更小,缩放效果很好。这可行,但我似乎无法弄清楚如何放大中心以外的某个位置。我可以通过向实部和虚部 (x, y) 添加一个数字来四处移动并最终到达该点,但我无法放大由光标位置给我的屏幕 (x, y) 确定的点。

【问题讨论】:

  • 在哪里以及如何设置((int *)param) 值?这些为您提供x 的起始值和结束值;您可以立即从中计算出您的相对水平光标位置。 (虽然我不确定您为什么不对y 做同样的事情。)它有助于将您的计算可视化为不仅是 zoom 而是作为 translation好吧。
  • 这只是为了将工作分成 4 个相等的部分,这样我就可以使用多个线程(如果我有 600 个像素,第一个线程执行像素 0 到 150 等等),我有光标 x和 y 因为当用户滚动时调用一个函数。我的问题是如何将缩放发生的点从分形的中心更改为光标所在的任何点。
  • 您能否以另一种方式调试或输出(mv_x,mv_y) 的实际值在julia_thread 中使用的是什么?对于 zoom_factor 1 或 2,它应该按预期工作,对于所有其他的,它根本不应该工作,返回一个单色方块。

标签: c math fractals


【解决方案1】:

不加选择地进行整数除法是一个非常糟糕的主意:

2 / zoom_factor

如果zoom_factor 大于2,将返回0。将2 替换为2.0 以强制浮点除法,这应该足以修复代码。


如果我的解释正确,您希望屏幕窗口代表坐标或分形平面中的一个正方形,其宽度和高度为 4.0/zoom_factor,围绕点 (mv_x, mv_y)

mv 位于WIN_SIZE/2,因此

coord = mv + ( 4*value/WIN_SIZE - 2 )/zoom_factor

完全可以这样实现

return mv + ( (4.0*value)/WIN_SIZE - 2.0 )/zoom_factor;

并且使用因子4.0,分母的类型为双精度,除法以双精度进行。


慢推导

函数range_change要实现的是坐标的线性变化

coord = A*screen + B

其中screen 是输入屏幕坐标,coord 是 Julia 分形的笛卡尔平面中的坐标。端点映射是

screen=0         --> coord = center - 2.0/zoom
screen=WIN_SIZE  --> coord = center + 2.0/zoom

从第一个我们读到B=center - 2.0/zoom 和从第二个公式

A*WIN_SIZE + center - 2.0/zoom = center + 2.0/zoom
A*WIN_SIZE                     =          4.0/zoom
A = 4.0/(zoom*WIN_SIZE)

给出转换公式

coord = (4.0*value)/(zoom*WIN_SIZE) + center - 2.0/zoom
      = ( (4.0*value)/WIN_SIZE - 2.0 )/zoom + center 

【讨论】:

  • 什么分形维数(这是一个标准的数学概念,也称为 Hausdorff 维数)?但你是对的,以前的版本会给出从mv-0.5/zoom_factormv-0.5/zoom_factor 的真实坐标,这与规定的像素大小相矛盾。现在从mv-(0.5*WIN_SIZE)/zoom_factormv+(0.5*WIN_SIZE)/zoom_factor
  • 你在哪里找到你的指控?分形是某个向量空间中的点集,在一定变换下具有自相似性。计算机图形学中所谓的 Julia 或 Mandelbrot 集是这些分形集的某种彩色距离图。正方形 [-2,2]×[-2,2] 或 [-2.5,1.5]×[-2,2] 是这些颜色图的视口,第一个通常用于完整的 Julia,第二个用于完整的 Mandelbrot设置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 2017-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-14
相关资源
最近更新 更多