Skip to content

Commit 258dca7

Browse files
authored
Big Update!
New controls: F - Fullscreen Arrow keys - move 5 - failed möbius. looks like depressed mandelbrot fractal Space - prints position+zoom Bug fixes: Julia set selection Y axis was flipped, whoops! Resizing now works properly
1 parent ab3c8c7 commit 258dca7

File tree

1 file changed

+124
-120
lines changed

1 file changed

+124
-120
lines changed

mandel.cpp

Lines changed: 124 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#include <GL/glut.h>
22
#include <iostream>
33
#include <cmath>
4+
static bool fullscreen = false;
45
float lerp(float a,float b,float t){return a+t*(b-a);}
5-
int WIDTH =800;
6-
int HEIGHT=600;
6+
float WIDTH =800;
7+
float oWIDTH,oHEIGHT;
8+
using namespace std;
9+
float HEIGHT=600;
710
int mouseX,mouseY;
811
bool biomorph=false;
912
bool julia=false;
@@ -17,6 +20,8 @@ int fractal=1;
1720
long double startX,startY,start_X,start_Y;
1821
int maxIter =250;
1922
int maxIter2=250;
23+
int rot=0;
24+
float dist=0;
2025
long double zoomFactor=1.0;
2126
float period=0,iterations=0,iter=0,log_zn,nu,r1,r2,g1,g2,b1,b2,deltaX,deltaY,t;
2227
void reset(){
@@ -30,67 +35,60 @@ bool inCardioidOrBulb(long double x, long double y) {
3035

3136
void key(unsigned char key, int x, int y) {
3237
if (key == 27) {
33-
std::cout << "Thank you for using https://github.com/iogameplayer/smoothmandelbrot.\n";
3438
exit(0);
3539
}
40+
if (key == 32){
41+
std::cout << "---Position---\n"<< "x: " << xPos <<"\ny: " << yPos << "\nZoom:" << zoom << "\n--------------\n";glutPostRedisplay();
42+
}
43+
3644
switch (key){
37-
case 'q': {
38-
zoom *= 1.1;
39-
maxIter = maxIter2;
40-
render = true;
41-
glutPostRedisplay();
42-
break;
43-
}
45+
case 'q': {zoom *= 1.1;maxIter = maxIter2;render = true;xPos+=WIDTH/20/zoom;yPos+=HEIGHT/20/zoom;glutPostRedisplay();break;}
46+
case 'e': {zoom *= 0.9;maxIter = maxIter2;render = true;xPos-=WIDTH/20/zoom;yPos-=HEIGHT/20/zoom;glutPostRedisplay();break;}
47+
48+
case '+': {maxIter *= 1.1;if(maxIter>1000000){maxIter=1000000;}if(maxIter<11){maxIter+=1;}
49+
maxIter2 = maxIter;std::cout << "Maximum iterations: " << maxIter << "\n";render = true;glutPostRedisplay();break;}
50+
case '=': {maxIter *= 1.1;if(maxIter>1000000){maxIter=1000000;}if(maxIter<11){maxIter+=1;}
51+
maxIter2 = maxIter;std::cout << "Maximum iterations: " << maxIter << "\n";render = true;glutPostRedisplay();break;}
52+
case '-': {if(maxIter<11){maxIter-=1;if(maxIter==-1){maxIter=0;}}else{maxIter /= 1.1;}
53+
maxIter2 = maxIter;std::cout << "Maximum iterations: " << maxIter << "\n";render = true;
54+
if(maxIter>1000000){maxIter=1000000;}glutPostRedisplay();break;}
4455

45-
case 'e': {
46-
zoom *= 0.9;
47-
maxIter = maxIter2;
48-
render = true;
49-
glutPostRedisplay();
50-
break;
51-
}
52-
case '+': {maxIter *= 1.1;if(maxIter>1000000){maxIter=1000000;}maxIter2 = maxIter;std::cout << "Maximum iterations: " << maxIter << "\n";render = true;glutPostRedisplay();break;}
53-
case '=': {maxIter *= 1.1;if(maxIter>1000000){maxIter=1000000;}maxIter2 = maxIter;std::cout << "Maximum iterations: " << maxIter << "\n";render = true;glutPostRedisplay();break;}
54-
case '-': {maxIter /= 1.1;maxIter2 = maxIter;if(maxIter<10){maxIter=10;}std::cout << "Maximum iterations: " << maxIter << "\n";render = true;glutPostRedisplay();if(maxIter>1000000){maxIter=1000000;}break;}
5556
case 'b': {biomorph=!biomorph;glutPostRedisplay();break;}
5657
case 's': {smooth =!smooth; glutPostRedisplay();break;}
57-
case '4': {fractal=4;std::cout << "-New Fractal?-\n"; break;}
58-
//case '5': {fractal=5;std::cout << "----Newton----\n"; break;}
59-
case '3': {fractal=3;std::cout << "---Tri-corn---\n"; break;}
60-
case '2': {fractal=2;std::cout << "-Burning Ship-\n"; break;}
61-
case '1': {fractal=1;std::cout << "Mandelbrot Set\n"; break;}
62-
case 'r': {reset();break;}
63-
case 'j': {
64-
if(julia){
65-
julia=false;
66-
reset();
67-
std::cout << "-Fractal Mode-\n";
68-
}
69-
else{
70-
julia=true;
71-
xJul=mouseX/zoom+xPos;
72-
yJul=mouseY/zoom+yPos;
73-
reset();
74-
std::cout << "--Julia Mode--\nReal:" << xJul << "\nImag:" << yJul << "\n--------------\n";
75-
}
76-
break;
77-
}
58+
case '4': {fractal=4;std::cout << "-New Fractal?-\n";glutPostRedisplay();break;}
59+
case '5': {fractal=5;std::cout << "----thing?----\n";glutPostRedisplay();break;}
60+
case '3': {fractal=3;std::cout << "---Tri-corn---\n";glutPostRedisplay();break;}
61+
case '2': {fractal=2;std::cout << "-Burning Ship-\n";glutPostRedisplay();break;}
62+
case '1': {fractal=1;std::cout << "Mandelbrot Set\n";glutPostRedisplay();break;}
63+
case 'r': {reset();break;}
64+
case 'f': {fullscreen = !fullscreen;if(fullscreen){oWIDTH=WIDTH;oHEIGHT=HEIGHT;glutFullScreen();}else{glutReshapeWindow(oWIDTH,oHEIGHT);}break;}
65+
case 'j': {if(julia){julia=false;reset();std::cout << "-Fractal Mode-\n";}else{julia=true;xJul=xPos+mouseX/zoom;yJul=yPos+(HEIGHT-mouseY)/zoom;reset();std::cout << "--Julia Mode--\nReal:" << xJul << "\nImag:" << yJul << "\n--------------\n";}break;}
7866
}
7967
}
8068
long double r0,i0,real,imag,tempreal,io,ro;
69+
8170
float escapesmooth(long double real, long double imag, int x, int y){
82-
r0=real;
83-
i0=imag;
84-
if(julia){
85-
r0=xJul;i0=yJul;
86-
}
71+
r0=real;
72+
i0=imag;
73+
if(julia){
74+
r0=xJul;i0=yJul;
75+
}
8776
iter=0.0;
8877
if(fractal==1&&!julia){if(inCardioidOrBulb(real,imag)){return maxIter;}}
8978
while(iter<maxIter&&real*real+imag*imag<=16){
9079
if(fractal==4){
9180
tempreal=real*imag+r0;
9281
imag=2*real-imag+i0;
9382
real=tempreal;
83+
}else if (fractal == 5) { //failed möbius fractal - still looks interesting, like an depressed version of the Mandelbrot set.
84+
long double rx = cos(M_PI / 360);
85+
long double ry = sin(M_PI / 360);
86+
87+
long double cx2 = rx * rx * real + ry * ry * imag +r0;
88+
long double cy2 = rx * rx * imag - ry * ry * real +i0;
89+
90+
real = rx * (real * real - imag * imag) - ry * (2 * real * imag) + cx2;
91+
imag = rx * (2 * real * imag) + ry * (real * real - imag * imag) + cy2;
9492
}
9593
else{
9694
tempreal=real*real-imag*imag+r0;
@@ -100,8 +98,7 @@ float escapesmooth(long double real, long double imag, int x, int y){
10098
imag=2*real*imag+i0;}
10199
else if(fractal==3){
102100
imag=-2*real*imag+i0;}
103-
real=tempreal;
104-
}
101+
real=tempreal;}
105102
iter++;
106103
if(real==ro&&imag==io){
107104
iter=maxIter;
@@ -129,92 +126,99 @@ float escapesmooth(long double real, long double imag, int x, int y){
129126
return iter;
130127
}
131128
void display(){
132-
if(render){
133-
for(int y=HEIGHT;y>0;y--){
134-
glBegin(GL_POINTS);
135-
for(int x=0;x<WIDTH;x++){
136-
iterations=escapesmooth(x/zoom+xPos,y/zoom+yPos,xJul,yJul);
137-
glVertex2i(x,y);
138-
if(iterations==maxIter){
139-
glColor3f(0,0,0);
140-
}
129+
if(render){
130+
for(int y=HEIGHT;y>0;y--){
131+
glBegin(GL_POINTS);
132+
for(int x=0;x<WIDTH+1;x++){
133+
iterations=escapesmooth(x/zoom+xPos,y/zoom+yPos,xJul,yJul);
134+
glVertex2i(x,y);
135+
if(iterations==maxIter){
136+
glColor3f(0,0,0);
137+
}
138+
else{
139+
r1=0.5+sin(floor(iterations)/10)/2;
140+
g1=floor(iterations)/maxIter;
141+
b1=1-floor(iterations)/maxIter;
142+
if(smooth){
143+
r2=0.5+sin((floor(iterations)+1)/10)/2;
144+
g2= (floor(iterations)+1)/maxIter;
145+
b2=1-(floor(iterations)+1)/maxIter;}
146+
/*Sunburst:
147+
float r1=floor(iterations)/32;
148+
float r2=floor(iterations+1)/32;
149+
float g1=floor(iterations)/64;
150+
float g2=floor(iterations+1)/64;
151+
float b1=floor(iterations)/128;
152+
float b2=floor(iterations+1)/128;
153+
/*test
154+
float r1=floor(iterations)/32;
155+
float r2=floor(iterations+1)/32;
156+
float g1=floor(iterations)/64;
157+
float g2=floor(iterations+1)/64;
158+
float b1=floor(iterations)/128;
159+
float b2=floor(iterations+1)/128;*/
160+
t=fmod(iterations,1);
161+
if(smooth){
162+
glColor3f(lerp(r1,r2,t),lerp(g1,g2,t),lerp(b1,b2,t));}
141163
else{
142-
r1=0.5+sin(floor(iterations)/10)/2;
143-
g1=floor(iterations)/maxIter;
144-
b1=1-floor(iterations)/maxIter;
145-
if(smooth){
146-
r2=0.5+sin((floor(iterations)+1)/10)/2;
147-
g2= (floor(iterations)+1)/maxIter;
148-
b2=1-(floor(iterations)+1)/maxIter;}
149-
/*Sunburst:*//*
150-
float r1=floor(iterations)/32;
151-
float r2=floor(iterations+1)/32;
152-
float g1=floor(iterations)/64;
153-
float g2=floor(iterations+1)/64;
154-
float b1=floor(iterations)/128;
155-
float b2=floor(iterations+1)/128;
156-
/*test*//*
157-
float r1=floor(iterations)/32;
158-
float r2=floor(iterations+1)/32;
159-
float g1=floor(iterations)/64;
160-
float g2=floor(iterations+1)/64;
161-
float b1=floor(iterations)/128;
162-
float b2=floor(iterations+1)/128;*/
163-
164-
t=fmod(iterations,1);
165-
if(smooth){
166-
if(x==1&&y==1){std::cout << "a";}
167-
glColor3f(lerp(r1,r2,t),lerp(g1,g2,t),lerp(b1,b2,t));}
168-
else{
169-
glColor3f(r1,g1,b1);
170-
}
164+
glColor3f(r1,g1,b1);
165+
}
171166
}
172167
}
173-
glEnd();
174-
glFlush();}
168+
glEnd();
169+
glFlush();
170+
}
175171
}
176-
//maxIter*=1.2;
177172
}
178-
void reshape(int w,int h){glutReshapeWindow(w,h);HEIGHT=h;WIDTH=w;}
179-
bool isDragging = false;
173+
void reshape(int w, int h) {
174+
glViewport(0, 0, w, h);
175+
glMatrixMode(GL_PROJECTION);
176+
glLoadIdentity();
177+
glOrtho(0, w, 0, h, -1, 1);
178+
glMatrixMode(GL_MODELVIEW);
179+
glLoadIdentity();
180+
WIDTH = w;
181+
HEIGHT = h;
182+
render=true;
183+
glutPostRedisplay();
184+
}bool isDragging = false;
180185
int lastX,lastY;
181186

182187
void mouse(int button, int state, int x, int y){
183-
if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN){
184-
isDragging=true;
185-
lastX=x;
186-
lastY=y;
187-
} else if(button==GLUT_LEFT_BUTTON&&state==GLUT_UP){
188-
isDragging=false;
188+
if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN){
189+
isDragging=true;
190+
lastX=x;
191+
lastY=y;
192+
} else if(button==GLUT_LEFT_BUTTON&&state==GLUT_UP){
193+
isDragging=false;
189194
}
190195
}
191196
void motion(int x, int y) {
192-
if (isDragging) {
193-
deltaX=(x-lastX)/zoom;
194-
deltaY=(y-lastY)/zoom;
195-
xPos-=deltaX;
196-
yPos+=deltaY;
197-
lastX=x;
198-
lastY=y;
199-
maxIter=maxIter2;
200-
glutPostRedisplay();
201-
}
197+
if (isDragging) {
198+
deltaX=(x-lastX)/zoom;
199+
deltaY=(y-lastY)/zoom;
200+
xPos-=deltaX;
201+
yPos+=deltaY;
202+
lastX=x;
203+
lastY=y;
204+
maxIter=maxIter2;
205+
glutPostRedisplay();
206+
}
202207
}
203-
204208
void onMouseMove(int x, int y) {
205-
mouseX = x;
206-
mouseY = y;
209+
mouseX = x;
210+
mouseY = y;
207211
}
208212
void specialfunc(int key, int x, int y){
209213
switch(key){
210214
case GLUT_KEY_UP:{
211-
yPos+=40/zoom;break;}
215+
yPos+=40/zoom;glutPostRedisplay();break;}
212216
case GLUT_KEY_DOWN:{
213-
yPos-=40/zoom;break;}
217+
yPos-=40/zoom;glutPostRedisplay();break;}
214218
case GLUT_KEY_RIGHT:{
215-
xPos+=40/zoom;break;}
219+
xPos+=40/zoom;glutPostRedisplay();break;}
216220
case GLUT_KEY_LEFT:{
217-
xPos-=40/zoom;break;}
221+
xPos-=40/zoom;glutPostRedisplay();break;}
218222
}
219223
}
220224
int main(int argc, char** argv){
@@ -224,19 +228,19 @@ int main(int argc, char** argv){
224228
glutCreateWindow("mandel badandel");
225229

226230
glMatrixMode(GL_PROJECTION);
227-
glLoadIdentity();
228-
gluOrtho2D(0, WIDTH, 0, HEIGHT);
229-
glMatrixMode(GL_MODELVIEW);
230-
glLoadIdentity();
231+
glLoadIdentity();
232+
gluOrtho2D(0, WIDTH, 0, HEIGHT);
233+
glMatrixMode(GL_MODELVIEW);
234+
glLoadIdentity();
231235
glClearColor(0.0,0.0,0.0,1.0);
232236
std::cout << "Maximum iterations: " << maxIter << "\n";
233237

234238
glutSpecialFunc(specialfunc);
235239
glutPassiveMotionFunc(onMouseMove);
236240
glutDisplayFunc(display);
237241
glutReshapeFunc(reshape);
238-
glutMouseFunc(mouse);
239-
glutMotionFunc(motion);
242+
glutMouseFunc(mouse);
243+
glutMotionFunc(motion);
240244
glutKeyboardFunc(key);
241245

242246
glutMainLoop();

0 commit comments

Comments
 (0)