Mandelbrot 的算法在不使用复数的情况下无法给出所需的结果
Mandelbrot's algorithm not giving the desired result without using complex numbers
当我使用以下算法来使用 mandelbrot 算法时,我得到的图像与我想要的图像相似,但它看起来更像是最终图像的轮廓,当我使用具有复数的算法时,它给出了适当清晰的图像
代码是用c++写的
//pseudocode
//z=x+yi //x=0,y=0
//c=x0+y0i //x=scaled(px),y=scaled(py)
//do
//z2=x2+(2*xy)i-y2
//z=z2+c //z=x2-y2+x0+(2*xy+y0)i
//x=x2-y2+x0 //y=2*xy+y0
//x2=x*x //y2=y*y
//if(sqrt(x2+y2)<2 )
// break
//iteration++
//while( iteration<max_iteration)
//code without complex numbers
int mandelbrot::_test_num_iteration( double px, double py ) {
double x0{ scale_x( px ) }, x{ 0 };
double y0{ scale_y( py ) }, y{ 0 };
double x2{ 0 }, y2{ 0 };
//z=x+iy c=x0+iy0
int iteration{ 0 };
while (iteration < max_iteration) { //for instance max_iteration=1000
x2 = x * x; y2 = y * y;
x = x2 + x0 - y2; y = 2 * x * y + y0;
x2 = (x * x); y2 = (y * y);
if (sqrt(( x2 + y2 )) > 2)
break;
iteration++;
}
return iteration;
}
//code with complex numbers
int mandelbrot::get_iteration( double px, double py) {
//x+iy=z
//z2=x2+(2*xyi)-y2
//c=x0+iy0
//x0&y0=scaled x and y coordinates
double x{ scale_x( px ) };
double y{ scale_y( py ) };
complex::complex_numbers z;
complex::complex_numbers c{ x,y };
int iteration{ 0 };
while (iteration < max_iteration) {
z = z * z + c;
if (mod( z ) > 2) //mod is a function which returns sqrt(x2+y2)
break;
iteration++;
}
return iteration;
}
此块中有一个错误:
x2 = x * x; y2 = y * y;
x = x2 + x0 - y2; y = 2 * x * y + y0;
您尝试实施 z*z+c
。但是,在第二行中,您将“z”的实部更改为实部减去虚部再加上常数的平方。这时候z的实部已经更新了。接下来更新 y(虚部与更新后的实部)。哎呀
我会逐行查看并检查您对复数运算的实现是否确实按照预期进行。如果您不知道如何使用调试器,请使用一些 cout <<
语句。
编辑:删除了不正确的 sqrt(x2+y2)
评论。
问题是您没有根据旧值计算两个新值。
这里,
x = x2 + x0 - y2; y = 2 * x * y + y0;
您正在为新 y
使用新 x
。
您需要几个变量来临时存储更新后的值。
double new_x = x2 - y2 + x0;
double new_y = 2 * x * y + y0;
x = new_x;
y = new_y;
当我使用以下算法来使用 mandelbrot 算法时,我得到的图像与我想要的图像相似,但它看起来更像是最终图像的轮廓,当我使用具有复数的算法时,它给出了适当清晰的图像
代码是用c++写的
//pseudocode
//z=x+yi //x=0,y=0
//c=x0+y0i //x=scaled(px),y=scaled(py)
//do
//z2=x2+(2*xy)i-y2
//z=z2+c //z=x2-y2+x0+(2*xy+y0)i
//x=x2-y2+x0 //y=2*xy+y0
//x2=x*x //y2=y*y
//if(sqrt(x2+y2)<2 )
// break
//iteration++
//while( iteration<max_iteration)
//code without complex numbers
int mandelbrot::_test_num_iteration( double px, double py ) {
double x0{ scale_x( px ) }, x{ 0 };
double y0{ scale_y( py ) }, y{ 0 };
double x2{ 0 }, y2{ 0 };
//z=x+iy c=x0+iy0
int iteration{ 0 };
while (iteration < max_iteration) { //for instance max_iteration=1000
x2 = x * x; y2 = y * y;
x = x2 + x0 - y2; y = 2 * x * y + y0;
x2 = (x * x); y2 = (y * y);
if (sqrt(( x2 + y2 )) > 2)
break;
iteration++;
}
return iteration;
}
//code with complex numbers
int mandelbrot::get_iteration( double px, double py) {
//x+iy=z
//z2=x2+(2*xyi)-y2
//c=x0+iy0
//x0&y0=scaled x and y coordinates
double x{ scale_x( px ) };
double y{ scale_y( py ) };
complex::complex_numbers z;
complex::complex_numbers c{ x,y };
int iteration{ 0 };
while (iteration < max_iteration) {
z = z * z + c;
if (mod( z ) > 2) //mod is a function which returns sqrt(x2+y2)
break;
iteration++;
}
return iteration;
}
此块中有一个错误:
x2 = x * x; y2 = y * y;
x = x2 + x0 - y2; y = 2 * x * y + y0;
您尝试实施 z*z+c
。但是,在第二行中,您将“z”的实部更改为实部减去虚部再加上常数的平方。这时候z的实部已经更新了。接下来更新 y(虚部与更新后的实部)。哎呀
我会逐行查看并检查您对复数运算的实现是否确实按照预期进行。如果您不知道如何使用调试器,请使用一些 cout <<
语句。
编辑:删除了不正确的 sqrt(x2+y2)
评论。
问题是您没有根据旧值计算两个新值。
这里,
x = x2 + x0 - y2; y = 2 * x * y + y0;
您正在为新 y
使用新 x
。
您需要几个变量来临时存储更新后的值。
double new_x = x2 - y2 + x0;
double new_y = 2 * x * y + y0;
x = new_x;
y = new_y;