朱莉娅用实数设定计算

时间:2017-10-31 00:40:37

标签: c algorithm math mandelbrot

我正在尝试制作一个julia设置图像并在C中编程。我曾尝试研究一种算法来创建Julia集的图像,但我对大多数在线示例感到困惑(因为大多数示例似乎都被复制了,但对逐步发生的事情几乎没有解释)。

我已经多次重写我的代码以适应我在网上找到的算法,但收效甚微。目前,我正在使用迭代函数来定义以下每个像素的颜色:

// Loop through each pixel to work out new image set
int x, y;
for(x = 0; x < SIZE; x++){
    for(y = 0; y < SIZE; y++){

        int i = iterate(x, y, maxIterations, c);
        image[x][y] = i % 256 + 255 + 255 * (i < maxIterations);

    }
}

/* Iterate function */
int iterate(int x, int y, int maxI, double c[]){
    double z, zx, zy, oldRe, oldIm;   //real and imaginary parts of new and old
    double xmin = -1.0, xmax = 1.0, ymin = -1.0, ymax = 1.0;
    int k; // number of times iterated

    //calculate the initial real and imaginary part of z
    // z0 = (x + yi)^2 + c = (0 + 0i) + c = c
    zx = 1.5*(x - SIZE/2)/(0.5*SIZE);
    zy = 1.0*(y - SIZE/2)/(0.5*SIZE);

    //start the iteration process
    for(k = 1; k < maxI; k++){
      //remember value of previous iteration
      oldRe = zx;
      oldIm = zy;
      z = zx*zx - zy*zy + c[0];

      //the actual iteration, the real and imaginary part are calculated
      zx = oldRe * oldRe - oldIm * c[1] + c[0];
      zy = 2 * oldRe * oldIm + c[1];
      zy = 2.0*zx*zy + c[1];
      zx = z;

      //if the point is outside the circle with radius 2: stop
      if((zx * zx + zy * zy) > 4) break;
}

/*
while(((zx * zx + zy * zy) > 4) && (k < maxI)) {
    //remember value of previous iteration
    z = zx*zx - zy*zy + c[0];
    zy = 2*x*y-c[1];
    zx = z;
    //if the point is outside the circle with radius 2: stop
}
return k;

}     * / 注释掉的while循环是我在网上找到的第二种算法,但也是不正确的。我不确定我在等式中缺少什么。任何猜测?

(我不是在寻找一个解决方案,只是一些可以将真实的,虚构的复数转换为我的边界框中的位置的伪代码,在这种情况下:-1,1)。

2 个答案:

答案 0 :(得分:0)

以下是我刚认证的学校项目的可读代码中的重新转录

YOUR_CR和YOUR_CI是Julia的两个可能变量, LOWER_LIMIT和UPPER_LIMIT(X和Y)对应于您想要绘制的窗口。代码应该正确地缩放输出到窗口和缩放级别以绘制分形(限制比例在分形的数学范围内,不是像素)。

# define X 0
# define Y 1

# define ZR 0
# define ZI 1
# define CR 2
# define CI 3

static int          iterations(long double coords[])
{
    long double     pos[4];
    int             i;
    double          tmp;

    pos[CR] = YOUR_CR;
    pos[CI] = YOUR_CI;
    pos[ZR] = coords[X];
    pos[ZI] = coords[Y];
    i = 0;
    while (i < MAX_ITERATIONS && (PYTHAGORE(pos[ZR], pos[ZI]) < 4))
    {
        tmp = pos[ZR];
        pos[ZR] = pos[ZR] * pos[ZR] - pos[ZI] * pos[ZI] + pos[CR];
        pos[ZI] = 2 * pos[ZI] * tmp + pos[CI];
        i++;
    }
    return (i);
}

# define TRANSLATE_X_PIXEL(a, b) ((int)(((a - LOWER_LIMIT_X) / (UPPER_LIMIT_X - LOWER_LIMIT_X)) * WIDTH))
# define TRANSLATE_Y_PIXEL(a, b) ((int)(((a - LOWER_LIMIT_Y) / (UPPER_LIMIT_Y - LOWER_LIMIT_Y)) * HEIGHT))

void                julia()
{
    long double     coords[2];
    int             itera;

    coords[X] = LOWER_LIMIT_X;
    while ((coords[X] += ((UPPER_LIMIT_X - LOWER_LIMIT_X) /
                    (double)(WIDTH + 1))) <= UPPER_LIMIT_X)
    {
        coords[Y] = LOWER_LIMIT_Y;
        while ((coords[Y] += ((UPPER_LIMIT_Y - LOWER_LIMIT_Y) /
                        (double)(HEIGHT + 1))) <= UPPER_LIMIT_Y)
        {
                itera = iterations(coords);
                set_pixel(TRANSLATE_X_PIXEL(coords[Y]), TRANSLATE_Y_PIXEL(coords[Y]), itera * DESIRED_COLOR);
        }
    }
}

答案 1 :(得分:0)

超出评论的while代码是错误的,因为它在虚部计算中使用x,y而不是zx,zy。您的代码看起来就像是采用了一种方法并在其中间粘贴了另一种方法。

你想要的经典二次Julia迭代,它是实现

的实现
znext = z*z + c = (zx+*zy)*(zx+i*zy)+(cx+*cy)
      = (zx*zx-zy*zy+cx) + i*(2*zx*zy+cy) 

您不能进行就地替换,因为zxzy都用于两个公式,并且需要保留旧值。正确的代码应该是

for(k = 1; k < maxI; k++){
    // compute the new real part, store temporarily in helper variable
    double z = zx*zx - zy*zy + c[0];
    // compute the imaginary part, since no further operations, do it in place
    zy = 2.0*zx*zy + c[1];
    //store the new real part in the real part variable
    zx = z;
    //if the point is outside the circle with radius 2: stop
    if((zx * zx + zy * zy) > 4) break;
}

如果存储方块,则需要较少的乘法,

for(k = 1; k < maxI; k++){
    double sqzx = zx*zx, sqzy = zy*zy;
    // compute the imaginary part first, since the real part only uses the squares, not zy
    zy = 2.0*zx*zy + c[1];
    // compute the new real part using the pre-computed squares
    zx = sqzx - sqzy + c[0];
    //if the point is outside the circle with radius 2: stop
    if( ( sqzx + sqzy ) > 4 ) break;
}