You need to perform complex arithmetic.
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;
}
The formula is zk+1 = zk2 + c, with z0 = 0 or equivalently z1 = c
where c is the current position, i.e. c = x2
+ i⋅y2
.
I have z = x3
+ i⋅y3
so z2 = (x3
+ i⋅y3
)2 = x3
2 + 2⋅i⋅x3
⋅y3
+ i2⋅y3
2.
With i2 = −1 this simplifies to z2 = (x3
2 − y3
2) + i⋅(2⋅x3
⋅y3
) and to these I add c
i.e. x2
and y2
.
See https://jsfiddle.net/d5avqq5w/ for live demo.
Your original code discarded the angle information in the z = Math.sqrt( x2*x2 + y2*y2 )
step, since x2
and y2
were not used after that point. Therefore the resulting color had to be independent of the angle, i.e. composed of concentric circles.
The page you gave as a reference deals with the absolute value of complex numbers. But the iteration step of the Mandelbrot formula should operate on the complex numbers as they are, not on any absolute values of complex numbers, so following that formula here is inappropriate.
There is one valid application of an absolute value, and that is when deciding whether or not to terminate the loop (i.e. to detect divergence). The other page you referenced just writes about
The modulus (length) of zn exceeds a given value.
without actually giving the threshold explicitely. I've used a threshold of 4, but I avoided the square root by testing whether the square of the length of z exceeds 16. That's where the x3*x3 + y3*y3 < 16
in my code comes from. It is more common to use 2 as the threshold (i.e. 4 for the squared test), but I felt that using 4 would be closer to the code you had, i.e. better suited to highlight the distinction between comparing the absolute value and comparing its square. Using 4 instead of 2 may cause us to detect divergence a bit later, leading to slightly higher values of the counter variable when the loop exits.
Note that Wikipedia also has some pseudocode which you might have used as the starting point, along with an explanation how the real-valued arithmetic in the code relates to the complex-valued arithmetic in the rest of the article.