重新创建我的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 =缩放的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作为合理的救援半径。而(x x + y y <= (1 << 16)AND迭代
x-y y + x0 y = 2 * x y + y0 x = xtemp迭代=迭代+ 1} //用于避免 集合内的点的浮点问题。如果(迭代< max_iteration){//使用日志删除内部术语的sqrt 简化规则。 log_zn = log(x x + y * y)/ 2 nu = log(log_zn / log(2))/ log(2)//重新排列电位函数。 //除法 用log(2)代替log(N = 1 << 8)// log_zn //因为我们想要 整个调色板的范围从//中心到半径2,不是我们的 救援半径。迭代=迭代+ 1-nu} color1 = 调色板[floor(iteration)] color2 =调色板[floor(iteration)+ 1] // 迭代%1 =迭代的小数部分。颜色= linear_interpolate(color1,color2,迭代%1)图(Px,Py,颜色) }
对此:
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)
有人可以帮助我理解并给出实现此方法的方法吗?
答案 0 :(得分:2)
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/