【问题标题】:Implementing smooth coloring of Mandelbrot set实现 Mandelbrot 集的平滑着色
【发布时间】:2019-05-07 12:10:53
【问题描述】:

重新创建我为 Mandelbrot 集着色的方式我很难在 JavaScript 中实现它。我目前使用常见的“逃生时间”算法:

 for(px = 0; px < a; px+=scale){
   for(py = 0; py < b; py+=scale){
    x0 = panX + px/zm;
    y0 = panY + py/zm;

    var x = 0;
    var y = 0;

    var i = 0;
     var xtemp;

     var xSquare = x*x;
     var ySquare = y*y;

    while (x*x + y*y <= 4  &&  i < maxI) {
      xtemp = x*x - y*y + x0
      y = 2*x*y + y0
      x = xtemp
          i += 1;
    }

    //coloring
    var shade = pallete.colourAt(i);
    c.fillStyle = "#"+shade;
    c.fillRect(px,py,scale, scale);
    }
 }

这是full code.,我想在Wikipedia找到的这个伪代码实现上面的部分。

对于屏幕上的每个像素 (Px, Py),执行:{ x0 = scaled x 坐标 像素数(按 Mandelbrot X 比例缩放 (-2.5, 1))y0 = 像素的缩放 y 坐标(缩放到位于 Mandelbrot Y 比例尺中) (-1, 1)) x = 0.0 y = 0.0 迭代 = 0 max_iteration = 1000 // 这里 选择 N=2^8 作为合理的救助半径。而 ( xx + yy x - yy + x0 y = 2*xy + y0 x = xtemp 迭代 = 迭代 + 1 } // 用来避免 集合内的点的浮点问题。如果 ( 迭代 x + y*y ) / 2 nu = log( log_zn / log(2) ) / log(2) // 重新排列势函数。 //除法 log_zn by log(2) 而不是 log(N = 1linear_interpolate(color1, color2, iteration % 1) plot(Px, Py, color) }

到这里:

for(px = 0; px < a; px+=scale){
  for(py = 0; py < b; py+=scale){
    //zoom factors
    x0 = panX + px/zm;
    y0 = panY + py/zm;

    var x = 0;
    var y = 0;

    var i = 0;
    var xtemp;

    var xSquare = x*x;
    var ySquare = y*y;

    while (x*x + y*y <= 4  &&  i < maxI) {
      /*ticks++
      xtemp = x*x - y*y + x0
      y = 2*x*y + y0
      x = xtemp
      i = i + 1*/

      y = x*y;
      y += y;
      y += y0;

      x = xSquare - ySquare + x0;
      xSquare = Math.pow(x,2);
      ySquare = Math.pow(y,2);
      i += 1;
    }


    if ( i < maxI ) {

    log_zn = Math.log( x*x + y*y ) / 2
    nu = Math.log( log_zn / Math.log(2) ) / Math.log(2)



    i += 1 - nu
    }
    color1 = palette.colourAt(Math.floor(i))
    color2 = palette.colourAt(Math.floor(i) + 1)

    /*****************
    I dont know how to implement this.....
    color = linear_interpolate(color1, color2, iteration % 1)
    *****************/

    c.fillStyle = color
    c.fillRect(px,py,scale, scale);
    }
}

但是我不知道这部分伪代码如何实现:

color1 = palette[floor(iteration)]
color2 = palette[floor(iteration) + 1]
 // iteration % 1 = fractional part of iteration.
color = linear_interpolate(color1, color2, iteration % 1)
plot(Px, Py, color)

有人可以帮助我理解并给出实现方法吗?

【问题讨论】:

标签: javascript colors fractals mandelbrot


【解决方案1】:

linear_interpolate 函数应该根据线性函数 y = mx + b 计算两种颜色之间的颜色。 要将线性函数应用于颜色,y 是输出颜色,m 是两种颜色之间的差异,b 是起始颜色,x 是介于 0 和 1 之间的值。 当 x 为 0 时,此函数输出起始颜色。当 x 为 1 时,此函数输出结束颜色。

要进行此计算,我们需要三个数字形式的颜色。如果您需要使用十六进制字符串,则必须将它们拆分并将每两个字符解析为 16 位数字。我将使用已经是数字形式的调色板,因为它更容易。

这是我的三个调色板。我不建议你使用这些颜色,只是为了演示:

let palette = [{r:255,g:0,b:0},{r:0,g:255,b:0},{r:0,g:0,b:0}]

第一个函数接受迭代,它可能不是整数,可能大于 1。它占用迭代的下限,将其转换为数组索引必须是的整数。然后将剩余的迭代除以 1 得到一个介于 0 和 1 之间的数字。

function interpolation(iteration) {
    let color1 = palette[Math.floor(iteration)];
    let color2 = palette[Math.floor(iteration) + 1];
    return linear_interpolate(color1, color2, iteration % 1);
}

现在我们需要创建线性插值函数,它必须将线性函数应用于每个颜色通道,并使用 floor 将它们变成一个整数。我让它在 rgb() 中返回一个 css 颜色,但你可以将它转换为十六进制。

function linear_interpolate(color1, color2, ratio) {
    let r = Math.floor((color2.r - color1.r) * ratio + color1.r);
    let g = Math.floor((color2.g - color1.g) * ratio + color1.g);
    let b = Math.floor((color2.b - color1.b) * ratio + color1.b);
    return 'rgb(' + r + ',' + g + ',' + b + ')';
}

这里是阴影矩形的代码:https://jsfiddle.net/q7kLszud/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    相关资源
    最近更新 更多