// Mandelbrot/Julia Set Program
// Tom Dixon - Supercomp Period 3
//
// Left: Box zoom; Middle: Show iteration; Right: Default window
// Space Bar: Shows Julia set for current point, returns to Mandelbrot
#include<GL/glut.h>
#include<iostream.h>
#include<malloc.h>
#include<assert.h>
int xsize = 500, ysize = 500, mode = 0, ok=0;
double x1=-2.5, x2=1.5, y1=-2, y2=2, zx, zy, jx=0, jy=0, ***screen;
#include "mtga.h"
void init() {
glClearColor(0,0,0,0);
glShadeModel(GL_FLAT);
}
void display() {
if (ok) {
glBegin(GL_POINTS);
for(int x=0; x<xsize; x++)
for(int y=0; y<ysize; y++) {
glColor3f(screen[x][y][0], screen[x][y][1], screen[x][y][2]);
glVertex3f(x+0.5, y+0.5, 0);
}
glEnd();
}
else {
free(screen);
screen = (double ***)malloc(sizeof(double **)*xsize);
for (int i = 0; i < xsize; i++)
screen[i] = (double **)malloc(sizeof(double *)*ysize);
for (i = 0; i < xsize; i++)
for (int j = 0; j < ysize; j++)
screen[i][j] = (double *)malloc(sizeof(double)*3);
assert(screen);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_POINTS);
double a, b, ta, x ,y;
int it, max=-1, min=10000, maxit=int(1/(x2-x1)+1/(y2-y1)+20);
for(int i=0; i<xsize; i++)
for(int j=0; j<ysize; j++) {
x=x1+(x2-x1)*i/xsize;
y=y2-(y2-y1)*j/ysize;
it=0;
a=x; b=y;
while (it<maxit && a*a+b*b<4) {
ta=a*a-b*b+(mode ? jx : x);
b=2*a*b+(mode ? jy : y);
a=ta;
it++;
}
if (it>max) max=it;
if (it<min) min=it;
}
maxit=max;
for(int i=0; i<xsize; i++)
for(int j=0; j<ysize; j++) {
it=0;
x=x1+(x2-x1)*i/xsize;
y=y2-(y2-y1)*j/ysize;
a=x; b=y;
while (it<maxit && a*a+b*b<4) {
ta=a*a-b*b+(mode ? jx : x);
b=2*a*b+(mode ? jy : y);
a=ta;
it++;
}
if (it<maxit) {
screen[i][j][0]=double(it-min)/(max-min);
screen[i][j][1]=1-double(it-min)/(max-min);
screen[i][j][2]=double(it-min)/(max-min);
}
else screen[i][j][0]=screen[i][j][1]=screen[i][j][2]=0;
glColor3f(screen[i][j][0], screen[i][j][1], screen[i][j][2]);
glVertex3f(i+0.5, j+0.5, 0);
}
glEnd();
ok=1;
}
}
void reshape(int w, int h) {
xsize=w; ysize=h;
glViewport(0, 0, GLsizei(w), GLsizei(h));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, xsize, 0, ysize, -1, 1);
glMatrixMode(GL_MODELVIEW);
ok=0;
}
void showit(int x, int y) {
double a=x1+(x2-x1)*x/xsize, ia=a, b=y2-(y2-y1)*y/ysize, ib=b, ta;
int it=0;
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
while (it<100 && a*a+b*b<4) {
glVertex3f(a, b, 0);
ta=a*a-b*b+ia;
b=2*a*b+ib;
a=ta;
it++;
}
glVertex3f(a, b, 0);
glEnd();
ok=0;
}
void zoom(int button, int state, int x, int y) {
if (button==GLUT_MIDDLE_BUTTON) showit(x, y);
else if (button==GLUT_RIGHT_BUTTON) {
x1=-2.5; x2=2; y1=-2; y2=2;
reshape(xsize, ysize);
glutPostRedisplay();
}
else if (button==GLUT_LEFT_BUTTON) {
if (state==GLUT_DOWN) {
zx=x1+(x2-x1)*x/xsize;
zy=y2-(y2-y1)*y/ysize;
}
else {
x2=x1+(x2-x1)*x/xsize;
y1=y2-(y2-y1)*y/ysize;
x1=zx; y2=zy;
reshape(xsize, ysize);
glutPostRedisplay();
}
}
}
void keyboard(unsigned char ch, int x, int y) {
if (ch==' ') {
mode=!mode;
if (mode) {
jx=x1+(x2-x1)*x/xsize;
jy=y2-(y2-y1)*y/ysize;
}
x1=-2.5; x2=1.5; y1=-2; y2=2;
reshape(xsize, ysize);
glutPostRedisplay();
}
if (ch=='t' || ch=='T') writetga();
}
void main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(xsize, ysize);
glutInitWindowPosition(100, 100);
glutCreateWindow("Mandelbrot/Julia-o-Rama");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(zoom);
glutKeyboardFunc(keyboard);
glutMainLoop();
}
|