File: common\frasetup.c
1 #include <limits.h>
2 #include <string.h>
3 #ifdef __TURBOC__
5 #elif !defined(__386BSD__)
6 #include <malloc.h>
7 #endif
8 /* see Fractint.c for a description of the "include" hierarchy */
9 #include "port.h"
10 #include "prototyp.h"
11 #include "helpdefs.h"
12 #include "fractype.h"
13
14 #ifndef XFRACT
15 #define MPCmod(m) (*pMPadd(*pMPmul((m).x, (m).x), *pMPmul((m).y, (m).y)))
16 #endif
17
18 /* -------------------------------------------------------------------- */
19 /* Setup (once per fractal image) routines */
20 /* -------------------------------------------------------------------- */
21
22 int
23 MandelSetup(void) /* Mandelbrot Routine */
24 {
25 if (debugflag != 90
26 && !invert && decomp[0] == 0 && rqlim == 4.0
27 && bitshift == 29 && potflag == 0
28 && biomorph == -1 && inside > -59 && outside >= -1
29 && useinitorbit != 1 && using_jiim == 0 && bailoutest == Mod
30 && (orbitsave&2) == 0)
31 calctype = calcmand; /* the normal case - use CALCMAND */
32 else
33 {
34 /* special case: use the main processing loop */
35 calctype = StandardFractal;
36 longparm = &linit;
37 }
38 return(1);
39 }
40
41 int
42 JuliaSetup(void) /* Julia Routine */
43 {
44 if (debugflag != 90
45 && !invert && decomp[0] == 0 && rqlim == 4.0
46 && bitshift == 29 && potflag == 0
47 && biomorph == -1 && inside > -59 && outside >= -1
48 && !finattract && using_jiim == 0 && bailoutest == Mod
49 && (orbitsave&2) == 0)
50 calctype = calcmand; /* the normal case - use CALCMAND */
51 else
52 {
53 /* special case: use the main processing loop */
54 calctype = StandardFractal;
55 longparm = &lparm;
56 get_julia_attractor (0.0, 0.0); /* another attractor? */
57 }
58 return(1);
59 }
60
61 int
62 NewtonSetup(void) /* Newton/NewtBasin Routines */
63 {
64 int i;
65 #ifndef XFRACT
66 if (debugflag != 1010)
67 {
68 if(fpu != 0)
69 {
70 if(fractype == MPNEWTON)
71 fractype = NEWTON;
72 else if(fractype == MPNEWTBASIN)
73 fractype = NEWTBASIN;
74 }
75 else
76 {
77 if(fractype == NEWTON)
78 fractype = MPNEWTON;
79 else if(fractype == NEWTBASIN)
80 fractype = MPNEWTBASIN;
81 }
82 curfractalspecific = &fractalspecific[fractype];
83 }
91 #endif
92 /* set up table of roots of 1 along unit circle */
93 degree = (int)parm.x;
94 if(degree < 2)
95 degree = 3; /* defaults to 3, but 2 is possible */
96 root = 1;
97
98 /* precalculated values */
99 roverd = (double)root / (double)degree;
100 d1overd = (double)(degree - 1) / (double)degree;
101 maxcolor = 0;
102 threshold = .3*PI/degree; /* less than half distance between roots */
103 #ifndef XFRACT
104 if (fractype == MPNEWTON || fractype == MPNEWTBASIN) {
105 mproverd = *pd2MP(roverd);
106 mpd1overd = *pd2MP(d1overd);
107 mpthreshold = *pd2MP(threshold);
108 mpone = *pd2MP(1.0);
109 }
110 #endif
111
112 floatmin = FLT_MIN;
113 floatmax = FLT_MAX;
114
115 basin = 0;
116 if(roots != staticroots) {
117 free(roots);
118 roots = staticroots;
119 }
120
121 if (fractype==NEWTBASIN)
122 {
123 if(parm.y)
124 basin = 2; /*stripes */
125 else
126 basin = 1;
127 if(degree > 16)
128 {
129 if((roots=(_CMPLX *)malloc(degree*sizeof(_CMPLX)))==NULL)
130 {
131 roots = staticroots;
132 degree = 16;
133 }
134 }
135 else
136 roots = staticroots;
137
138 /* list of roots to discover where we converged for newtbasin */
139 for(i=0;i<degree;i++)
140 {
141 roots[i].x = cos(i*twopi/(double)degree);
142 roots[i].y = sin(i*twopi/(double)degree);
143 }
144 }
145 #ifndef XFRACT
146 else if (fractype==MPNEWTBASIN)
147 {
148 if(parm.y)
149 basin = 2; /*stripes */
150 else
151 basin = 1;
152
153 if(degree > 16)
154 {
155 if((MPCroots=(struct MPC *)malloc(degree*sizeof(struct MPC)))==NULL)
156 {
157 MPCroots = (struct MPC *)staticroots;
158 degree = 16;
159 }
160 }
161 else
162 MPCroots = (struct MPC *)staticroots;
163
164 /* list of roots to discover where we converged for newtbasin */
165 for(i=0;i<degree;i++)
166 {
167 MPCroots[i].x = *pd2MP(cos(i*twopi/(double)degree));
168 MPCroots[i].y = *pd2MP(sin(i*twopi/(double)degree));
169 }
170 }
171 #endif
172
173 param[0] = (double)degree; /* JCO 7/1/92 */
174 if (degree%4 == 0)
175 symmetry = XYAXIS;
176 else
177 symmetry = XAXIS;
178
179 calctype=StandardFractal;
180 #ifndef XFRACT
181 if (fractype == MPNEWTON || fractype == MPNEWTBASIN)
182 setMPfunctions();
183 #endif
184 return(1);
185 }
186
187
188 int
189 StandaloneSetup(void)
190 {
191 timer(0,curfractalspecific->calctype);
192 return(0); /* effectively disable solid-guessing */
193 }
194
195 int
196 UnitySetup(void)
197 {
198 periodicitycheck = 0;
199 FgOne = (1L << bitshift);
200 FgTwo = FgOne + FgOne;
201 return(1);
202 }
203
204 int
205 MandelfpSetup(void)
206 {
207 bf_math = 0;
208 c_exp = (int)param[2];
209 pwr.x = param[2] - 1.0;
210 pwr.y = param[3];
211 floatparm = &init;
212 switch (fractype)
213 {
214 case MARKSMANDELFP:
215 if(c_exp < 1){
216 c_exp = 1;
217 param[2] = 1;
218 }
219 if(!(c_exp & 1))
220 symmetry = XYAXIS_NOPARM; /* odd exponents */
221 if(c_exp & 1)
222 symmetry = XAXIS_NOPARM;
223 break;
224 case MANDELFP:
225 /*
226 floating point code could probably be altered to handle many of
227 the situations that otherwise are using StandardFractal().
228 calcmandfp() can currently handle invert, any rqlim, potflag
229 zmag, epsilon cross, and all the current outside options
230 Wes Loewer 11/03/91
231 Took out support for inside= options, for speed. 7/13/97
232 */
233 if (debugflag != 90
234 && !distest
235 && decomp[0] == 0
236 && biomorph == -1
237 && (inside >= -1)
238 /* uncomment this next line if more outside options are added */
239 && outside >= -6
240 && useinitorbit != 1
241 && (soundflag & 0x07) < 2
242 && using_jiim == 0 && bailoutest == Mod
243 && (orbitsave&2) == 0)
244 {
245 calctype = calcmandfp; /* the normal case - use calcmandfp */
246 #ifndef XFRACT
247 if (cpu >= 386 && fpu >= 387)
248 {
249 calcmandfpasmstart_p5();
250 calcmandfpasm = (long (*)(void))calcmandfpasm_p5;
251 }
252 else if (cpu == 286 && fpu >= 287)
253 {
254 calcmandfpasmstart();
255 calcmandfpasm = (long (*)(void))calcmandfpasm_287;
256 }
257 else
258
259 {
260 calcmandfpasmstart();
261 calcmandfpasm = (long (*)(void))calcmandfpasm_87;
262 }
278 #endif
279 }
280 else
281 {
282 /* special case: use the main processing loop */
283 calctype = StandardFractal;
284 }
285 break;
286 case FPMANDELZPOWER:
287 if((double)c_exp == param[2] && (c_exp & 1)) /* odd exponents */
288 symmetry = XYAXIS_NOPARM;
289 if(param[3] != 0)
290 symmetry = NOSYM;
291 if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
292 fractalspecific[fractype].orbitcalc = floatZpowerFractal;
293 else
294 fractalspecific[fractype].orbitcalc = floatCmplxZpowerFractal;
295 break;
296 case MAGNET1M:
297 case MAGNET2M:
298 attr[0].x = 1.0; /* 1.0 + 0.0i always attracts */
299 attr[0].y = 0.0; /* - both MAGNET1 and MAGNET2 */
300 attrperiod[0] = 1;
301 attractors = 1;
302 break;
303 case SPIDERFP:
304 if(periodicitycheck==1) /* if not user set */
305 periodicitycheck=4;
306 break;
307 case MANDELEXP:
308 symmetry = XAXIS_NOPARM;
309 break;
310 /* Added to account for symmetry in manfn+exp and manfn+zsqrd */
311 /* JCO 2/29/92 */
312 case FPMANTRIGPLUSEXP:
313 case FPMANTRIGPLUSZSQRD:
314 if(parm.y == 0.0)
315 symmetry = XAXIS;
316 else
317 symmetry = NOSYM;
318 if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */
319 symmetry = NOSYM;
320 break;
321 case QUATFP:
322 floatparm = &tmp;
323 attractors = 0;
324 periodicitycheck = 0;
325 break;
326 case HYPERCMPLXFP:
327 floatparm = &tmp;
328 attractors = 0;
329 periodicitycheck = 0;
330 if(param[2] != 0)
331 symmetry = NOSYM;
332 if(trigndx[0] == 14) /* FLIP */
333 symmetry = NOSYM;
334 break;
335 case TIMSERRORFP:
336 if(trigndx[0] == 14) /* FLIP */
337 symmetry = NOSYM;
338 break;
339 case MARKSMANDELPWRFP:
340 if(trigndx[0] == 14) /* FLIP */
341 symmetry = NOSYM;
342 break;
343 default:
344 break;
345 }
346 return(1);
347 }
348
349 int
350 JuliafpSetup(void)
351 {
352 c_exp = (int)param[2];
353 floatparm = &parm;
354 if(fractype==COMPLEXMARKSJUL)
355 {
356 pwr.x = param[2] - 1.0;
357 pwr.y = param[3];
358 coefficient = ComplexPower(*floatparm, pwr);
359 }
360 switch (fractype)
361 {
362 case JULIAFP:
363 /*
364 floating point code could probably be altered to handle many of
365 the situations that otherwise are using StandardFractal().
366 calcmandfp() can currently handle invert, any rqlim, potflag
367 zmag, epsilon cross, and all the current outside options
368 Wes Loewer 11/03/91
369 Took out support for inside= options, for speed. 7/13/97
370 */
371 if (debugflag != 90
372 && !distest
373 && decomp[0] == 0
374 && biomorph == -1
375 && (inside >= -1)
376 /* uncomment this next line if more outside options are added */
377 && outside >= -6
378 && useinitorbit != 1
379 && (soundflag & 0x07) < 2
380 && !finattract
381 && using_jiim == 0 && bailoutest == Mod
382 && (orbitsave&2) == 0)
383 {
384 calctype = calcmandfp; /* the normal case - use calcmandfp */
385 #ifndef XFRACT
386 if (cpu >= 386 && fpu >= 387)
387 {
388 calcmandfpasmstart_p5();
389 calcmandfpasm = (long (*)(void))calcmandfpasm_p5;
390 }
391 else if (cpu == 286 && fpu >= 287)
392 {
393 calcmandfpasmstart();
394 calcmandfpasm = (long (*)(void))calcmandfpasm_287;
395 }
396 else
397 {
398 calcmandfpasmstart();
399 calcmandfpasm = (long (*)(void))calcmandfpasm_87;
400 }
416 #endif
417 }
418 else
419 {
420 /* special case: use the main processing loop */
421 calctype = StandardFractal;
422 get_julia_attractor (0.0, 0.0); /* another attractor? */
423 }
424 break;
425 case FPJULIAZPOWER:
426 if((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2] )
427 symmetry = NOSYM;
428 if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
429 fractalspecific[fractype].orbitcalc = floatZpowerFractal;
430 else
431 fractalspecific[fractype].orbitcalc = floatCmplxZpowerFractal;
432 get_julia_attractor (param[0], param[1]); /* another attractor? */
433 break;
434 case MAGNET2J:
435 FloatPreCalcMagnet2();
436 case MAGNET1J:
437 attr[0].x = 1.0; /* 1.0 + 0.0i always attracts */
438 attr[0].y = 0.0; /* - both MAGNET1 and MAGNET2 */
439 attrperiod[0] = 1;
440 attractors = 1;
441 get_julia_attractor (0.0, 0.0); /* another attractor? */
442 break;
443 case LAMBDAFP:
444 get_julia_attractor (0.0, 0.0); /* another attractor? */
445 get_julia_attractor (0.5, 0.0); /* another attractor? */
446 break;
447 case LAMBDAEXP:
448 if(parm.y == 0.0)
449 symmetry=XAXIS;
450 get_julia_attractor (0.0, 0.0); /* another attractor? */
451 break;
452 /* Added to account for symmetry in julfn+exp and julfn+zsqrd */
453 /* JCO 2/29/92 */
454 case FPJULTRIGPLUSEXP:
455 case FPJULTRIGPLUSZSQRD:
456 if(parm.y == 0.0)
457 symmetry = XAXIS;
458 else
459 symmetry = NOSYM;
460 if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */
461 symmetry = NOSYM;
462 get_julia_attractor (0.0, 0.0); /* another attractor? */
463 break;
464 case HYPERCMPLXJFP:
465 if(param[2] != 0)
466 symmetry = NOSYM;
467 if(trigndx[0] != SQR)
468 symmetry=NOSYM;
469 case QUATJULFP:
470 attractors = 0; /* attractors broken since code checks r,i not j,k */
471 periodicitycheck = 0;
472 if(param[4] != 0.0 || param[5] != 0)
473 symmetry = NOSYM;
474 break;
475 case FPPOPCORN:
476 case FPPOPCORNJUL:
477 {
478 int default_functions = 0;
479 if(trigndx[0] == SIN &&
480 trigndx[1] == TAN &&
481 trigndx[2] == SIN &&
482 trigndx[3] == TAN &&
483 fabs(parm2.x - 3.0) < .0001 &&
484 parm2.y == 0 &&
485 parm.y == 0)
486 {
487 default_functions = 1;
488 if(fractype == FPPOPCORNJUL)
489 symmetry = ORIGIN;
490 }
491 if(save_release <=1960)
492 curfractalspecific->orbitcalc = PopcornFractal_Old;
493 else if(default_functions && debugflag == 96)
494 curfractalspecific->orbitcalc = PopcornFractal;
495 else
496 curfractalspecific->orbitcalc = PopcornFractalFn;
497 get_julia_attractor (0.0, 0.0); /* another attractor? */
498 }
499 break;
500 case FPCIRCLE:
501 if (inside == STARTRAIL) /* FPCIRCLE locks up when used with STARTRAIL */
502 inside = 0; /* arbitrarily set inside = NUMB */
503 get_julia_attractor (0.0, 0.0); /* another attractor? */
504 break;
505 default:
506 get_julia_attractor (0.0, 0.0); /* another attractor? */
507 break;
508 }
509 return(1);
510 }
511
512 int
513 MandellongSetup(void)
514 {
515 FgHalf = fudge >> 1;
516 c_exp = (int)param[2];
517 if(fractype==MARKSMANDEL && c_exp < 1){
518 c_exp = 1;
519 param[2] = 1;
520 }
521 if((fractype==MARKSMANDEL && !(c_exp & 1)) ||
522 (fractype==LMANDELZPOWER && (c_exp & 1)))
523 symmetry = XYAXIS_NOPARM; /* odd exponents */
524 if((fractype==MARKSMANDEL && (c_exp & 1)) || fractype==LMANDELEXP)
525 symmetry = XAXIS_NOPARM;
526 if(fractype==SPIDER && periodicitycheck==1)
527 periodicitycheck=4;
528 longparm = &linit;
529 if(fractype==LMANDELZPOWER)
530 {
531 if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
532 fractalspecific[fractype].orbitcalc = longZpowerFractal;
533 else
534 fractalspecific[fractype].orbitcalc = longCmplxZpowerFractal;
535 if(param[3] != 0 || (double)c_exp != param[2] )
536 symmetry = NOSYM;
537 }
538 /* Added to account for symmetry in manfn+exp and manfn+zsqrd */
539 /* JCO 2/29/92 */
540 if((fractype==LMANTRIGPLUSEXP)||(fractype==LMANTRIGPLUSZSQRD))
541 {
542 if(parm.y == 0.0)
543 symmetry = XAXIS;
544 else
545 symmetry = NOSYM;
546 if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */
547 symmetry = NOSYM;
548 }
549 if(fractype == TIMSERROR)
550 {
551 if(trigndx[0] == 14) /* FLIP */
552 symmetry = NOSYM;
553 }
554 if(fractype == MARKSMANDELPWR)
555 {
556 if(trigndx[0] == 14) /* FLIP */
557 symmetry = NOSYM;
558 }
559 return(1);
560 }
561
562 int
563 JulialongSetup(void)
564 {
565 c_exp = (int)param[2];
566 longparm = &lparm;
567 switch (fractype)
568 {
569 case LJULIAZPOWER:
570 if((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2])
571 symmetry = NOSYM;
572 if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
573 fractalspecific[fractype].orbitcalc = longZpowerFractal;
574 else
575 fractalspecific[fractype].orbitcalc = longCmplxZpowerFractal;
576 break;
577 case LAMBDA:
578 get_julia_attractor (0.0, 0.0); /* another attractor? */
579 get_julia_attractor (0.5, 0.0); /* another attractor? */
580 break;
581 case LLAMBDAEXP:
582 if(lparm.y == 0)
583 symmetry = XAXIS;
584 break;
585 /* Added to account for symmetry in julfn+exp and julfn+zsqrd */
586 /* JCO 2/29/92 */
587 case LJULTRIGPLUSEXP:
588 case LJULTRIGPLUSZSQRD:
589 if(parm.y == 0.0)
590 symmetry = XAXIS;
591 else
592 symmetry = NOSYM;
593 if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */
594 symmetry = NOSYM;
595 get_julia_attractor (0.0, 0.0); /* another attractor? */
596 break;
597 case LPOPCORN:
598 case LPOPCORNJUL:
599 {
600 int default_functions = 0;
601 if(trigndx[0] == SIN &&
602 trigndx[1] == TAN &&
603 trigndx[2] == SIN &&
604 trigndx[3] == TAN &&
605 fabs(parm2.x - 3.0) < .0001 &&
606 parm2.y == 0 &&
607 parm.y == 0)
608 {
609 default_functions = 1;
610 if(fractype == LPOPCORNJUL)
611 symmetry = ORIGIN;
612 }
613 if(save_release <=1960)
614 curfractalspecific->orbitcalc = LPopcornFractal_Old;
615 else if(default_functions && debugflag == 96)
616 curfractalspecific->orbitcalc = LPopcornFractal;
617 else
618 curfractalspecific->orbitcalc = LPopcornFractalFn;
619 get_julia_attractor (0.0, 0.0); /* another attractor? */
620 }
621 break;
622 default:
623 get_julia_attractor (0.0, 0.0); /* another attractor? */
624 break;
625 }
626 return(1);
627 }
628
629 int
630 TrigPlusSqrlongSetup(void)
631 {
632 curfractalspecific->per_pixel = julia_per_pixel;
633 curfractalspecific->orbitcalc = TrigPlusSqrFractal;
634 if(lparm.x == fudge && lparm.y == 0L && lparm2.y == 0L && debugflag != 90)
635 {
636 if(lparm2.x == fudge) /* Scott variant */
637 curfractalspecific->orbitcalc = ScottTrigPlusSqrFractal;
638 else if(lparm2.x == -fudge) /* Skinner variant */
639 curfractalspecific->orbitcalc = SkinnerTrigSubSqrFractal;
640 }
641 return(JulialongSetup());
642 }
643
644 int
645 TrigPlusSqrfpSetup(void)
646 {
647 curfractalspecific->per_pixel = juliafp_per_pixel;
648 curfractalspecific->orbitcalc = TrigPlusSqrfpFractal;
649 if(parm.x == 1.0 && parm.y == 0.0 && parm2.y == 0.0 && debugflag != 90)
650 {
651 if(parm2.x == 1.0) /* Scott variant */
652 curfractalspecific->orbitcalc = ScottTrigPlusSqrfpFractal;
653 else if(parm2.x == -1.0) /* Skinner variant */
654 curfractalspecific->orbitcalc = SkinnerTrigSubSqrfpFractal;
655 }
656 return(JuliafpSetup());
657 }
658
659 int
660 TrigPlusTriglongSetup(void)
661 {
662 FnPlusFnSym();
663 if(trigndx[1] == SQR)
664 return(TrigPlusSqrlongSetup());
665 curfractalspecific->per_pixel = long_julia_per_pixel;
666 curfractalspecific->orbitcalc = TrigPlusTrigFractal;
667 if(lparm.x == fudge && lparm.y == 0L && lparm2.y == 0L && debugflag != 90)
668 {
669 if(lparm2.x == fudge) /* Scott variant */
670 curfractalspecific->orbitcalc = ScottTrigPlusTrigFractal;
671 else if(lparm2.x == -fudge) /* Skinner variant */
672 curfractalspecific->orbitcalc = SkinnerTrigSubTrigFractal;
673 }
674 return(JulialongSetup());
675 }
676
677 int
678 TrigPlusTrigfpSetup(void)
679 {
680 FnPlusFnSym();
681 if(trigndx[1] == SQR)
682 return(TrigPlusSqrfpSetup());
683 curfractalspecific->per_pixel = otherjuliafp_per_pixel;
684 curfractalspecific->orbitcalc = TrigPlusTrigfpFractal;
685 if(parm.x == 1.0 && parm.y == 0.0 && parm2.y == 0.0 && debugflag != 90)
686 {
687 if(parm2.x == 1.0) /* Scott variant */
688 curfractalspecific->orbitcalc = ScottTrigPlusTrigfpFractal;
689 else if(parm2.x == -1.0) /* Skinner variant */
690 curfractalspecific->orbitcalc = SkinnerTrigSubTrigfpFractal;
691 }
692 return(JuliafpSetup());
693 }
694
695 int
696 FnPlusFnSym(void) /* set symmetry matrix for fn+fn type */
697 {
698 static char far fnplusfn[7][7] =
699 {/* fn2 ->sin cos sinh cosh exp log sqr */
700 /* fn1 */
701 /* sin */ {PI_SYM,XAXIS, XYAXIS, XAXIS, XAXIS, XAXIS, XAXIS},
702 /* cos */ {XAXIS, PI_SYM,XAXIS, XYAXIS,XAXIS, XAXIS, XAXIS},
703 /* sinh*/ {XYAXIS,XAXIS, XYAXIS, XAXIS, XAXIS, XAXIS, XAXIS},
704 /* cosh*/ {XAXIS, XYAXIS,XAXIS, XYAXIS,XAXIS, XAXIS, XAXIS},
705 /* exp */ {XAXIS, XYAXIS,XAXIS, XAXIS, XYAXIS,XAXIS, XAXIS},
706 /* log */ {XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, XAXIS},
707 /* sqr */ {XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, XYAXIS}
708 };
709 if(parm.y == 0.0 && parm2.y == 0.0)
710 { if(trigndx[0] < 7 && trigndx[1] < 7) /* bounds of array JCO 5/6/92*/
711 symmetry = fnplusfn[trigndx[0]][trigndx[1]]; /* JCO 5/6/92 */
712 if(trigndx[0] == 14 || trigndx[1] == 14) /* FLIP */
713 symmetry = NOSYM;
714 } /* defaults to XAXIS symmetry JCO 5/6/92 */
715 else
716 symmetry = NOSYM;
717 return(0);
718 }
719
720 int
721 LambdaTrigOrTrigSetup(void)
722 {
723 /* default symmetry is ORIGIN JCO 2/29/92 (changed from PI_SYM) */
724 longparm = &lparm; /* added to consolidate code 10/1/92 JCO */
725 floatparm = &parm;
726 if ((trigndx[0] == EXP) || (trigndx[1] == EXP))
727 symmetry = NOSYM; /* JCO 1/9/93 */
728 if ((trigndx[0] == LOG) || (trigndx[1] == LOG))
729 symmetry = XAXIS;
730 get_julia_attractor (0.0, 0.0); /* an attractor? */
731 return(1);
732 }
733
734 int
735 JuliaTrigOrTrigSetup(void)
736 {
737 /* default symmetry is XAXIS */
738 longparm = &lparm; /* added to consolidate code 10/1/92 JCO */
739 floatparm = &parm;
740 if(parm.y != 0.0)
741 symmetry = NOSYM;
742 if(trigndx[0] == 14 || trigndx[1] == 14) /* FLIP */
743 symmetry = NOSYM;
744 get_julia_attractor (0.0, 0.0); /* an attractor? */
745 return(1);
746 }
747
748 int
749 ManlamTrigOrTrigSetup(void)
750 { /* psuedo */
751 /* default symmetry is XAXIS */
752 longparm = &linit; /* added to consolidate code 10/1/92 JCO */
753 floatparm = &init;
754 if (trigndx[0] == SQR)
755 symmetry = NOSYM;
756 if ((trigndx[0] == LOG) || (trigndx[1] == LOG))
757 symmetry = NOSYM;
758 return(1);
759 }
760
761 int
762 MandelTrigOrTrigSetup(void)
763 {
764 /* default symmetry is XAXIS_NOPARM */
765 longparm = &linit; /* added to consolidate code 10/1/92 JCO */
766 floatparm = &init;
767 if ((trigndx[0] == 14) || (trigndx[1] == 14)) /* FLIP JCO 5/28/92 */
768 symmetry = NOSYM;
769 return(1);
770 }
771
772
773 int
774 ZXTrigPlusZSetup(void)
775 {
776 /* static char far ZXTrigPlusZSym1[] = */
777 /* fn1 -> sin cos sinh cosh exp log sqr */
778 /* {XAXIS,XYAXIS,XAXIS,XYAXIS,XAXIS,NOSYM,XYAXIS}; */
779 /* static char far ZXTrigPlusZSym2[] = */
780 /* fn1 -> sin cos sinh cosh exp log sqr */
781 /* {NOSYM,ORIGIN,NOSYM,ORIGIN,NOSYM,NOSYM,ORIGIN}; */
782
783 if(param[1] == 0.0 && param[3] == 0.0)
784 /* symmetry = ZXTrigPlusZSym1[trigndx[0]]; */
785 switch(trigndx[0])
786 {
787 case COS: /* changed to two case statments and made any added */
788 case COSH: /* functions default to XAXIS symmetry. JCO 5/25/92 */
789 case SQR:
790 case 9: /* 'real' cos */
791 symmetry = XYAXIS;
792 break;
793 case 14: /* FLIP JCO 2/29/92 */
794 symmetry = YAXIS;
795 break;
796 case LOG:
797 symmetry = NOSYM;
798 break;
799 default:
800 symmetry = XAXIS;
801 break;
802 }
803 else
804 /* symmetry = ZXTrigPlusZSym2[trigndx[0]]; */
805 switch(trigndx[0])
806 {
807 case COS:
808 case COSH:
809 case SQR:
810 case 9: /* 'real' cos */
811 symmetry = ORIGIN;
812 break;
813 case 14: /* FLIP JCO 2/29/92 */
814 symmetry = NOSYM;
815 break;
816 default:
817 symmetry = NOSYM;
818 break;
819 }
820 if(curfractalspecific->isinteger)
821 {
822 curfractalspecific->orbitcalc = ZXTrigPlusZFractal;
823 if(lparm.x == fudge && lparm.y == 0L && lparm2.y == 0L && debugflag != 90)
824 {
825 if(lparm2.x == fudge) /* Scott variant */
826 curfractalspecific->orbitcalc = ScottZXTrigPlusZFractal;
827 else if(lparm2.x == -fudge) /* Skinner variant */
828 curfractalspecific->orbitcalc = SkinnerZXTrigSubZFractal;
829 }
830 return(JulialongSetup());
831 }
832 else
833 {
834 curfractalspecific->orbitcalc = ZXTrigPlusZfpFractal;
835 if(parm.x == 1.0 && parm.y == 0.0 && parm2.y == 0.0 && debugflag != 90)
836 {
837 if(parm2.x == 1.0) /* Scott variant */
838 curfractalspecific->orbitcalc = ScottZXTrigPlusZfpFractal;
839 else if(parm2.x == -1.0) /* Skinner variant */
840 curfractalspecific->orbitcalc = SkinnerZXTrigSubZfpFractal;
841 }
842 }
843 return(JuliafpSetup());
844 }
845
846 int
847 LambdaTrigSetup(void)
848 {
849 int isinteger;
850 if((isinteger = curfractalspecific->isinteger) != 0)
851 curfractalspecific->orbitcalc = LambdaTrigFractal;
852 else
853 curfractalspecific->orbitcalc = LambdaTrigfpFractal;
854 switch(trigndx[0])
855 {
856 case SIN:
857 case COS:
858 case 9: /* 'real' cos, added this and default for additional functions */
859 symmetry = PI_SYM;
860 if(isinteger)
861 curfractalspecific->orbitcalc = LambdaTrigFractal1;
862 else
863 curfractalspecific->orbitcalc = LambdaTrigfpFractal1;
864 break;
865 case SINH:
866 case COSH:
867 symmetry = ORIGIN;
868 if(isinteger)
869 curfractalspecific->orbitcalc = LambdaTrigFractal2;
870 else
871 curfractalspecific->orbitcalc = LambdaTrigfpFractal2;
872 break;
873 case SQR:
874 symmetry = ORIGIN;
875 break;
876 case EXP:
877 if(isinteger)
878 curfractalspecific->orbitcalc = LongLambdaexponentFractal;
879 else
880 curfractalspecific->orbitcalc = LambdaexponentFractal;
881 symmetry = NOSYM; /* JCO 1/9/93 */
882 break;
883 case LOG:
884 symmetry = NOSYM;
885 break;
886 default: /* default for additional functions */
887 symmetry = ORIGIN; /* JCO 5/8/92 */
888 break;
889 }
890 get_julia_attractor (0.0, 0.0); /* an attractor? */
891 if(isinteger)
892 return(JulialongSetup());
893 else
894 return(JuliafpSetup());
895 }
896
897 int
898 JuliafnPlusZsqrdSetup(void)
899 {
900 /* static char far fnpluszsqrd[] = */
901 /* fn1 -> sin cos sinh cosh sqr exp log */
902 /* sin {NOSYM,ORIGIN,NOSYM,ORIGIN,ORIGIN,NOSYM,NOSYM}; */
903
904 /* symmetry = fnpluszsqrd[trigndx[0]]; JCO 5/8/92 */
905 switch(trigndx[0]) /* fix sqr symmetry & add additional functions */
906 {
907 case COS: /* cosxx */
908 case COSH:
909 case SQR:
910 case 9: /* 'real' cos */
911 case 10: /* tan */
912 case 11: /* tanh */
913 symmetry = ORIGIN;
914 /* default is for NOSYM symmetry */
915 }
916 if(curfractalspecific->isinteger)
917 return(JulialongSetup());
918 else
919 return(JuliafpSetup());
920 }
921
922 int
923 SqrTrigSetup(void)
924 {
925 /* static char far SqrTrigSym[] = */
926 /* fn1 -> sin cos sinh cosh sqr exp log */
927 /* {PI_SYM,PI_SYM,XYAXIS,XYAXIS,XYAXIS,XAXIS,XAXIS}; */
928 /* symmetry = SqrTrigSym[trigndx[0]]; JCO 5/9/92 */
929 switch(trigndx[0]) /* fix sqr symmetry & add additional functions */
930 {
931 case SIN:
932 case COS: /* cosxx */
933 case 9: /* 'real' cos */
934 symmetry = PI_SYM;
935 /* default is for XAXIS symmetry */
936 }
937 if(curfractalspecific->isinteger)
938 return(JulialongSetup());
939 else
940 return(JuliafpSetup());
941 }
942
943 int
944 FnXFnSetup(void)
945 {
946 static char far fnxfn[7][7] =
947 {/* fn2 ->sin cos sinh cosh exp log sqr */
948 /* fn1 */
949 /* sin */ {PI_SYM,YAXIS, XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS},
950 /* cos */ {YAXIS, PI_SYM,XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS},
951 /* sinh*/ {XYAXIS,XYAXIS,XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS},
952 /* cosh*/ {XYAXIS,XYAXIS,XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS},
953 /* exp */ {XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, NOSYM, XYAXIS},
954 /* log */ {NOSYM, NOSYM, NOSYM, NOSYM, NOSYM, XAXIS, NOSYM},
955 /* sqr */ {XYAXIS,XYAXIS,XYAXIS,XYAXIS,XYAXIS,NOSYM, XYAXIS},
956 };
957 /*
958 if(trigndx[0]==EXP || trigndx[0]==LOG || trigndx[1]==EXP || trigndx[1]==LOG)
959 symmetry = XAXIS;
960 else if((trigndx[0]==SIN && trigndx[1]==SIN)||(trigndx[0]==COS && trigndx[1]==COS))
961 symmetry = PI_SYM;
962 else if((trigndx[0]==SIN && trigndx[1]==COS)||(trigndx[0]==COS && trigndx[1]==SIN))
963 symmetry = YAXIS;
964 else
965 symmetry = XYAXIS;
966 */
967 if(trigndx[0] < 7 && trigndx[1] < 7) /* bounds of array JCO 5/22/92*/
968 symmetry = fnxfn[trigndx[0]][trigndx[1]]; /* JCO 5/22/92 */
969 /* defaults to XAXIS symmetry JCO 5/22/92 */
970 else { /* added to complete the symmetry JCO 5/22/92 */
971 if (trigndx[0]==LOG || trigndx[1] ==LOG) symmetry = NOSYM;
972 if (trigndx[0]==9 || trigndx[1] ==9) { /* 'real' cos */
973 if (trigndx[0]==SIN || trigndx[1] ==SIN) symmetry = PI_SYM;
974 if (trigndx[0]==COS || trigndx[1] ==COS) symmetry = PI_SYM;
975 }
976 if (trigndx[0]==9 && trigndx[1] ==9) symmetry = PI_SYM;
977 }
978 if(curfractalspecific->isinteger)
979 return(JulialongSetup());
980 else
981 return(JuliafpSetup());
982 }
983
984 int
985 MandelTrigSetup(void)
986 {
987 int isinteger;
988 if((isinteger = curfractalspecific->isinteger) != 0)
989 curfractalspecific->orbitcalc = LambdaTrigFractal;
990 else
991 curfractalspecific->orbitcalc = LambdaTrigfpFractal;
992 symmetry = XYAXIS_NOPARM;
993 switch(trigndx[0])
994 {
995 case SIN:
996 case COS:
997 if(isinteger)
998 curfractalspecific->orbitcalc = LambdaTrigFractal1;
999 else
1000 curfractalspecific->orbitcalc = LambdaTrigfpFractal1;
1001 break;
1002 case SINH:
1003 case COSH:
1004 if(isinteger)
1005 curfractalspecific->orbitcalc = LambdaTrigFractal2;
1006 else
1007 curfractalspecific->orbitcalc = LambdaTrigfpFractal2;
1008 break;
1009 case EXP:
1010 symmetry = XAXIS_NOPARM;
1011 if(isinteger)
1012 curfractalspecific->orbitcalc = LongLambdaexponentFractal;
1013 else
1014 curfractalspecific->orbitcalc = LambdaexponentFractal;
1015 break;
1016 case LOG:
1017 symmetry = XAXIS_NOPARM;
1018 break;
1019 default: /* added for additional functions, JCO 5/25/92 */
1020 symmetry = XYAXIS_NOPARM;
1021 break;
1022 }
1023 if(isinteger)
1024 return(MandellongSetup());
1025 else
1026 return(MandelfpSetup());
1027 }
1028
1029 int
1030 MarksJuliaSetup(void)
1031 {
1032 #ifndef XFRACT
1033 if(param[2] < 1)
1034 param[2] = 1;
1035 c_exp = (int)param[2];
1036 longparm = &lparm;
1037 lold = *longparm;
1038 if(c_exp > 3)
1039 lcpower(&lold,c_exp-1,&lcoefficient,bitshift);
1040 else if(c_exp == 3)
1041 {
1042 lcoefficient.x = multiply(lold.x,lold.x,bitshift) - multiply(lold.y,lold.y,bitshift);
1043 lcoefficient.y = multiply(lold.x,lold.y,bitshiftless1);
1044 }
1045 else if(c_exp == 2)
1046 lcoefficient = lold;
1047 else if(c_exp < 2) {
1048 lcoefficient.x = 1L << bitshift;
1049 lcoefficient.y = 0L;
1050 }
1051 get_julia_attractor (0.0, 0.0); /* an attractor? */
1052 #endif
1053 return(1);
1054 }
1055
1056 int
1057 MarksJuliafpSetup(void)
1058 {
1059 if(param[2] < 1)
1060 param[2] = 1;
1061 c_exp = (int)param[2];
1062 floatparm = &parm;
1063 old = *floatparm;
1064 if(c_exp > 3)
1065 cpower(&old,c_exp-1,&coefficient);
1066 else if(c_exp == 3)
1067 {
1068 coefficient.x = sqr(old.x) - sqr(old.y);
1069 coefficient.y = old.x * old.y * 2;
1070 }
1071 else if(c_exp == 2)
1072 coefficient = old;
1073 else if(c_exp < 2) {
1074 coefficient.x = 1.0;
1075 coefficient.y = 0.0;
1076 }
1077 get_julia_attractor (0.0, 0.0); /* an attractor? */
1078 return(1);
1079 }
1080
1081 int
1082 SierpinskiSetup(void)
1083 {
1084 /* sierpinski */
1085 periodicitycheck = 0; /* disable periodicity checks */
1086 ltmp.x = 1;
1087 ltmp.x = ltmp.x << bitshift; /* ltmp.x = 1 */
1088 ltmp.y = ltmp.x >> 1; /* ltmp.y = .5 */
1089 return(1);
1090 }
1091
1092 int
1093 SierpinskiFPSetup(void)
1094 {
1095 /* sierpinski */
1096 periodicitycheck = 0; /* disable periodicity checks */
1097 tmp.x = 1;
1098 tmp.y = 0.5;
1099 return(1);
1100 }
1101
1102 int
1103 HalleySetup(void)
1104 {
1105 /* Halley */
1106 periodicitycheck=0;
1107
1108 if(usr_floatflag)
1109 fractype = HALLEY; /* float on */
1110 else
1111 fractype = MPHALLEY;
1112
1113 curfractalspecific = &fractalspecific[fractype];
1114
1115 degree = (int)parm.x;
1116 if(degree < 2)
1117 degree = 2;
1118 param[0] = (double)degree;
1119
1120 /* precalculated values */
1121 AplusOne = degree + 1; /* a+1 */
1122 Ap1deg = AplusOne * degree;
1123
1124 #ifndef XFRACT
1125 if(fractype == MPHALLEY) {
1126 setMPfunctions();
1127 mpAplusOne = *pd2MP((double)AplusOne);
1128 mpAp1deg = *pd2MP((double)Ap1deg);
1129 mpctmpparm.x = *pd2MP(parm.y);
1130 mpctmpparm.y = *pd2MP(parm2.y);
1131 mptmpparm2x = *pd2MP(parm2.x);
1132 mpone = *pd2MP(1.0);
1133 }
1134 #endif
1135
1136 if(degree % 2)
1137 symmetry = XAXIS; /* odd */
1138 else
1139 symmetry = XYAXIS; /* even */
1140 return(1);
1141 }
1142
1143 int
1144 PhoenixSetup(void)
1145 {
1146 longparm = &lparm; /* added to consolidate code 10/1/92 JCO */
1147 floatparm = &parm;
1148 degree = (int)parm2.x;
1149 if(degree < 2 && degree > -3) degree = 0;
1150 param[2] = (double)degree;
1151 if(degree == 0){
1152 if(usr_floatflag)
1153 curfractalspecific->orbitcalc = PhoenixFractal;
1154 else
1155 curfractalspecific->orbitcalc = LongPhoenixFractal;
1156 }
1157 if(degree >= 2){
1158 degree = degree - 1;
1159 if(usr_floatflag)
1160 curfractalspecific->orbitcalc = PhoenixPlusFractal;
1161 else
1162 curfractalspecific->orbitcalc = LongPhoenixPlusFractal;
1163 }
1164 if(degree <= -3){
1165 degree = abs(degree) - 2;
1166 if(usr_floatflag)
1167 curfractalspecific->orbitcalc = PhoenixMinusFractal;
1168 else
1169 curfractalspecific->orbitcalc = LongPhoenixMinusFractal;
1170 }
1171
1172 return(1);
1173 }
1174
1175 int
1176 PhoenixCplxSetup(void)
1177 {
1178 longparm = &lparm;
1179 floatparm = &parm;
1180 degree = (int)param[4];
1181 if(degree < 2 && degree > -3) degree = 0;
1182 param[4] = (double)degree;
1183 if(degree == 0){
1184 if(parm2.x != 0 || parm2.y != 0)
1185 symmetry = NOSYM;
1186 else
1187 symmetry = ORIGIN;
1188 if(parm.y == 0 && parm2.y == 0)
1189 symmetry = XAXIS;
1190 if(usr_floatflag)
1191 curfractalspecific->orbitcalc = PhoenixFractalcplx;
1192 else
1193 curfractalspecific->orbitcalc = LongPhoenixFractalcplx;
1194 }
1195 if(degree >= 2){
1196 degree = degree - 1;
1197 if(parm.y == 0 && parm2.y == 0)
1198 symmetry = XAXIS;
1199 else
1200 symmetry = NOSYM;
1201 if(usr_floatflag)
1202 curfractalspecific->orbitcalc = PhoenixCplxPlusFractal;
1203 else
1204 curfractalspecific->orbitcalc = LongPhoenixCplxPlusFractal;
1205 }
1206 if(degree <= -3){
1207 degree = abs(degree) - 2;
1208 if(parm.y == 0 && parm2.y == 0)
1209 symmetry = XAXIS;
1210 else
1211 symmetry = NOSYM;
1212 if(usr_floatflag)
1213 curfractalspecific->orbitcalc = PhoenixCplxMinusFractal;
1214 else
1215 curfractalspecific->orbitcalc = LongPhoenixCplxMinusFractal;
1216 }
1217
1218 return(1);
1219 }
1220
1221 int
1222 MandPhoenixSetup(void)
1223 {
1224 longparm = &linit; /* added to consolidate code 10/1/92 JCO */
1225 floatparm = &init;
1226 degree = (int)parm2.x;
1227 if(degree < 2 && degree > -3) degree = 0;
1228 param[2] = (double)degree;
1229 if(degree == 0){
1230 if(usr_floatflag)
1231 curfractalspecific->orbitcalc = PhoenixFractal;
1232 else
1233 curfractalspecific->orbitcalc = LongPhoenixFractal;
1234 }
1235 if(degree >= 2){
1236 degree = degree - 1;
1237 if(usr_floatflag)
1238 curfractalspecific->orbitcalc = PhoenixPlusFractal;
1239 else
1240 curfractalspecific->orbitcalc = LongPhoenixPlusFractal;
1241 }
1242 if(degree <= -3){
1243 degree = abs(degree) - 2;
1244 if(usr_floatflag)
1245 curfractalspecific->orbitcalc = PhoenixMinusFractal;
1246 else
1247 curfractalspecific->orbitcalc = LongPhoenixMinusFractal;
1248 }
1249
1250 return(1);
1251 }
1252
1253 int
1254 MandPhoenixCplxSetup(void)
1255 {
1256 longparm = &linit; /* added to consolidate code 10/1/92 JCO */
1257 floatparm = &init;
1258 degree = (int)param[4];
1259 if(degree < 2 && degree > -3) degree = 0;
1260 param[4] = (double)degree;
1261 if(parm.y != 0 || parm2.y != 0)
1262 symmetry = NOSYM;
1263 if(degree == 0){
1264 if(usr_floatflag)
1265 curfractalspecific->orbitcalc = PhoenixFractalcplx;
1266 else
1267 curfractalspecific->orbitcalc = LongPhoenixFractalcplx;
1268 }
1269 if(degree >= 2){
1270 degree = degree - 1;
1271 if(usr_floatflag)
1272 curfractalspecific->orbitcalc = PhoenixCplxPlusFractal;
1273 else
1274 curfractalspecific->orbitcalc = LongPhoenixCplxPlusFractal;
1275 }
1276 if(degree <= -3){
1277 degree = abs(degree) - 2;
1278 if(usr_floatflag)
1279 curfractalspecific->orbitcalc = PhoenixCplxMinusFractal;
1280 else
1281 curfractalspecific->orbitcalc = LongPhoenixCplxMinusFractal;
1282 }
1283
1284 return(1);
1285 }
1286
1287 int
1288 StandardSetup(void)
1289 {
1290 if(fractype==UNITYFP)
1291 periodicitycheck=0;
1292 return(1);
1293 }
1294
1295 int
1296 VLSetup(void)
1297 {
1298 if (param[0] < 0.0) param[0] = 0.0;
1299 if (param[1] < 0.0) param[1] = 0.0;
1300 if (param[0] > 1.0) param[0] = 1.0;
1301 if (param[1] > 1.0) param[1] = 1.0;
1302 floatparm = &parm;
1303 return 1;
1304 }
1305