朱莉娅集查看器

Julia Set Viewer

我一直在尝试在我的站点上制作一个 julia 集查看器 http://thejamespaterson.com/scripts/julia/,但我目前无法让程序显示正确的 julia 集。例如,当使用 C 值 0+0i 进行测试时,我得到以下图像: 结果应该是一个圆圈。我不确定为什么会这样。我写了自己的复数库和绘图函数,它们贴在下面。任何帮助将不胜感激;

function complexNum(real, imaginary) {
  this.real = real;
  this.imaginary = imaginary;
  return this;
}

function addComplex(c1, c2) {
  this.real = c1.real + c2.real;
  this.imaginary = c1.imaginary + c2.imaginary;
  return this;
}

function multComplex(c1, c2) {
  this.real = (c1.real * c2.real) - (c1.imaginary * c2.imaginary);
  this.imaginary = (c1.real * c2.imaginary) + (c2.real * c1.imaginary);
  return this;
}

function dispComplex(c) {
  var sign = '';
  if (c.imaginary >= 0) {
    sign = '+';
  }
  return c.real + sign + c.imaginary + "i";
}

function getComplexModulus(c) {
  return Math.sqrt((c.real * c.real) + (c.imaginary * c.imaginary));
}

//globals
var MAXITERATION = 100;
var BOUNDARY = 4;
var CANVASID = "juliaDraw";
var CONTEXT = document.getElementById("juliaDraw").getContext('2d');
var HEIGHT = 750;
var WIDTH = 750;
var juliaImageData = CONTEXT.createImageData(WIDTH, HEIGHT);

function readInput(inputID) {
  return document.getElementById(inputID).value;
}

function drawPointOnCanvas(x, y, color) {
  //console.log('drawing pixel at '+x+','+y);
  CONTEXT.fillStyle = color;
  CONTEXT.fillRect(x, y, 1, 1);
}

function createArray(length) {
  var arr = new Array(length || 0),
    i = length;
  if (arguments.length > 1) {
    var args = Array.prototype.slice.call(arguments, 1);
    while (i--) arr[length - 1 - i] = createArray.apply(this, args);
  }
  return arr;
}

function doesPointEscape(c, complexNum) {
  var iterations = 0;
  var escaped = false;
  while ((!escaped) && (iterations < MAXITERATION)) {
    if (getComplexModulus(complexNum) > BOUNDARY) {
      escaped = true;
    }
    complexNum = addComplex(multComplex(complexNum, complexNum), c);
    iterations++;
  }
  if (escaped) {
    return true;
  } else {
    return false;
  }
}

function plotJuliaSet(canvasID, width, height, c, start, stepsize) {
  var complexNumberArray = createArray(width + 1, height + 1);
  var doesPointEscapeArray = createArray(width + 1, height + 1);
  var real = start.real;
  var imaginary = start.imaginary;
  console.log('====Drawing Set====');
  console.log('c = ' + dispComplex(c));
  for (var x = 0; x <= width; x++) {
    imaginary = start.imaginary;
    for (var y = 0; y <= height; y++) {
      complexNumberArray[x][y] = new complexNum(real, imaginary);
      doesPointEscapeArray[x][y] = doesPointEscape(c, complexNumberArray[x][y]);
      if (doesPointEscapeArray[x][y]) {
        //drawPointOnCanvas(x, y,'blue');
      } else {
        drawPointOnCanvas(x, y, 'black');
        //console.log('point '+dispComplex(complexNumberArray[x][y])+' does not escape');
      }
      imaginary = imaginary - stepsize;
    }
    real = real + stepsize;
  }
  //CONTEXT.putImageData(juliaImageData, 0, 0);
  console.log('done');
}

function defaultDraw() {
  CONTEXT.clearRect(0, 0, WIDTH, HEIGHT);
  var start = new complexNum(-2, 2);
  var c = new complexNum(0, 0);
  plotJuliaSet(CANVASID, WIDTH, HEIGHT, c, start, 2 / 350);
}

function drawJulia() {
  CONTEXT.clearRect(0, 0, WIDTH, HEIGHT);
  var start = new complexNum(-2, 2);
  var c = new complexNum(readInput('realValue') * 1, readInput('imagValue') * 1);
  plotJuliaSet(CANVASID, WIDTH, HEIGHT, c, start, 2 / 350);
}
<!doctype html>
<html>

<head>
  <title>Julia Set Viewer</title>
  <style>
    .desc {
      float: right;
      width: 300px;
    }
    #juliaDraw {
      border: 1px dotted;
      float: left;
    }
  </style>
</head>

<body>
  <div class="desc">
    <h1>Julia Set Viewer</h1>
    <p>You can view Julia sets with this simple online tool. Don't know what a Julia set is? Learn about it <a href="https://www.youtube.com/watch?v=2AZYZ-L8m9Q">here.</a>
      This script uses a complex number library that I built to handle the arithmetic required to process these images. The source code is hosted on my <a href="https://github.com/jamjar919">github.</a>
    </p>
  </div>
  <canvas id="juliaDraw" width=750 height=750 onClick="defaultDraw()"></canvas>
  <div class="controls">
    <form>
      <label>Real:
        <input type="text" id="realValue" value="0">
      </label>
      <label>Imag:
        <input type="text" id="imagValue" value="0">
      </label>
      <input type="button" onClick="drawJulia()">
    </form>
  </div>
  <script src="complex.js"></script>
  <script src="juliaset.js"></script>
</body>

</html>

问题源于对 Javascript 中 this 指针使用的混淆。

将 doesPointEscape() 中的 Julia 计算更改为

complexNum = new addComplex(new multComplex(complexNum, complexNum), c);

而且有效。

这将 return 来自 multComplex 的新复数,然后将其添加到 c 和 return 来自 addComplex 的新复数分配给 complexNum。

您的 multComplex 和 addComplex 函数使用 this 指针,但要使 this 指针指向您的复数之一,您必须在现有复数上调用该函数,或调用 new 创建一个新的。

或者,您可以将 multComplex() 和 addComplex() 函数重写为

function multComplex(c1, c2) {
    var real = (c1.real * c2.real) - (c1.imaginary * c2.imaginary);
    var imaginary = (c1.real * c2.imaginary) + (c2.real * c1.imaginary);
    return new ComplexNum(real, imaginary);
}

function addComplex(c1, c2) {
    var real = c1.real + c2.real;
    var imaginary = c1.imaginary + c2.imaginary;
    return new ComplexNum(real, imaginary);
}

那么您的 doesPointEscape() 函数应该按原样工作。