1 /*
2 * Fractal code by Jer Johnson (K)1998 (jer@gweep.net)
3 *
4 * julia improvements by Daniel Burn <daniel@bizo.biz.usyd.edu.au>
5 */
6
7 #include <X11/X.h>
8 #include <X11/Xlib.h>
9 #include <X11/Xutil.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <math.h>
13 #include "trippy.h"
14 #include "lmath.h"
15 #include "complex.h"
16
17 extern XEvent event;
18
19 void
exit_fracrect()20 exit_fracrect()
21 {
22 return;
23 }
24
25 void
draw_fracrect(int winno,int x1,int y1,int x2,int y2,int c,int d)26 draw_fracrect(int winno,int x1,int y1,int x2,int y2,int c,int d)
27 {
28 int xm,ym,q;
29
30 if(options.number>12) {
31 options.number=12;
32 }
33 if(d>options.number)return; /* only go 12 levels deep */
34 c=c%numcolors;
35 if(c==0)
36 c=1;
37
38 q=d+1;
39
40 xm=(x1+x2)/2;
41 ym=(y1+y2)/2;
42
43 XFillRectangle(display,window[winno],color_gcs[c],x1,y1,x2-x1,y2-y1);
44
45 draw_fracrect(winno,x1,ym,xm,y2,c+8/d,q);
46 draw_fracrect(winno,xm,y1,x2,ym,c+16/d,q);
47 draw_fracrect(winno,x1,y1,xm,ym,c+32/d,q);
48 draw_fracrect(winno,xm,ym,x2,y2,c+64/d,q);
49 return;
50 }
51
52 void
exit_mandel()53 exit_mandel()
54 {
55 return;
56 }
57
58 void
draw_mandel(int l,int t,int r,int b,int winno)59 draw_mandel(int l,int t,int r, int b, int winno )
60 {
61 int x,y,i;
62 double left,right,top,bottom;
63 struct COMPLEX C;
64 struct COMPLEX Z;
65 int useCY = CY[winno];
66 int useCX = CX[winno];
67
68 top=(double)t/(useCY*.5)-1.25;
69 bottom=(double)b/(useCY*.5)-.75;
70 left=(double)l/(useCX*.5)-1.875;
71 right=(double)r/(useCX*.5)-1.375;
72 printf("Drawing Mandel from (%f,%f) to (%f,%f)\n",
73 ((right-left)*0/useCX)+left,
74 ((bottom-top)*0/useCY)+top,
75 ((right-left)*useCX/useCX)+left,
76 ((bottom-top)*useCY/useCY)+top);
77
78 for(y=0;y<useCY;y++)
79 {
80 if((y%10==0))
81 if (XCheckMaskEvent(display,~0L,&event)==True)
82 handle_event(&event); /* check for kills every so often */
83
84 for(x=0;x<useCX;x++)
85 {
86 C.real=(double)((right-left)*x/useCX)+left;
87 C.imag=(double)((bottom-top)*y/useCY)+top;
88 Z.real=C.real;
89 Z.imag=C.imag;
90 for (i=1;i<(options.number*10);i++)
91 {
92 Z=multComplex(Z,Z);
93 Z=addComplex(Z,C);
94 if((Z.real*Z.real)+(Z.imag*Z.imag)>4.0)
95 break;
96 }
97 XDrawPoint(display,window[winno],
98 color_gcs[(i%numcolors)?(i%numcolors):1],x,y);
99 }
100 }
101 }
102
103 void
exit_julia()104 exit_julia()
105 {
106 return;
107 }
108
109 /* julia.. the fractal set, not the person */
110 void
draw_julia(int winno,double coordx,double coordy)111 draw_julia(int winno, double coordx, double coordy)
112 {
113 int x,y,i;
114 struct COMPLEX Z,Z2;
115 double useCX = CX[winno]*.5;
116 double useCY = CY[winno]*.4;
117
118 for(y=0;y<CY[winno];y++)
119 {
120 if (XCheckMaskEvent(display,~0L,&event)==True) /* check with the */
121 handle_event(&event); /* outside world */
122 for(x=0;x<CX[winno];x++)
123 {
124 Z.real=(double)(x-useCX)/useCY;
125 Z.imag=(double)(y-useCX)/useCY;
126
127 /* C.real = -0.27334;
128 C.imag = 0.00742; */
129
130 /* F(z)=z^2+c */
131 for (i=0;i<(options.number*10);i++)
132 {
133 Z2.real = Z.real * Z.real - Z.imag * Z.imag + coordx;
134 Z.imag = 2.0 * Z.real * Z.imag + coordy;
135 Z.real = Z2.real;
136 /*
137 Z=multComplex(Z,Z);
138 Z=addComplex(Z,C);
139 */
140 if((Z.real*Z.real)+(Z.imag*Z.imag)>4.0)
141 break;
142 }
143 XDrawPoint(display,window[winno],color_gcs[(i%(numcolors-1))+1],x,y);
144 }
145 }
146 }
147
148 void
exit_newton()149 exit_newton()
150 {
151 return;
152 }
153
154 /* newton.. the fractal set, not the person */
155 void
draw_newton(int winno)156 draw_newton(int winno)
157 {
158 int x,y,i,D;
159 struct COMPLEX Z;
160 const struct COMPLEX minus1= {-1,0};
161 struct COMPLEX expon;
162 struct COMPLEX expDown;
163 int useCX = CX[winno];
164 int useCY = CY[winno];
165 int midCX = useCX>>1;
166 int midCY = useCY>>1;
167 int val=options.number;
168
169 expon.imag=expDown.imag=0;
170 expon.real=val; expDown.real= val-1;
171
172 for(D=16;D>=1;D>>=1)
173 {
174 for(y=0;y<useCY;y+=D)
175 {
176 if (XCheckMaskEvent(display,~0L,&event)==True)
177 handle_event(&event);
178 for(x=0;x<useCX;x+=D)
179 {
180 Z.real=(double)(x-midCX)/(double)midCX;
181 Z.imag=(double)(y-midCY)/(double)midCY;
182 /* z^val-1 = 0 */
183 for (i=0;i<(options.number*10);i++)
184 {
185 double lastR=Z.real; double lastI=Z.imag;
186 /* Z(j+1)=Z(i)-( (Z(i)^3-1)/(3*Z(i)^2)) */
187 /* Whoa! this is REAL MESSY! */
188 Z= addComplex(Z,multComplex(minus1,(divComplex(
189 (addComplex(powComplex(Z,expon),minus1)),
190 (multComplex(expon,powComplex(Z,expDown)))))));
191
192 if((fabs(Z.real-1.0)<0.01)&&(fabs(Z.imag)<0.01))
193 {
194 /* printf("Breaking out "); */
195 break;
196 }
197 /*
198 fprintf(stderr,"Iter[%d] Z.real = %lf \t Z.imag= %lf\n",
199 i,Z.real,Z.imag);
200 */
201 if(Z.real==lastR && Z.imag==lastI) /* we're stuck.. quit now */
202 {
203 i=10*options.number;
204 break;
205 }
206 }
207 XFillRectangle(display,window[winno],color_gcs[(i%numcolors)+1],x,y,D,D);
208 /* XDrawPoint(display,window[winno],color_gcs[(i%numcolors)+1],x,y); */
209 }
210 }
211 }
212 }
213