Just Some Julia Sets
So one of the neat side things I learned at GHP was how the Mandelbrot Set works. Somehow I had the impression that the Mandelbrot Set was really complicated so I had never looked up the details. But it is really crazy-simple, assuming you know what a complex number is. Anyways, once I learned this, I just had to cook up my own mini-fractal generator and explore. I didn’t actually draw the Mandelbrot (yeah, now that I understand the Mandelbrot just doesn’t excite me anymore): I’m drawing some julia sets which are a very close relative.
And I did it in Processing which made it extra easy and fun.
class Cnum //complex number
{
float r; //real
float i; //imaginary
Cnum(float r_, float i_) {
r = r_;
i = i_;
}
String irep()
{
return "[" + r + " + " + i + "i]";
}
String prep()
{
float theta = arg();
float r2 = sqrt((i*i) + (r*r));
return "[r=" + r2 + " theta=" + theta + "]";
}
String toString() {
return irep();
}
boolean isInfinity()
{
return r == Float.POSITIVE_INFINITY;
}
boolean isZero()
{
return r == 0 && i == 0;
}
Cnum conj()
{
return new Cnum(r, i*-1);
}
Cnum neg()
{
return new Cnum(-r,-i);
}
float arg()
{
return atan2(i,r);
}
float abs()
{
return sqrt(r*r + i*i);
}
}
Cnum add(Cnum a, Cnum b)
{
return new Cnum(a.r + b.r, a.i + b.i);
}
Cnum sub(Cnum a, Cnum b)
{
return new Cnum(a.r - b.r, a.i - b.i);
}
Cnum mul(Cnum a, Cnum b)
{
return new Cnum(a.r*b.r - a.i*b.i, a.i*b.r + a.r*b.i);
}
int WIDTH = 500;
int HEIGHT = 500;
boolean changeOnMove = true;
void plot(Cnum a)
{
float xPercentage = (a.r - upperLeft.r)/(lowerRight.r - upperLeft.r);
float yPercentage = (a.i - lowerRight.i)/(upperLeft.i - lowerRight.i);
int x = round(xPercentage*WIDTH);
int y = round((1 - yPercentage)*HEIGHT);
point(x, y);
}
Cnum convert(int x, int y)
{
float xPercentage = x/float(WIDTH);
float yPercentage = y/float(HEIGHT);
return new Cnum((lowerRight.r - upperLeft.r)*xPercentage + upperLeft.r,
(upperLeft.i - lowerRight.i)*(1 - yPercentage) + lowerRight.i);
}
Cnum upperLeft, lowerRight;
PFont fontA;
void setup() {
upperLeft = new Cnum(-2, 2);
lowerRight = new Cnum(2, -2);
size(WIDTH, HEIGHT);
stroke(226);
fill(226);
fontA = loadFont("SansSerif.plain-12.vlw");
// Set the font and its size (in units of pixels)
textFont(fontA, 12);
oldMouse = new Cnum(0,0);
}
void keyPressed() {
if (key == 'q')
exit();
if (key == 's')
save("output.png");
if (key == ' ') {
changeOnMove = !(changeOnMove);
draggedX = 0;
draggedY = 0;
}
}
Cnum oldMouse;
int maxIter = 20;
void draw() {
Cnum mouse;
background(0);
if(changeOnMove) {
mouse = convert(mouseX, mouseY);
if(mouse.r == oldMouse.r && mouse.i == oldMouse.i) {
if(maxIter < 1000)
maxIter = maxIter + 20;
else
return;
} else {
maxIter = 5;
oldMouse = mouse;
}
} else {
mouse = oldMouse;
}
for(int q = 0; q < WIDTH; q++)
for(int j = 0; j < HEIGHT; j++) {
Cnum orig = convert(q,j);
//Cnum acc = add(mul(orig,orig), mouse) ;
Cnum acc = orig ;
//Cnum acc = add(orig, mouse);
for(int i = 0; i < maxIter; i++) {
acc = add(mul(mul(acc,acc),acc), mouse) ;
if(acc.abs() > 2){
int strokeColor = 255 - i*5;
if (strokeColor < 0 ) strokeColor = 0;
stroke(strokeColor);
plot(orig);
break;
}
}
}
fill(0,0,222);
text("z^2 + cl c=" + mouse.r + " + " + mouse.i + "i", 30, 60);
if(draggedX != 0 || draggedY != 0) {
stroke(0,0,222);
noFill();
int max = max(mouseX - draggedX, mouseY - draggedY);
rect(draggedX, draggedY, max, max);
}
}
int draggedX = 0;
int draggedY = 0;
void mousePressed()
{
if(!changeOnMove) {
draggedX = mouseX;
draggedY = mouseY;
}
}
void mouseReleased()
{
if(!changeOnMove && draggedX != 0 && draggedY != 0) {
int temp;
if(mouseX < draggedX) {
temp = mouseX;
mouseX = draggedX;
draggedX = temp;
}
if(mouseY < draggedY) {
temp = mouseY;
mouseY = draggedY ;
draggedY = temp;
}
int max = max (mouseX - draggedX, mouseY - draggedY);
Cnum lowerRightNew = convert(draggedX + max, draggedY + max);
Cnum upperLeftNew = convert(draggedX, draggedY);
upperLeft = upperLeftNew;
lowerRight = lowerRightNew;
draggedX = 0;
draggedY = 0;
}
}
It’s is so simple, just listen to this song by Johnny C.
http://www.jonathancoulton.com/songdetails/Mandelbrot%20Set