Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/409.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我得到的是圆而不是曼德布罗特_Javascript_Math_Mandelbrot - Fatal编程技术网

Javascript 我得到的是圆而不是曼德布罗特

Javascript 我得到的是圆而不是曼德布罗特,javascript,math,mandelbrot,Javascript,Math,Mandelbrot,我试图严格遵循公式,但不知怎的,我得到的只是一个圆。这是在mandelbrot集合坐标中,我非常理解 for(x=-50;x<50;x++){ for(y=-50;y<50;y++){ // Canvas pixel coordinates to -2,2 var x2 = x * 0.04; var y2 = y * 0.04; var i = 0; var z = 0; var c = Math.sqrt( x2*x2 +

我试图严格遵循公式,但不知怎的,我得到的只是一个圆。这是在mandelbrot集合坐标中,我非常理解

for(x=-50;x<50;x++){
  for(y=-50;y<50;y++){

    // Canvas pixel coordinates to -2,2
    var x2 = x * 0.04;
    var y2 = y * 0.04;

    var i = 0;
    var z = 0;
    var c = Math.sqrt( x2*x2 + y2*y2 );

    while(true) {

      if( i > 20 || z > 4.0 ) {
        break;
      }

      z = z*z + c;

      i = i + 1;
    }
  }
}
jsFiddle:
您需要执行复杂的算术运算

var x3 = 0, y3 = 0, k = 0;
while (x3*x3 + y3*y3 < 16 && k++ < 20) {
   var tmp = x3*x3 - y3*y3 + x2;
   y3 = 2*x3*y3 + y2;
   x3 = tmp;
}
公式为zk+1=zk2+c,其中z0=0或相当于z1=c 其中c是当前位置,即c=x2+i⋅y2。 我有z=x3+I⋅y3 so z2=x3+i⋅y32=x32+2⋅我⋅x3⋅y3+i2⋅y32。 带i2=−1这简化为z2=x32− y32+i⋅2.⋅x3⋅y3,加上c,即x2和y2

见现场演示

原始代码放弃了z=Math.sqrt x2*x2+y2*y2步骤中的角度信息,因为在该点之后没有使用x2和y2。因此,产生的颜色必须与角度无关,即由同心圆组成

处理复数的绝对值。但是Mandelbrot公式的迭代步骤应该按原样对复数进行操作,而不是对复数的任何绝对值进行操作,因此遵循该公式是不合适的

绝对值有一个有效的应用,即在决定是否终止循环(即检测发散)时。只是写

zn的模量长度超过给定值

没有明确给出阈值。我使用了4的阈值,但是我通过测试z长度的平方是否超过16来避免平方根。这就是我代码中x3*x3+y3*y3<16的来源。使用2作为阈值(即平方测试的4)更为常见,但我觉得使用4更接近您的代码,即更适合强调比较绝对值和比较其平方之间的区别。使用4而不是2可能会导致稍后检测发散,从而在循环退出时导致计数器变量的值稍高


请注意,还有一些伪代码,您可以将其用作起点,并在本文的其余部分解释代码中的实值运算与复数运算的关系。

您需要执行复数运算

var x3 = 0, y3 = 0, k = 0;
while (x3*x3 + y3*y3 < 16 && k++ < 20) {
   var tmp = x3*x3 - y3*y3 + x2;
   y3 = 2*x3*y3 + y2;
   x3 = tmp;
}
公式为zk+1=zk2+c,其中z0=0或相当于z1=c 其中c是当前位置,即c=x2+i⋅y2。 我有z=x3+I⋅y3 so z2=x3+i⋅y32=x32+2⋅我⋅x3⋅y3+i2⋅y32。 带i2=−1这简化为z2=x32− y32+i⋅2.⋅x3⋅y3,加上c,即x2和y2

见现场演示

原始代码放弃了z=Math.sqrt x2*x2+y2*y2步骤中的角度信息,因为在该点之后没有使用x2和y2。因此,产生的颜色必须与角度无关,即由同心圆组成

处理复数的绝对值。但是Mandelbrot公式的迭代步骤应该按原样对复数进行操作,而不是对复数的任何绝对值进行操作,因此遵循该公式是不合适的

绝对值有一个有效的应用,即在决定是否终止循环(即检测发散)时。只是写

zn的模量长度超过给定值

没有明确给出阈值。我使用了4的阈值,但是我通过测试z长度的平方是否超过16来避免平方根。这就是我代码中x3*x3+y3*y3<16的来源。使用2作为阈值(即平方测试的4)更为常见,但我觉得使用4更接近您的代码,即更适合强调比较绝对值和比较其平方之间的区别。使用4而不是2可能会导致稍后检测发散,从而在循环退出时导致计数器变量的值稍高


请注意,其中还有一些伪代码,您可能会将其用作起点,并解释代码中的实值运算与本文其余部分中的复数运算的关系。

您犯了一个数学错误。C、Z是复数,但您将其视为实数

我已经对你的代码做了最小限度的修改,使它按预期工作

var canvas = $('canvas');
var ctx = canvas[0].getContext('2d');

for(x=-50;x<50;x++){
    for(y=-50;y<50;y++){

    var x2 = x * 0.04;
    var y2 = y * 0.04;

    var i = 0;
    var z = 0;
    //c - complex number. so c = x2+i*y2, where i^2 =-1 
    //var c = Math.sqrt( x2*x2 + y2*y2 );
    var xi= x2;
    var yi=y2;

    while(true) {


      if( i > 50 || xi*xi+yi*yi > 4.0 ) {
        break;
      }

      // z - complex number, so on every step we should calculate real and imaginary parts
      //z^2 = (x^2-y^2)+i*(2*x*y), i^2 =-1
      var tmp = xi*xi - yi*yi+x2;
      yi = 2*xi*yi+y2;
      xi = tmp;
      i = i + 1;
    }

    var color = parseInt(15/21*i).toString(16);
    ctx.fillStyle = '#'+color+color+color;

    ctx.fillRect((x+50)*2,(y+50)*2,2,2);
  }
}

你犯了一个数学错误。C,Z是复数,但你把它们当作实数

我已经对你的代码做了最小限度的修改,使它按预期工作

var canvas = $('canvas');
var ctx = canvas[0].getContext('2d');

for(x=-50;x<50;x++){
    for(y=-50;y<50;y++){

    var x2 = x * 0.04;
    var y2 = y * 0.04;

    var i = 0;
    var z = 0;
    //c - complex number. so c = x2+i*y2, where i^2 =-1 
    //var c = Math.sqrt( x2*x2 + y2*y2 );
    var xi= x2;
    var yi=y2;

    while(true) {


      if( i > 50 || xi*xi+yi*yi > 4.0 ) {
        break;
      }

      // z - complex number, so on every step we should calculate real and imaginary parts
      //z^2 = (x^2-y^2)+i*(2*x*y), i^2 =-1
      var tmp = xi*xi - yi*yi+x2;
      yi = 2*xi*yi+y2;
      xi = tmp;
      i = i + 1;
    }

    var color = parseInt(15/21*i).toString(16);
    ctx.fillStyle = '#'+color+color+color;

    ctx.fillRect((x+50)*2,(y+50)*2,2,2);
  }
}

你能链接到你试图遵循的公式吗?它可以让你更容易发现错误。你的代码与@jamice上的代码不太一样,我用这个来表示复数:曼德尔布罗特的算法:你能链接到你试图遵循的公式吗?它可能会让你更容易发现错误。您的代码与@jamice上的代码不太一样,我用这个来表示复数:曼德尔布罗特的算法:谢谢,非常有见地的回答。谢谢, 这是一个很有见地的回答。