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