home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 November / Chip_2001-11_cd1.bin / sharewar / chaospro / cpro302.exe / LKM.CCL < prev    next >
Encoding:
Text File  |  2001-07-15  |  116.9 KB  |  5,977 lines

  1. comment {
  2.  
  3. Coloring schemes developed by Kerry Mitchell
  4.  
  5. Compilation dated 15jul2001
  6.  
  7. Includes:
  8.   Basic
  9.   Basic Plus
  10.   Emboss
  11.   Gaussian Integer
  12.   Statistics
  13.   Polar Curves
  14.   Astroid
  15.   5 Point Star
  16.   Conic Sections
  17.   Conic Lite
  18.   2 Sections
  19.   Conic Lite Old
  20.   Bubbles
  21.   Range
  22.   Passthru
  23.   Distance to a Point
  24.   Pythagorean Triple
  25.   Spiral
  26.   Grid
  27.   Single Truchet
  28.   Double Truchet
  29.   Rose Curve String Art
  30.   Astroid String Art
  31.   Crosshatch
  32. }
  33.  
  34.  
  35. basic { // Kerry Mitchell 20sep98
  36. //
  37. // The standard coloring parameters:
  38. // polar angle (includes all 4 quadrants
  39. // instead of only 2 from atan),
  40. // magnitude of z, real(z), imag(z),
  41. // and iteration number.
  42. //
  43. real Var_x;
  44. real Var_y;
  45. parameter int colorby;
  46. real t;
  47.  
  48.     void init(void)
  49.     {
  50.     }
  51.     void loop(void)
  52.     {
  53.     }
  54.     void final(void)
  55.     {
  56.         Var_x=real(z);
  57.         Var_y=imag(z);
  58.         if ((colorby==1))
  59.         {// polar angle
  60.             t=atan2(z);
  61.             t=t/pi;
  62.             if ((t<0.0))
  63.             {
  64.                 t=t+2.0;
  65.             }
  66.             index=0.5*t;
  67.         }
  68.         else if ((colorby==2))
  69.         {// magnitude
  70.             index=cabs(z);
  71.         }
  72.         else if ((colorby==3))
  73.         {// real(z)
  74.             index=Var_x;
  75.         }
  76.         else if ((colorby==4))
  77.         {// imag(z)
  78.             index=Var_y;
  79.         }
  80.         else
  81.         {
  82.                      // iteration
  83.             index=0.01*numiter;
  84.         }
  85.     }
  86.     void description(void)
  87.     {
  88.         this.title="Basic";
  89.    
  90.         colorby.caption = "color by";
  91.         colorby.default = 0;
  92.         colorby.enum = "iteration\npolar angle\nmagnitude\nreal(z)\nimag(z)";
  93.   
  94.     }
  95. }
  96.  
  97.  
  98. basic-plus { // Kerry Mitchell 26feb99
  99. //
  100. // The standard coloring parameters:
  101. // polar angle, magnitude, real, imag
  102. // for z, pixel, z-pixel, & z/pixel
  103. // and iteration number.
  104. //
  105. // Replaces the "Basic" coloring formula
  106. //
  107. complex var;
  108. real t;
  109. parameter int vartype;
  110. parameter int colorby;
  111.  
  112.     void init(void)
  113.     {
  114.         var=(0.0,0.0);
  115.         t=0.0;
  116.     }
  117.     void loop(void)
  118.     {
  119.     }
  120.     void final(void)
  121.     {
  122. //
  123. // establish variable used for coloring
  124. //
  125.         if ((vartype==1))
  126.         {// pixel
  127.             var=pixel;
  128.         }
  129.         else if ((vartype==2))
  130.         {// z-pixel
  131.             var=z-pixel;
  132.         }
  133.         else if ((vartype==3))
  134.         {// z/pixel
  135.             var=z/pixel;
  136.         }
  137.         else
  138.         {
  139.                     // z
  140.             var=z;
  141.         }
  142. //
  143. // pick coloring characteristic
  144. //
  145.         if ((colorby==1))
  146.         {// polar angle
  147.             t=atan2(var);
  148.             t=t/pi;
  149.             if ((t<0.0))
  150.             {
  151.                 t=t+2.0;
  152.             }
  153.             index=0.5*t;
  154.         }
  155.         else if ((colorby==2))
  156.         {// magnitude
  157.             index=cabs(var);
  158.         }
  159.         else if ((colorby==3))
  160.         {// real
  161.             index=real(var);
  162.         }
  163.         else if ((colorby==4))
  164.         {// imag
  165.             index=imag(var);
  166.         }
  167.         else
  168.         {
  169.                      // iteration
  170.             index=0.01*numiter;
  171.         }
  172.     }
  173.     void description(void)
  174.     {
  175.         this.title="Basic Plus";
  176.    
  177.         vartype.caption="variable";
  178.         vartype.default=0;
  179.         vartype.enum="z\npixel\nz-pixel\nz/pixel";
  180.   
  181.    
  182.         colorby.caption="color by";
  183.         colorby.default=0;
  184.         colorby.enum="iteration\npolar angle\nmagnitude\nreal part\nimag part";
  185.   
  186.     }
  187. }
  188.  
  189.  
  190. emboss { // Kerry Mitchell 13sep98
  191. //
  192. // For use with "Emboss" formulas and
  193. // gradient.  Uses 3 colors:
  194. // #index values of 0.2, 0.5, and 0.8.
  195. //
  196.  
  197.     void final(void)
  198.     {
  199.         if ((real(z)<imag(z)))
  200.         {
  201.             index=0.2;
  202.         }
  203.         else if ((imag(z)<real(z)))
  204.         {
  205.             index=0.8;
  206.         }
  207.         else
  208.         {
  209.  
  210.             index=0.5;
  211.         }
  212.     }
  213.     void description(void)
  214.     {
  215.         this.title="Emboss";
  216.     }
  217. }
  218.  
  219.  
  220. comment { ; narrative copyright Kerry Mitchell 20sep98
  221.  
  222. Gaussian Integer Coloring
  223.  
  224. Gaussian integers are complex numbers such that both the real and
  225. imaginary parts are integers.  Examples are:  (0,0), (-2,3), (17,-5),
  226. and (1000000,123456789).  The gaussian scheme is concerned with how
  227. the orbit behaves relative to a Gaussian integer.
  228.  
  229. To find the Gaussian integer which the orbit most closely approaches,
  230. the built-in function round() is used.  Round(z) returns a complex
  231. number whose components are the rounded components of z.  This is a
  232. Gaussian integer.  The distance from z to round(z) is simply the
  233. magnitude of z - round(z).  The "minimum distance" method tracks this
  234. distance and records its smallest value.  The "iteration @ min" colors
  235. by the iteration number when this minimum is reached, and the "angle @
  236. min" methods colors by the polar angle of z when the minimum was reached.
  237. The corresponding "maximum" methods ("maximum distance", "iteration @
  238. max", and "angle @ max") work in a similar fashion for the maximum value
  239. of z - round(z).  The final method, "average distance", simply colors by
  240. the mean of the distance over the course of the orbit.  Note that the
  241. angle used here is the actual polar angle, with a range of 360 degrees,
  242. instead of the angle returned by the built-in "atan" function, which
  243. only has a range of 180 degrees.
  244.  
  245. These methods essentially overlay a 1x1 square grid onto the complex
  246. plane and ask how close (or far) the orbit comes to a node in the grid.
  247. Two options allow varying the size of the grid; these are called the
  248. "normalization" methods.  The first is to normalize z by the #pixel.
  249. This has the effect of asking how close the orbit comes to Gaussian
  250. integer multiples of the #pixel value (or, z/#pixel = has integer real
  251. and imaginary parts).  The other normalization method employs a user-
  252. specified complex factor.  Then, the coloring is performed according to
  253. how close the orbit comes to Gaussian integer multiples of this factor.
  254. For example, if the factor was set to (1.2,5.1), then the methods would be
  255. coloring by the orbits approach to nodes of a rectangular grid that was
  256. 1.2 units long by 5.1 units high.  This might be useful with Julia set
  257. images, as the factor can be set to the Julia parameter.  The default,
  258. "none" normalization, uses a factor of 1.
  259. }
  260.  
  261.  
  262. gauss { // Kerry Mitchell 20sep1998, last updated 28apr2001
  263. //
  264. // Colors by orbit's relationship
  265. // to Gaussian Integers. See comment
  266. // block for more information.
  267. //
  268. // Updated 02apr99 to include options for finding
  269. // the integer:  added trunc, floor, and ceil.
  270. // Thanks to Marcelo Anelli for the idea.
  271. //
  272. // Updated 28apr2001 to include normalizing by some function of z.
  273. // Added to new 'color by' choices:  max/min ratio and
  274. // min/mean/max angle.  Added "randomize" feature to randomly 
  275. // change z before finding the Gaussian integer.  This will
  276. // change the regular grid-like distribution of points.
  277. //
  278. real r;
  279. real rmin;
  280. real rmax;
  281. real rave;
  282. real total;
  283. real t;
  284. int iter;
  285. int itermin;
  286. int itermax;
  287. complex zmin;
  288. complex zmax;
  289. parameter int norm;
  290. complex normfac;
  291. parameter complex fac;
  292. real logfac;
  293. parameter real logseed;
  294. complex temp2;
  295. parameter bool randomize;
  296. parameter complex randomsize;
  297. parameter int inttype;
  298. complex temp;
  299. complex remain;
  300. parameter int colorby;
  301.  
  302.     void init(void)
  303.     {
  304.         r=0.0;
  305.         rmin=1.0e12;
  306.         rmax=0.0;
  307.         rave=0.0;
  308.         total=0.0;
  309.         t=0.0;
  310.         iter=0;
  311.         itermin=0;
  312.         itermax=0;
  313.         zmin=(0.0,0.0);
  314.         zmax=(0.0,0.0);
  315.         if ((norm==1))
  316.         {// pixel normalization
  317.             normfac=pixel;
  318.         }
  319.         else if ((norm==2))
  320.         {// factor normalization
  321.             normfac=fac;
  322.         }
  323.         else if ((norm==3))
  324.         {// f(z) normalization
  325.             normfac=normfunc(z);
  326.         }
  327.         else
  328.         {
  329.                                // no normalization
  330.             normfac=(1.0,0.0);
  331.         }
  332.         logfac=logseed;
  333.     }
  334.     void loop(void)
  335.     {
  336.         iter=iter+1;
  337.         temp2=z;
  338.         if ((randomize==true))
  339.         {
  340.             logfac=4*logfac*(1-logfac);
  341.             temp2=temp2*(1-randomsize*logfac);
  342.         }
  343.         if ((inttype==1))
  344.         {// trunc
  345.             temp=trunc(temp2/normfac);
  346.         }
  347.         else if ((inttype==2))
  348.         {// floor
  349.             temp=floor(temp2/normfac);
  350.         }
  351.         else if ((inttype==3))
  352.         {// ceil
  353.             temp=ceil(temp2/normfac);
  354.         }
  355.         else
  356.         {
  357.                                // round
  358.             temp=round(temp2/normfac);
  359.         }
  360.         remain=temp2-temp*normfac;
  361.         r=cabs(remain);
  362.         total=total+r;
  363.         rave=total/iter;
  364.         if ((r<rmin))
  365.         {
  366.             rmin=r;
  367.             zmin=temp2;
  368.             itermin=iter;
  369.         }
  370.         if ((r>rmax))
  371.         {
  372.             rmax=r;
  373.             zmax=temp2;
  374.             itermax=iter;
  375.         }
  376.     }
  377.     void final(void)
  378.     {
  379.         if ((colorby==1))
  380.         {// iteration @ min
  381.             index=0.01*itermin;
  382.         }
  383.         else if ((colorby==2))
  384.         {// angle @ min
  385.             t=atan2(zmin);
  386.             t=t/pi;
  387.             if ((t<0.0))
  388.             {
  389.                 t=t+2.0;
  390.             }
  391.             index=0.5*t;
  392.         }
  393.         else if ((colorby==3))
  394.         {// maximum distance
  395.             index=rmax;
  396.         }
  397.         else if ((colorby==4))
  398.         {// iteration @ max
  399.             index=0.01*itermax;
  400.         }
  401.         else if ((colorby==5))
  402.         {// angle @ max
  403.             t=atan2(zmax);
  404.             t=t/pi;
  405.             if ((t<0.0))
  406.             {
  407.                 t=t+2.0;
  408.             }
  409.             index=0.5*t;
  410.         }
  411.         else if ((colorby==6))
  412.         {// average distance
  413.             index=rave;
  414.         }
  415.         else if ((colorby==7))
  416.         {// min/mean/max angle
  417.             zmax=(rave-rmin)+flip(rmax-rave);
  418.             t=atan2(zmax);
  419.             t=t/pi;
  420.             if ((t<0.0))
  421.             {
  422.                 t=t+2.0;
  423.             }
  424.             index=0.5*t;
  425.         }
  426.         else if ((colorby==8))
  427.         {// max/min ratio
  428.             index=rmax/(rmin+1.e-12);
  429.         }
  430.         else
  431.         {
  432.                        // minimum distance
  433.             index=rmin;
  434.         }
  435.     }
  436.     void description(void)
  437.     {
  438.         this.title="Gaussian Integer";
  439.    
  440.         inttype.caption="integer type";
  441.         inttype.default=0;
  442.         inttype.enum="round(z)\ntrunc(z)\nfloor(z)\nceil(z)";
  443.   
  444.    
  445.         colorby.caption="color by";
  446.         colorby.default=0;
  447.         colorby.enum="minimum distance\niteration @ min\nangle @ min\nmaximum distance\niteration @ max\nangle @ max\naverage distance\nmin/mean/max angle\nmax/min ratio";
  448.   
  449.    
  450.         norm.caption="normalization";
  451.         norm.default=0;
  452.         norm.enum="none\npixel\nfactor\nf(z)";
  453.   
  454.    
  455.         fac.caption="normalizing factor";
  456.         fac.default=(2.0,1.0);
  457.   
  458.    
  459.         randomize.caption="randomize?";
  460.         randomize.default=false;
  461.         randomize.hint="Applies a random factor to z every iteration before finding the Gaussian integer.";
  462.   
  463.    
  464.         randomsize.caption="random size";
  465.         randomsize.default=(0.1,0);
  466.         randomsize.hint="Size of random factor, if 'randomize?' is checked.";
  467.   
  468.    
  469.         logseed.caption="random seed";
  470.         logseed.default=0.1;
  471.         logseed.min=0.0;
  472.         logseed.max=1.0;
  473.         logseed.hint="Randomize seed, between 0 and 1.";
  474.   
  475.    
  476.         normfunc.caption="normalizing function";
  477.         normfunc.default="ident" ;
  478.         normfunc.hint="For 'f(z)' normalization.";
  479.   
  480.     }
  481. }
  482.  
  483.  
  484. comment { ; copyright Kerry Mitchell 04nov98
  485.  
  486. Statistics
  487.  
  488. This started out with an article written by Stephen Ferguson on an
  489. analysis of fractal dimension, which he based on an algorithm by Holger
  490. Jaenisch.  The formulas here modify Stephen's analysis and add other
  491. standard statistical measures.  Since the measures are typically used
  492. with bounded datasets, this coloring method may be more applicable as
  493. an "inside" scheme, but there's nothing stopping a user from employing
  494. it as an "outside" scheme as well.
  495.  
  496. The statistical measures implemented are:  minimum, maximum, range,
  497. mean, standard deviation, coefficient of variation, and fractal
  498. dimension.  All are defined only for real variables, so there are
  499. 4 choices for reducing the complex #z to a real number:  real(#z),
  500. imag(#z), the magnitude of #z, and imag(#z)/real(#z).  The last
  501. method is an attempt to capture the polar angle of #z, without the
  502. discontinuities involved in actually using the angle arg(#z).
  503.  
  504. Once the choice of variable has been made, the first 3 measures are
  505. simple enough to compute.  Simply monitor the orbit, updating the
  506. minimum and maximum as they change.  Once the iteration has ceased,
  507. the range is just (maximum - minimum).  The mean is computed by keeping
  508. a running sum of the variable, then dividing it by the number of
  509. iterations.
  510.  
  511. The standard deviation is a measure of the spread of the data, and is
  512. defined in terms of the sum of the squared differences between each
  513. datum and the mean.  This can also be computed by keeping a running
  514. sum of the square of the variable.  This sum is used with the sum for
  515. the mean to determine the standard deviation.  The coefficient of
  516. variation is a normalized standard deviation:  it's the ratio of the
  517. standard deviation to the mean.  Finally, the "fractal dimension"
  518. computed here is not the true fractal dimension, but an approximation
  519. to it.  It's the standard deviation normalized by the range.
  520.  
  521. }
  522.  
  523.  
  524. statistics { // Kerry Mitchell 03nov98
  525. //
  526. // Colors according to various
  527. // statistical properties of the
  528. // iterate.  Primarily an "inside"
  529. // coloring method.
  530. //
  531. int iter;
  532. real r;
  533. real rmin;
  534. real rmax;
  535. real sumsum;
  536. real sum;
  537. parameter int vartype;
  538. parameter int stattype;
  539.  
  540.     void init(void)
  541.     {
  542.         iter=0;
  543.         r=0.0;
  544.         rmin=1e12;
  545.         rmax=-rmin;
  546.         sumsum=0.0;
  547.         sum=0.0;
  548.     }
  549.     void loop(void)
  550.     {
  551.         iter=iter+1;
  552.         if ((vartype==0))
  553.         {// real(z)
  554.             r=real(z);
  555.         }
  556.         else if ((vartype==1))
  557.         {// imag(z)
  558.             r=imag(z);
  559.         }
  560.         else if ((vartype==2))
  561.         {// magnitude(z)
  562.             r=cabs(z);
  563.         }
  564.         else
  565.         {
  566.                           // imag(z)/real(z)
  567.             r=imag(z)/real(z);
  568.         }
  569.         sum=sum+r;
  570.         sumsum=sumsum+r*r;
  571.         if ((r<rmin))
  572.         {
  573.             rmin=r;
  574.         }
  575.         if ((r>rmax))
  576.         {
  577.             rmax=r;
  578.         }
  579.     }
  580.     void final(void)
  581.     {
  582.         if ((stattype==0))
  583.         {// minimum
  584.             index=rmin;
  585.         }
  586.         else if ((stattype==1))
  587.         {// maximum
  588.             index=rmax;
  589.         }
  590.         else if ((stattype==2))
  591.         {// range
  592.             index=rmax-rmin;
  593.         }
  594.         else if ((stattype==3))
  595.         {// mean
  596.             index=sum/iter;
  597.         }
  598.         else if ((stattype==4))
  599.         {// standard deviation
  600.             index=sqrt(sumsum-sum*sum/iter);
  601.         }
  602.         else if ((stattype==5))
  603.         {// coefficient of variation
  604.             index=sqrt(sumsum-sum*sum/iter)/sum*iter;
  605.         }
  606.         else
  607.         {
  608.                           // fractal dimension
  609.             index=sqrt(sumsum-sum*sum/iter)/(rmax-rmin);
  610.         }
  611.     }
  612.     void description(void)
  613.     {
  614.         this.title="Statistics";
  615.    
  616.         vartype.caption="variable";
  617.         vartype.default=2;
  618.         vartype.enum="real(z)\nimag(z)\nmagnitude\nimag/real";
  619.         vartype.hint="variable for which statistics will be calculated";
  620.   
  621.    
  622.         stattype.caption="statistic";
  623.         stattype.default=6;
  624.         stattype.enum="minimum\nmaximum\nrange\nmean\nstd. deviation\nvariation\nfractal dimension";
  625.         stattype.hint="statistic that will be calculated";
  626.   
  627.     }
  628. }
  629.  
  630.  
  631. comment { ; copyright Kerry Mitchell 15nov98
  632.  
  633. Polar Curves
  634.  
  635. Typically, points in a plane are thought of in terms of their x- and
  636. y-coordinates, that is, how far away (and on which side) the point is
  637. from the horizontal x-axis and the vertical y-axis.  Another way of
  638. looking at the point is with polar coordinates, which specify the
  639. distance of the point from the origin (r) and its direction (t).  The
  640. two methods are equivalent:
  641.  
  642. x = r*cos(t), y=r*sin(t), or
  643. r^2 = x^2 + y^2, tan(t) = y/x.
  644.  
  645. Polar curves are curves that specify r as a function of t, instead of
  646. y as a function of x.  The curve used in this coloring method is:
  647.  
  648. r = [a * f(b*t)]^n + r0,
  649.  
  650. where f is one of UltraFractal's builtin functions (e.g., sin, cos, exp,
  651. etc.), a is an amplitude scaling factor, and b is a frequency factor.
  652. The exponent n is useful for making the curve wider or thinner, and r0
  653. is a expansion or contraction constant.
  654.  
  655. Some special curves can be generated using this function.  Spirals can
  656. be made by using the "ident" function.  Here, the exponent n controls
  657. how tightly wound the spiral is.  However, only one revolution of the
  658. spiral will be drawn, as t is limited to the range 0 to 2*pi.
  659.  
  660. "Rose" curves are made by using either sin or cos functions.  The
  661. parameter a controls the size of the curve.  The number of "petals"
  662. is b, so long as b is a positive integer.  Increasing n from 1 will
  663. make the petals thinner; decreasing it toward 0 will make them thicker.
  664. Leave r0=0 for the standard rose curve, where the petals all join at
  665. the origin.
  666.  
  667. Since the sin and cos functions generate negative values, the "rose"
  668. curves will have some regions of negative r.  How this is handled
  669. depends on r0 and "negrflag", the negative r flag.  Setting negrflag to
  670. 1 will make the routine ignore negative r values.  This, with r0 is set
  671. to 0, will cause the rose curve to have "b" number of petals, all of
  672. them the same size.  Setting negrflag=2 will make the routine consider
  673. negative r's the same as positive r's.  Thus, the rose curve will have
  674. 2*b petals.  Increasing r0 from 0 will make r positive more often than
  675. negative.  This will also increase the number of petals from b to 2*b,
  676. but half of the petals will be small and half will be large.
  677.  
  678. The best way to see the effects of the parameter choices is to use the
  679. "draw curves" setting of the "color by" parameter.  Here, the image
  680. isn't a fractal, but rather the polar curve determined by a, b, n, r0,
  681. the chosen function, and the negative r flag.
  682.  
  683. The other "color by" settings use polar curves to color fractals.  There
  684. are 2 basic rendering methods:  how close the orbit comes to the polar
  685. curve, and how often the orbit is inside the polar curve.  The minimum
  686. approach method also has a few variants:  iteration number when the
  687. minimum was reached, and angle of #z when the minimum was reached.
  688.  
  689. }
  690.  
  691.  
  692. polar-curves { // Kerry Mitchell 15nov98
  693. //
  694. // colors by the relationship between
  695. // the orbit and a user-specified polar
  696. // curve (such as a spiral or a rose curve)
  697. //
  698. real err;
  699. real errmin;
  700. real r;
  701. real twopi;
  702. real t;
  703. int iter;
  704. int itermin;
  705. int incount;
  706. complex zmin;
  707. parameter real a;
  708. parameter real b;
  709. parameter real n;
  710. parameter real r0;
  711. parameter int rneg;
  712. parameter int colorby;
  713.  
  714.     void init(void)
  715.     {
  716.         err=0.0;
  717.         errmin=1.0e12;
  718.         r=0.0;
  719.         twopi=2.0*pi;
  720.         t=0.0;
  721.         iter=0;
  722.         itermin=0;
  723.         incount=0;
  724.         zmin=(0.0,0.0);
  725.     }
  726.     void loop(void)
  727.     {
  728.         iter=iter+1;
  729.         t=imag(log(z));
  730.         if ((t<0.0))
  731.         {
  732.             t=t+twopi;
  733.         }
  734.         r=a*real(fn1(b*t));
  735.         if ((r>=0.0))
  736.         {
  737.             r=r^n;
  738.         }
  739.         else
  740.         {
  741.  
  742.             r=-((-r)^n);
  743.         }
  744.         r=r+r0;
  745.         if ((rneg==0))
  746.         {
  747.             err=r-cabs(z);
  748.         }
  749.         else
  750.         {
  751.  
  752.             err=|r|-|z|;
  753.         }
  754.         if ((err<0.0))
  755.         {
  756.             incount=incount+1;
  757.             err=-err;
  758.         }
  759.         if ((err<errmin))
  760.         {
  761.             errmin=err;
  762.             zmin=z;
  763.             itermin=iter;
  764.         }
  765.     }
  766.     void final(void)
  767.     {
  768.         if ((colorby==0))
  769.         {// minimum distance
  770.             index=cabs(log(errmin));
  771.         }
  772.         else if ((colorby==1))
  773.         {// iteration @ min
  774.             index=0.01*itermin;
  775.         }
  776.         else if ((colorby==2))
  777.         {// angle @ min
  778.             t=atan2(zmin);
  779.             t=t/pi;
  780.             if ((t<0.0))
  781.             {
  782.                 t=t+2.0;
  783.             }
  784.             index=0.5*t;
  785.         }
  786.         else if ((colorby==3))
  787.         {// in fraction
  788.             index=incount/iter;
  789.         }
  790.         else
  791.         {
  792.                           // draw curves
  793.             t=imag(log(pixel));
  794.             if ((t<0.0))
  795.             {
  796.                 t=t+twopi;
  797.             }
  798.             r=a*real(fn1(b*t));
  799.             if ((r>=0.0))
  800.             {
  801.                 r=r^n;
  802.             }
  803.             else
  804.             {
  805.  
  806.                 r=-((-r)^n);
  807.             }
  808.             r=r+r0;
  809.             if ((rneg==0))
  810.             {
  811.                 err=r-cabs(pixel);
  812.             }
  813.             else
  814.             {
  815.  
  816.                 err=|r|-|pixel|;
  817.             }
  818.             index=cabs(log(cabs(err)));
  819.         }
  820.     }
  821.     void description(void)
  822.     {
  823.         this.title="Polar Curves";
  824.    
  825.         a.caption="amplitude";
  826.         a.default=1.0;
  827.   
  828.    
  829.         b.caption="frequency";
  830.         b.default=1.0;
  831.   
  832.    
  833.         n.caption="exponent";
  834.         n.default=1.0;
  835.   
  836.    
  837.         r0.caption="baseline r";
  838.         r0.default=0.0;
  839.   
  840.    
  841.         rneg.caption="r<0 flag";
  842.         rneg.default=0;
  843.         rneg.enum="ignore r<0\ntreat as r>0";
  844.         rneg.hint="1 to ignore negative r values, 2 to treat as positive";
  845.   
  846.    
  847.         colorby.caption="color by";
  848.         colorby.default=0;
  849.         colorby.enum="minimum distance\niteration @ min\nangle @ min\nin fraction\ndraw curves";
  850.   
  851.     }
  852. }
  853.  
  854.  
  855. comment { ; copyright Kerry Mitchell 15nov98
  856.  
  857. Astroid
  858.  
  859. The astroid is a figure from analytic geometry, resembling a four-
  860. pointed star with concave sides.  Its defining equation is:
  861.  
  862. x^(2/3) + y^(2/3) = a^(2/3)
  863.  
  864. where a determines the size of the figure, similar to the radius of
  865. a circle.  This equation can be generalized by changing the exponent
  866. of 2/3 to any value n.  If n is between 0 and 1, the figure resembles
  867. the standard astroid.  The sides go from being straight lines for n=1
  868. to lying atop of the coordinates axes as n approaches 0.  For n>1, the
  869. figure becomes convex, and is a circle for n=2.  As n approaches
  870. infinity, the figure approaches a square.  The astroid is further
  871. generalized by allowing it to be placed somewhere other than at the
  872. center of the complex plane.  The figure's orientation and location
  873. in the plane are determined by a "center" and "rotation angle" parameters.
  874.  
  875. This generalized astroid is the basis of this coloring scheme.  As with
  876. other plane figures, the astroid can be compared to the Mandelbrot and
  877. Julia orbits.  The image can be colored by how close the orbit comes
  878. to the astroid or how often the orbit lands inside the astroid.  A final
  879. choice of the "colorby" parameter draws the astroid only, so the effects
  880. of the parameter choices can be seen.
  881.  
  882. }
  883.  
  884.  
  885. astroid { // Kerry Mitchell 15nov98
  886. //
  887. // colors according to the relationship
  888. // between the orbit and an astroid
  889. // (4-pointed star figure)
  890. //
  891. real err;
  892. real errmin;
  893. real Var_x;
  894. real Var_y;
  895. real t;
  896. real aton;
  897. parameter real a;
  898. parameter real n;
  899. int iter;
  900. int itermin;
  901. int incount;
  902. complex zmin;
  903. parameter real rotangle;
  904. complex rot;
  905. complex temp;
  906. parameter complex Parm_center;
  907. parameter int colorby;
  908.  
  909.     void init(void)
  910.     {
  911.         err=0.0;
  912.         errmin=1.0e12;
  913.         Var_x=0.0;
  914.         Var_y=0.0;
  915.         t=0.0;
  916.         aton=a^n;
  917.         iter=0;
  918.         itermin=0;
  919.         incount=0;
  920.         zmin=(0.0,0.0);
  921.         t=rotangle/180.0*pi;
  922.         rot=exp(flip(t));
  923.     }
  924.     void loop(void)
  925.     {
  926.         iter=iter+1;
  927.         temp=rot*(z-Parm_center);
  928.         Var_x=cabs(real(temp));
  929.         Var_y=cabs(imag(temp));
  930.         err=Var_x^n+Var_y^n-aton;
  931.         if ((err<0.0))
  932.         {
  933.             incount=incount+1;
  934.             err=-err;
  935.         }
  936.         if ((err<errmin))
  937.         {
  938.             errmin=err;
  939.             zmin=z;
  940.             itermin=iter;
  941.         }
  942.     }
  943.     void final(void)
  944.     {
  945.         if ((colorby==0))
  946.         {// minimum distance
  947.             index=cabs(log(errmin));
  948.         }
  949.         else if ((colorby==1))
  950.         {// iteration @ min
  951.             index=0.01*itermin;
  952.         }
  953.         else if ((colorby==2))
  954.         {// angle @ min
  955.             t=atan2(zmin);
  956.             t=t/pi;
  957.             if ((t<0.0))
  958.             {
  959.                 t=t+2.0;
  960.             }
  961.             index=0.5*t;
  962.         }
  963.         else if ((colorby==3))
  964.         {// in fraction
  965.             index=incount/iter;
  966.         }
  967.         else
  968.         {
  969.                           // draw curve
  970.             temp=rot*(pixel-Parm_center);
  971.             Var_x=cabs(real(temp));
  972.             Var_y=cabs(imag(temp));
  973.             err=Var_x^n+Var_y^n-aton;
  974.             index=cabs(log(cabs(err)));
  975.         }
  976.     }
  977.     void description(void)
  978.     {
  979.         this.title="Astroid";
  980.    
  981.         a.caption="size";
  982.         a.default=1.0;
  983.   
  984.    
  985.         n.caption="exponent";
  986.         n.default=0.67;
  987.   
  988.    
  989.         rotangle.caption="rotation, degrees";
  990.         rotangle.default=0.0;
  991.   
  992.    
  993.         Parm_center.caption="center";
  994.         Parm_center.default=(0.0,0.0);
  995.   
  996.    
  997.         colorby.caption="color by";
  998.         colorby.default=0;
  999.         colorby.enum="minimum distance\niteration @ min\nangle @ min\nin fraction\ndraw curve";
  1000.   
  1001.     }
  1002. }
  1003.  
  1004.  
  1005. comment { ; narrative copyright Kerry Mitchell 25nov98
  1006.  
  1007. Seeing Stars
  1008.  
  1009. Most fractal images involve circles in some respect:  either stopping
  1010. the iteration when the orbit moves outside of a given circle, or
  1011. coloring by how close the orbit comes to a certain circle, or some
  1012. variation.  This formula uses a 5 point star instead of a circle.
  1013. The fractal can be colored by how close the orbit comes to a star, or
  1014. how often the orbit lands inside the star.
  1015.  
  1016. The star is represented by the 5 outer points.  These are equally spaced
  1017. on a circle.  The center and size of the circle are user-specified, as
  1018. is the rotation angle of the star.
  1019.  
  1020. How z at any iteration relates to the star (inside, outside, how close)
  1021. is determined by looking at each of the 10 sides, one at a time.  Each
  1022. side can be represented by a line A*x + B*y + C = 0, where A, B, and C
  1023. come from the coordinates of the 2 outer points that are joined to make
  1024. the side.  Given the numbers A, B, and C, the quantity
  1025.  
  1026.         q = A*real(z) + B*imag(z) + C
  1027.  
  1028. is computed.  If q is positive, then z is on one side of the line, and
  1029. if q is negative, then z is on the other side of the line.  If |q| is
  1030. very small, that means that z is very close to that side of the star.
  1031. Taking the signs of q for all 10 sides will determine if z is inside or
  1032. outside of the star.  Using the smallest value of |q| gives the distance
  1033. from z to the star.
  1034.  
  1035. To see this in action, use the "draw star" setting of the "color by"
  1036. parameter.  The outline of a star will be drawn, with the position,
  1037. orientation and size that you choose.  This setting along with the
  1038. "minimum distance" setting, uses a logarithmic transfer function from
  1039. distance to #index.  This helps highlight the star without needing to
  1040. find out if the point is exactly on the star or not.  The "in fraction"
  1041. will count how many times the orbit lands inside the star, then set
  1042. #index to the ratio of inside hits to total iterations for that pixel.
  1043.  
  1044. }
  1045.  
  1046.  
  1047. 5star { // Kerry Mitchell 25nov98
  1048. //
  1049. // colors by relationship to
  1050. // 5-point star
  1051. //
  1052. real err;
  1053. real errmin;
  1054. real Var_x;
  1055. real Var_y;
  1056. real xcen;
  1057. parameter complex Parm_center;
  1058. real ycen;
  1059. real phi;
  1060. parameter real phiangle;
  1061. real twopi;
  1062. real temp;
  1063. real t;
  1064. real t0;
  1065. real t1;
  1066. real t2;
  1067. real t3;
  1068. real t4;
  1069. real t5;
  1070. real t6;
  1071. real t7;
  1072. real t8;
  1073. real t9;
  1074. real x0;
  1075. parameter real r;
  1076. real y0;
  1077. real x1;
  1078. real y1;
  1079. real x2;
  1080. real y2;
  1081. real x3;
  1082. real y3;
  1083. real x4;
  1084. real y4;
  1085. int flag;
  1086. int incount;
  1087. int iter;
  1088. int itermin;
  1089. complex zmin;
  1090. parameter int colorby;
  1091.  
  1092.     void init(void)
  1093.     {
  1094.         err=0.0;
  1095.         errmin=1.0e20;
  1096.         Var_x=0.0;
  1097.         Var_y=0.0;
  1098.         xcen=real(Parm_center);
  1099.         ycen=imag(Parm_center);
  1100.         phi=phiangle/180.0*pi;
  1101.         twopi=2.0*pi;
  1102.         temp=0.1*twopi;
  1103.         t=0.0;
  1104.         t0=phi;
  1105.         t1=t0+temp;
  1106.         t2=t1+temp;
  1107.         t3=t2+temp;
  1108.         t4=t3+temp;
  1109.         t5=t4+temp;
  1110.         t6=t5+temp;
  1111.         t7=t6+temp;
  1112.         t8=t7+temp;
  1113.         t9=t8+temp;
  1114.         x0=r*cos(t0)+xcen;
  1115.         y0=r*sin(t0)+ycen;
  1116.         x1=r*cos(t2)+xcen;
  1117.         y1=r*sin(t2)+ycen;
  1118.         x2=r*cos(t4)+xcen;
  1119.         y2=r*sin(t4)+ycen;
  1120.         x3=r*cos(t6)+xcen;
  1121.         y3=r*sin(t6)+ycen;
  1122.         x4=r*cos(t8)+xcen;
  1123.         y4=r*sin(t8)+ycen;
  1124.         flag=0;
  1125.         incount=0;
  1126.         iter=0;
  1127.         itermin=0;
  1128.         zmin=(0.0,0.0);
  1129.     }
  1130.     void loop(void)
  1131.     {
  1132.         iter=iter+1;
  1133.         Var_x=real(z);
  1134.         Var_y=imag(z);
  1135.         t=imag(log(z-Parm_center));
  1136.         if ((t<0))
  1137.         {
  1138.             t=t+twopi;
  1139.         }
  1140.   //
  1141.   //  compute how close iterate is to each side of star
  1142.   //  and on which side
  1143.   //
  1144.         if (((t>t0)&&(t<=t1)))
  1145.         {
  1146.             err=Var_x*(y0-y2)+Var_y*(x2-x0)-x2*y0+x0*y2;
  1147.             if ((err<0))
  1148.             {
  1149.                 flag=1;
  1150.             }
  1151.         }
  1152.         else if (((t>t1)&&(t<=t2)))
  1153.         {
  1154.             err=Var_x*(y1-y4)+Var_y*(x4-x1)-x4*y1+x1*y4;
  1155.             if ((err<0))
  1156.             {
  1157.                 flag=1;
  1158.             }
  1159.         }
  1160.         else if (((t>t2)&&(t<=t3)))
  1161.         {
  1162.             err=Var_x*(y1-y3)+Var_y*(x3-x1)-x3*y1+x1*y3;
  1163.             if ((err<0))
  1164.             {
  1165.                 flag=1;
  1166.             }
  1167.         }
  1168.         else if (((t>t3)&&(t<=t4)))
  1169.         {
  1170.             err=Var_x*(y2-y0)+Var_y*(x0-x2)-x0*y2+x2*y0;
  1171.             if ((err<0))
  1172.             {
  1173.                 flag=1;
  1174.             }
  1175.         }
  1176.         else if (((t>t4)&&(t<=t5)))
  1177.         {
  1178.             err=Var_x*(y2-y4)+Var_y*(x4-x2)-x4*y2+x2*y4;
  1179.             if ((err<0))
  1180.             {
  1181.                 flag=1;
  1182.             }
  1183.         }
  1184.         else if (((t>t5)&&(t<=t6)))
  1185.         {
  1186.             err=Var_x*(y3-y1)+Var_y*(x1-x3)-x1*y3+x3*y1;
  1187.             if ((err<0))
  1188.             {
  1189.                 flag=1;
  1190.             }
  1191.         }
  1192.         else if (((t>t6)&&(t<=t7)))
  1193.         {
  1194.             err=Var_x*(y3-y0)+Var_y*(x0-x3)-x0*y3+x3*y0;
  1195.             if ((err<0))
  1196.             {
  1197.                 flag=1;
  1198.             }
  1199.         }
  1200.         else if (((t>t7)&&(t<=t8)))
  1201.         {
  1202.             err=Var_x*(y4-y2)+Var_y*(x2-x4)-x2*y4+x4*y2;
  1203.             if ((err<0))
  1204.             {
  1205.                 flag=1;
  1206.             }
  1207.         }
  1208.         else if (((t>t8)&&(t<=t9)))
  1209.         {
  1210.             err=Var_x*(y4-y1)+Var_y*(x1-x4)-x1*y4+x4*y1;
  1211.             if ((err<0))
  1212.             {
  1213.                 flag=1;
  1214.             }
  1215.         }
  1216.         else
  1217.         {
  1218.  
  1219.             err=Var_x*(y3-y0)+Var_y*(x0-x3)-x0*y3+x3*y0;
  1220.             if ((err<0))
  1221.             {
  1222.                 flag=1;
  1223.             }
  1224.         }
  1225.         err=cabs(err);
  1226.         if ((err<errmin))
  1227.         {
  1228.             errmin=err;
  1229.             itermin=iter;
  1230.             zmin=z;
  1231.         }
  1232.         if ((flag==1))
  1233.         {
  1234.             incount=incount+1;
  1235.         }
  1236.     }
  1237.     void final(void)
  1238.     {
  1239.         if ((colorby==0))
  1240.         {// minimum distance
  1241.             index=cabs(log(errmin));
  1242.         }
  1243.         else if ((colorby==1))
  1244.         {// iteration @ min
  1245.             index=0.01*itermin;
  1246.         }
  1247.         else if ((colorby==2))
  1248.         {// angle @ min
  1249.             t=atan2(zmin);
  1250.             t=t/pi;
  1251.             if ((t<0.0))
  1252.             {
  1253.                 t=t+2.0;
  1254.             }
  1255.             index=0.5*t;
  1256.         }
  1257.         else if ((colorby==3))
  1258.         {// in fraction
  1259.             index=incount/iter;
  1260.         }
  1261.         else
  1262.         {
  1263.                           // draw star
  1264.             Var_x=real(pixel);
  1265.             Var_y=imag(pixel);
  1266.             t=imag(log(pixel-Parm_center));
  1267.             if ((t<0))
  1268.             {
  1269.                 t=t+twopi;
  1270.             }
  1271.             if (((t>t0)&&(t<=t1)))
  1272.             {
  1273.                 err=Var_x*(y0-y2)+Var_y*(x2-x0)-x2*y0+x0*y2;
  1274.             }
  1275.             else if (((t>t1)&&(t<=t2)))
  1276.             {
  1277.                 err=Var_x*(y1-y4)+Var_y*(x4-x1)-x4*y1+x1*y4;
  1278.             }
  1279.             else if (((t>t2)&&(t<=t3)))
  1280.             {
  1281.                 err=Var_x*(y1-y3)+Var_y*(x3-x1)-x3*y1+x1*y3;
  1282.             }
  1283.             else if (((t>t3)&&(t<=t4)))
  1284.             {
  1285.                 err=Var_x*(y2-y0)+Var_y*(x0-x2)-x0*y2+x2*y0;
  1286.             }
  1287.             else if (((t>t4)&&(t<=t5)))
  1288.             {
  1289.                 err=Var_x*(y2-y4)+Var_y*(x4-x2)-x4*y2+x2*y4;
  1290.             }
  1291.             else if (((t>t5)&&(t<=t6)))
  1292.             {
  1293.                 err=Var_x*(y3-y1)+Var_y*(x1-x3)-x1*y3+x3*y1;
  1294.             }
  1295.             else if (((t>t6)&&(t<=t7)))
  1296.             {
  1297.                 err=Var_x*(y3-y0)+Var_y*(x0-x3)-x0*y3+x3*y0;
  1298.             }
  1299.             else if (((t>t7)&&(t<=t8)))
  1300.             {
  1301.                 err=Var_x*(y4-y2)+Var_y*(x2-x4)-x2*y4+x4*y2;
  1302.             }
  1303.             else if (((t>t8)&&(t<=t9)))
  1304.             {
  1305.                 err=Var_x*(y4-y1)+Var_y*(x1-x4)-x1*y4+x4*y1;
  1306.             }
  1307.             else
  1308.             {
  1309.  
  1310.                 err=Var_x*(y3-y0)+Var_y*(x0-x3)-x0*y3+x3*y0;
  1311.             }
  1312.             err=cabs(err);
  1313.             index=cabs(log(cabs(err)));
  1314.         }    
  1315.     }
  1316.     void description(void)
  1317.     {
  1318.         this.title="5 Point Star";
  1319.    
  1320.         Parm_center.caption="center of star";
  1321.         Parm_center.default=(0.0,0.0);
  1322.   
  1323.    
  1324.         r.caption="size of star";
  1325.         r.default=0.25;
  1326.         r.min=0.0;
  1327.   
  1328.    
  1329.         phiangle.caption="rotation, degrees";
  1330.         phiangle.default=0.0;
  1331.         phiangle.min=0.0;
  1332.         phiangle.max=36.0;
  1333.         phiangle.hint="only use angles between 0 and 36 degrees";
  1334.   
  1335.    
  1336.         colorby.caption="color by";
  1337.         colorby.default=0;
  1338.         colorby.enum="minimum distance\niteration @ min\nangle @ min\nin fraction\ndraw star";
  1339.   
  1340.     }
  1341. }
  1342.  
  1343.  
  1344. comment { ; copyright Kerry Mitchell 20dec98 
  1345.  
  1346. Conic Sections
  1347.  
  1348. Conic sections are sections of cones. Specifically, take a double-ended
  1349. cone, like 2 funnels placed tip-to-tip. Then, form the intersection of
  1350. the (double) cone with a plane. The intersection, usually one or two
  1351. curves, is a conic section. Conic sections can be a point, one line,
  1352. two lines, a parabola, an ellipse, a circle, or a hyperbola, depending
  1353. on the orientation of the plane relative to the cone. Analytically, they
  1354. can all be expressed by the same formula:
  1355.  
  1356.         Ax^2 + Bx + Cy^2 + Dy + Exy + F = 0,
  1357.  
  1358. where the parameters A through F determine the shape of the section, and
  1359. x and y are the 2 spatial coordinates. For example, the line y=x can be
  1360. represented as
  1361.  
  1362.         x - y = 0, or
  1363.         A = 0, B = 1, C = 0, D = -1, E = 0, F = 0. 
  1364.  
  1365. A circle centered at (1,0) with a radius of 2 would have the equation 
  1366.  
  1367.         (x - 1)^2 + y^2 = 4, or
  1368.         x^2 - 2x + y^2 - 3 = 0, giving
  1369.         A = 1, B = -2, C = 1, D = 0, E = 0, F = -3. 
  1370.  
  1371. How can these shapes be used to render fractals?  Firstly, the "draw
  1372. section" setting simply draws the section determined by the six parameters
  1373. A - F, to give the user an idea of how the parameter choices affect the
  1374. section generated.
  1375.  
  1376. These coloring formulas record how the orbit interacts with the given
  1377. section.  In "Conic Sections", all six section parameters are input to
  1378. determine the curve.  Then, the image can be colored according to the
  1379. distance of the orbit's approach to the section or how often the orbit
  1380. landed inside the section.  Here's how the "colorby" parameters work in
  1381. "Conic Sections":
  1382.  
  1383.         "minimum distance":  closest approach to section
  1384.         "iteration @ min":  iteration number at minimum approach
  1385.         "angle @ min":  polar angle of z at minimum approach
  1386.         "maximum distance":  furthest approach from section
  1387.         "iteration @ max":  iteration number at maximum approach
  1388.         "angle @ max":  polar angle of z at maximum approach
  1389.         "in fraction":  how many times orbit was inside section, as a
  1390. fraction of the total number of iterations
  1391.         "in/out ratio": ration of number of times orbit was inside the
  1392. section to the number of times the orbit was outside of the section
  1393.         "lsb binary":  builds up a binary index, adding a bit to the
  1394. right for each iteration, "1" if the orbit was inside the section
  1395. and "0" if it was outside
  1396.         "msb binary":  builds up a binary index, adding a bit to the
  1397. left for each iteration, "1" if the orbit was inside the section
  1398. and "0" if it was outside
  1399.         "draw section":  simply draws the chosen conic section
  1400.  
  1401. While using all six section parameters is very powerful, it is less
  1402. than user-friendly.  Hence "Conic Lite".  Here, the user chooses the
  1403. type of section, and only enters the relevant geometric characteristics.
  1404. The choices are:
  1405.  
  1406.         "line":  enter angle of line to horizontal, and point through
  1407. which line passes
  1408.         "circle":  enter center and radius
  1409.         "ellipse"  enter semi-major and semi-minor axes and center
  1410.         "horiz. hyperbola":  enter semi-major and semi-minor axes and
  1411. center
  1412.         "vert. hyperbola":  enter semi-major and semi-minor axes and
  1413. center
  1414.  
  1415. The coloring options have also been reduced, to:
  1416.  
  1417.         "minimum distance":  closest approach to section
  1418.         "iteration @ min":  iteration number at minimum approach
  1419.         "angle @ min":  polar angle of z at minimum approach
  1420.         "draw section":  simply draws the chosen conic section
  1421.  
  1422. The "2 Sections" coloring method combines the results from 2 conic
  1423. sections into one.  The choices of sections are the same as in "Conic
  1424. Lite".  At each iteration, the distance from the first curve (call it
  1425. x) and the distance from the second curve (call it y) are computed.
  1426. From these, an overall distance metric is determined:
  1427.  
  1428.         "x^2 + y^2":  standard magnitude
  1429.         "|x| + |y|":  manhattan metric
  1430.         "|x*y|":  hyperbolic
  1431.         "|x-y|":  umm, call it "|x-y|"
  1432.  
  1433. When the chosen metric is at its smallest value, the x and y values
  1434. are combined into a complex number, zerrmin.  Also, the iterate z is
  1435. stored as zmin.
  1436.  
  1437. The coloring options ("color by" parameter) are:
  1438.  
  1439.         "2 curve min":  magnitude of zerrmin
  1440.         "2 curve angle":  polar angle of zerrmin
  1441.         "z angle @ min":  polar angle of zmin
  1442.         "z mag @ min":  magnitude of zmin
  1443.         "iteration # @ min":  iteration number at metric minimum
  1444.         "draw section":  simply draws the 2 sections
  1445.  
  1446. The standard forms of the conic sections are given below. With a bit of
  1447. algebraic twiddling, they can be transformed into the general form, for
  1448. use in the coloring formulas.
  1449.  
  1450. point (h,k) x=h, y=k; or (x-h)^2 + (y-k)^2 = 0 [circle of radius 0
  1451. centered at (h,k)].
  1452.  
  1453. vertical line through (h,k): x=h
  1454.  
  1455. non-vertical line with slope m, through (h,k): y-k = m*(x-h) 
  1456.  
  1457. parabola, opening up or down, with vertex at (h,k): y-k = 4*p*(x-h)^2
  1458. [p determines width; +/up, -/down]
  1459.  
  1460. parabola, opening left or right, with vertex at (h,k): x-h = 4*p*(y-k)^2
  1461. [p determines width; +/right, -/left]
  1462.  
  1463. ellipse centered at (h,k), semimajor axis alpha, semiminor axis beta:
  1464. (x-h)^2/alpha^2 + (y-k)^2/beta^2 = 1
  1465.  
  1466. circle centered at (h,k), with radius r: (x-h)^2 + (y-k)^2 = r^2
  1467.  
  1468. hyperbola centered at (h,k), semimajor axis alpha, semiminor axis beta,
  1469. opening left/right: (x-h)^2/alpha^2 - (y-k)^2/beta^2 = 1
  1470.  
  1471. hyperbola centered at (h,k), semimajor axis alpha, semiminor axis beta,
  1472. opening up/down: (y-k)^2/beta^2 - (x-h)^2/alpha^2 = 1
  1473.  
  1474. coordinate rotation, from (u,v) to (x,y), through an angle theta:
  1475. u = x*cos(theta) + y*sin(theta)
  1476. v = -x*sin(theta) + y*cos(theta)
  1477. [rotating sections is how to generate non-zero E parameters]
  1478.  
  1479. }
  1480.  
  1481.  
  1482. conic-sections { // Kerry Mitchell 20dec98
  1483. //
  1484. // colors by relationship between orbit
  1485. // and fully-specified conic section
  1486. //
  1487. real cerr;
  1488. real cerrmin;
  1489. real cerrmax;
  1490. real Var_x;
  1491. real Var_y;
  1492. real err;
  1493. real t;
  1494. real total;
  1495. real lilbit;
  1496. real lilbase;
  1497. real bigbit;
  1498. real bigbase;
  1499. real bit;
  1500. int iter;
  1501. int incount;
  1502. int itermin;
  1503. int itermax;
  1504. complex zmin;
  1505. complex zmax;
  1506. parameter real aa;
  1507. parameter real bb;
  1508. parameter real cc;
  1509. parameter real dd;
  1510. parameter real ee;
  1511. parameter real ff;
  1512. parameter int colorby;
  1513.  
  1514.     void init(void)
  1515.     {
  1516.         cerr=0.0;
  1517.         cerrmin=1.0e12;
  1518.         cerrmax=0.0;
  1519.         Var_x=0.0;
  1520.         Var_y=0.0;
  1521.         err=0.0;
  1522.         t=0.0;
  1523.         total=0.0;
  1524.         lilbit=0.0;
  1525.         lilbase=0.5;
  1526.         bigbit=0.0;
  1527.         bigbase=1.0;
  1528.         bit=0.0;
  1529.         iter=0;
  1530.         incount=0;
  1531.         itermin=0;
  1532.         itermax=0;
  1533.         zmin=(0.0,0.0);
  1534.         zmax=(0.0,0.0);
  1535.     }
  1536.     void loop(void)
  1537.     {
  1538.         iter=iter+1;
  1539.         Var_x=real(z);
  1540.         Var_y=imag(z);
  1541.         err=(aa*Var_x+bb)*Var_x+(cc*Var_y+dd)*Var_y+ee*Var_x*Var_y+ff;
  1542.         bit=0.0;
  1543.         if ((err<0.0))
  1544.         {
  1545.             incount=incount+1;
  1546.             bit=1.0;
  1547.         }
  1548.         lilbit=lilbit+bit*lilbase;
  1549.         lilbase=lilbase*0.5;
  1550.         bigbit=bigbit+bit*bigbase;
  1551.         bigbase=bigbase*2.0;
  1552.         cerr=cabs(err);
  1553.         if ((cerr<cerrmin))
  1554.         {
  1555.             cerrmin=cerr;
  1556.             zmin=z;
  1557.             itermin=iter;
  1558.         }
  1559.         if ((cerr>cerrmax))
  1560.         {
  1561.             cerrmax=cerr;
  1562.             zmax=z;
  1563.             itermax=iter;
  1564.         }
  1565.         total=total+cerr;
  1566.     }
  1567.     void final(void)
  1568.     {
  1569.         if ((colorby==0))
  1570.         {// minimum distance
  1571.             index=0.5*cabs(log(cerrmin));
  1572.         }
  1573.         else if ((colorby==1))
  1574.         {// iteration @ min
  1575.             index=0.01*itermin;
  1576.         }
  1577.         else if ((colorby==2))
  1578.         {// angle @ min
  1579.             t=atan2(zmin)/pi;
  1580.             if ((t<0.0))
  1581.             {
  1582.                 t=t+2.0;
  1583.             }
  1584.             index=0.5*t;
  1585.         }
  1586.         else if ((colorby==3))
  1587.         {// maximum distance
  1588.             index=cerrmax;
  1589.         }
  1590.         else if ((colorby==4))
  1591.         {// iteration @ max
  1592.             index=0.01*itermax;
  1593.         }
  1594.         else if ((colorby==5))
  1595.         {// angle @ max
  1596.             t=atan2(zmax)/pi;
  1597.             if ((t<0.0))
  1598.             {
  1599.                 t=t+2.0;
  1600.             }
  1601.             index=0.5*t;
  1602.         }
  1603.         else if ((colorby==6))
  1604.         {// in fraction
  1605.             index=incount/iter;
  1606.         }
  1607.         else if ((colorby==7))
  1608.         {// in/out ratio
  1609.             index=incount/(iter-incount);
  1610.         }
  1611.         else if ((colorby==8))
  1612.         {// lsb binary
  1613.             index=lilbit;
  1614.         }
  1615.         else if ((colorby==9))
  1616.         {// msb binary
  1617.             index=0.5*bigbit/bigbase;
  1618.         }
  1619.         else
  1620.         {
  1621.                           // draw section
  1622.             Var_x=real(pixel);
  1623.             Var_y=imag(pixel);
  1624.             err=(aa*Var_x+bb)*Var_x+(cc*Var_y+dd)*Var_y+ee*Var_x*Var_y+ff;
  1625.             index=0.5*cabs(log(cabs(err)));
  1626.         }
  1627.     }
  1628.     void description(void)
  1629.     {
  1630.         this.title="Conic Sections";
  1631.    
  1632.         aa.caption="a";
  1633.         aa.default=0.0;
  1634.         aa.hint="coefficient of x^2 in conic section equation";
  1635.   
  1636.    
  1637.         bb.caption="b";
  1638.         bb.default=1.0;
  1639.         bb.hint="coefficient of x in conic section equation";
  1640.   
  1641.    
  1642.         cc.caption="c";
  1643.         cc.default=0.0;
  1644.         cc.hint="coefficient of y^2 in conic section equation";
  1645.   
  1646.    
  1647.         dd.caption="d";
  1648.         dd.default=-1.0;
  1649.         dd.hint="coefficient of y in conic section equation";
  1650.   
  1651.    
  1652.         ee.caption="e";
  1653.         ee.default=0.0;
  1654.         ee.hint="coefficient of x*y in conic section equation";
  1655.   
  1656.    
  1657.         ff.caption="f";
  1658.         ff.default=0.0;
  1659.         ff.hint="constant term in conic section equation";
  1660.   
  1661.    
  1662.         colorby.caption="color by";
  1663.         colorby.default=0;
  1664.         colorby.enum="minimum distance\niteration @ min\nangle @ min\nmaximum distance\niteration @ max\nangle @ max\nin fraction\nin/out ratio\nlsb binary\nmsb binary\ndraw section";
  1665.         colorby.hint="see lkm-pub.ucl for explanations";
  1666.   
  1667.     }
  1668. }
  1669.  
  1670.  
  1671. conic-lite { // Kerry Mitchell 20dec98
  1672. //
  1673. // colors by relationship between orbit
  1674. // and conic section.  tastes great, less
  1675. // choices, less filling, easier to use.
  1676. //
  1677. real cerr;
  1678. real cerrmin;
  1679. real Var_x;
  1680. real Var_y;
  1681. real t;
  1682. int iter;
  1683. int itermin;
  1684. real h;
  1685. parameter complex Parm_center;
  1686. real k;
  1687. real aa;
  1688. real bb;
  1689. real cc;
  1690. real dd;
  1691. real ff;
  1692. real a2;
  1693. real b2;
  1694. complex zmin;
  1695. parameter int type;
  1696. parameter real radius;
  1697. parameter real xaxis;
  1698. parameter real yaxis;
  1699. parameter real theta;
  1700. parameter int colorby;
  1701. complex err;
  1702.  
  1703.     void init(void)
  1704.     {
  1705.         cerr=0.0;
  1706.         cerrmin=1.0e12;
  1707.         Var_x=0.0;
  1708.         Var_y=0.0;
  1709.         t=0.0;
  1710.         iter=0;
  1711.         itermin=0;
  1712.         h=real(Parm_center);
  1713.         k=imag(Parm_center);
  1714.         aa=0.0;
  1715.         bb=0.0;
  1716.         cc=0.0;
  1717.         dd=0.0;
  1718.         ff=0.0;
  1719.         a2=0.0;
  1720.         b2=0.0;
  1721.         zmin=(0.0,0.0);
  1722. //
  1723. // set up constants depending on chosen type of section
  1724. //
  1725.         if ((type==1))
  1726.         {// circle
  1727.             aa=1.0;
  1728.             bb=-2.0*h;
  1729.             cc=1.0;
  1730.             dd=-2.0*k;
  1731.             ff=sqr(h)+sqr(k)-sqr(radius);
  1732.         }
  1733.         else if ((type==2))
  1734.         {// ellipse
  1735.             a2=sqr(xaxis);
  1736.             b2=sqr(yaxis);
  1737.             aa=b2;
  1738.             bb=-2.0*h*b2;
  1739.             cc=a2;
  1740.             dd=-2.0*k*a2;
  1741.             ff=b2*sqr(h)+a2*sqr(k)-a2*b2;
  1742.         }
  1743.         else if ((type==3))
  1744.         {// horizontal hyperbola
  1745.             a2=sqr(xaxis);
  1746.             b2=sqr(yaxis);
  1747.             aa=b2;
  1748.             bb=-2.0*h*b2;
  1749.             cc=-a2;
  1750.             dd=2.0*k*a2;
  1751.             ff=b2*sqr(h)-a2*sqr(k)-a2*b2;
  1752.         }
  1753.         else if ((type==4))
  1754.         {// vertical hyperbola
  1755.             a2=sqr(xaxis);
  1756.             b2=sqr(yaxis);
  1757.             aa=-b2;
  1758.             bb=2.0*h*b2;
  1759.             cc=a2;
  1760.             dd=-2.0*k*a2;
  1761.             ff=-b2*sqr(h)+a2*sqr(k)-a2*b2;
  1762.         }
  1763.         else
  1764.         {
  1765.                           // line
  1766.             t=theta/180*pi;
  1767.             aa=0.0;
  1768.             bb=sin(t);
  1769.             cc=0.0;
  1770.             dd=-cos(t);
  1771.             ff=-(bb*h+dd*k);
  1772.         }
  1773.     }
  1774.     void loop(void)
  1775.     {
  1776.         iter=iter+1;
  1777.         Var_x=real(z);
  1778.         Var_y=imag(z);
  1779.         cerr=cabs((aa*Var_x+bb)*Var_x+(cc*Var_y+dd)*Var_y+ff);
  1780.         if ((cerr<cerrmin))
  1781.         {
  1782.             cerrmin=cerr;
  1783.             zmin=z;
  1784.             itermin=iter;
  1785.         }
  1786.     }
  1787.     void final(void)
  1788.     {
  1789.         if ((colorby==0))
  1790.         {// minimum distance
  1791.             index=0.5*cabs(log(cerrmin));
  1792.         }
  1793.         else if ((colorby==1))
  1794.         {// iteration @ min
  1795.             index=0.01*itermin;
  1796.         }
  1797.         else if ((colorby==2))
  1798.         {// angle @ min
  1799.             t=atan2(zmin)/pi;
  1800.             if ((t<0.0))
  1801.             {
  1802.                 t=t+2.0;
  1803.             }
  1804.             index=0.5*t;
  1805.         }
  1806.         else
  1807.         {
  1808.                           // draw section
  1809.             Var_x=real(pixel);
  1810.             Var_y=imag(pixel);
  1811.             err=(aa*Var_x+bb)*Var_x+(cc*Var_y+dd)*Var_y+ff;
  1812.             index=0.5*cabs(log(cabs(err)));
  1813.         }
  1814.     }
  1815.     void description(void)
  1816.     {
  1817.         this.title="Conic Lite";
  1818.    
  1819.         type.caption="section type";
  1820.         type.default=1;
  1821.         type.enum="line\ncircle\nellipse\nhoriz. hyperbola\nvert. hyperbola";
  1822.   
  1823.    
  1824.         Parm_center.caption="center";
  1825.         Parm_center.default=(0.0,0.0);
  1826.   
  1827.    
  1828.         theta.caption="angle of line";
  1829.         theta.default=45.0;
  1830.         theta.hint="angle to horizontal, degrees";
  1831.   
  1832.    
  1833.         radius.caption="radius";
  1834.         radius.default=1.0;
  1835.         radius.min=0.0;
  1836.   
  1837.    
  1838.         xaxis.caption="x axis";
  1839.         xaxis.default=1.5;
  1840.         xaxis.min=0.0;
  1841.         xaxis.hint="for ellipses and hyperbolas";
  1842.   
  1843.    
  1844.         yaxis.caption="y axis";
  1845.         yaxis.default=0.75;
  1846.         yaxis.min=0.0;
  1847.         yaxis.hint="for ellipses and hyperbolas";
  1848.   
  1849.    
  1850.         colorby.caption="color by";
  1851.         colorby.default=0;
  1852.         colorby.enum="minimum distance\niteration @ min\nangle @ min\ndraw section";
  1853.   
  1854.     }
  1855. }
  1856.  
  1857.  
  1858. 2-sections { // Kerry Mitchell 20dec98
  1859. //
  1860. // colors by the relationship between
  1861. // the orbit and 2 conic sections
  1862. //
  1863. real Var_x;
  1864. real Var_y;
  1865. real t;
  1866. real err1;
  1867. real err2;
  1868. real cerr;
  1869. real cerrmin;
  1870. int iter;
  1871. int itermin;
  1872. real h1;
  1873. parameter complex center1;
  1874. real k1;
  1875. real a1;
  1876. real b1;
  1877. real c1;
  1878. real d1;
  1879. real f1;
  1880. real h2;
  1881. parameter complex center2;
  1882. real k2;
  1883. real a2;
  1884. real b2;
  1885. real c2;
  1886. real d2;
  1887. real f2;
  1888. real tempa;
  1889. real tempb;
  1890. complex zmin;
  1891. complex zerrmin;
  1892. complex temperr;
  1893. parameter int type1;
  1894. parameter real radius1;
  1895. parameter real xaxis1;
  1896. parameter real yaxis1;
  1897. parameter real theta1;
  1898. parameter int type2;
  1899. parameter real radius2;
  1900. parameter real xaxis2;
  1901. parameter real yaxis2;
  1902. parameter real theta2;
  1903. parameter int metrictype;
  1904. parameter int colorby;
  1905.  
  1906.     void init(void)
  1907.     {
  1908.         Var_x=0.0;
  1909.         Var_y=0.0;
  1910.         t=0.0;
  1911.         err1=0.0;
  1912.         err2=0.0;
  1913.         cerr=0.0;
  1914.         cerrmin=1.0e12;
  1915.         iter=0;
  1916.         itermin=0;
  1917.         h1=real(center1);
  1918.         k1=imag(center1);
  1919.         a1=0.0;
  1920.         b1=0.0;
  1921.         c1=0.0;
  1922.         d1=0.0;
  1923.         f1=0.0;
  1924.         h2=real(center2);
  1925.         k2=imag(center2);
  1926.         a2=0.0;
  1927.         b2=0.0;
  1928.         c2=0.0;
  1929.         d2=0.0;
  1930.         f2=0.0;
  1931.         tempa=0.0;
  1932.         tempb=0.0;
  1933.         zmin=(0.0,0.0);
  1934.         zerrmin=(0.0,0.0);
  1935.         temperr=(0.0,0.0);
  1936. //
  1937. // conic section parameters for first curve
  1938. //
  1939.         if ((type1==1))
  1940.         {// circle
  1941.             a1=1.0;
  1942.             b1=-2.0*h1;
  1943.             c1=1.0;
  1944.             d1=-2.0*k1;
  1945.             f1=sqr(h1)+sqr(k1)-sqr(radius1);
  1946.         }
  1947.         else if ((type1==2))
  1948.         {// ellipse
  1949.             tempa=sqr(xaxis1);
  1950.             tempb=sqr(yaxis1);
  1951.             a1=tempb;
  1952.             b1=-2.0*h1*tempb;
  1953.             c1=tempa;
  1954.             d1=-2.0*k1*tempa;
  1955.             f1=tempb*sqr(h1)+tempa*sqr(k1)-tempa*tempb;
  1956.         }
  1957.         else if ((type1==3))
  1958.         {// horizontal hyperbola
  1959.             tempa=sqr(xaxis1);
  1960.             tempb=sqr(yaxis1);
  1961.             a1=tempb;
  1962.             b1=-2.0*h1*tempb;
  1963.             c1=-tempa;
  1964.             d1=2.0*k1*tempa;
  1965.             f1=tempb*sqr(h1)-tempa*sqr(k1)-tempa*tempb;
  1966.         }
  1967.         else if ((type1==4))
  1968.         {// vertical hyperbola
  1969.             tempa=sqr(xaxis1);
  1970.             tempb=sqr(yaxis1);
  1971.             a1=-tempb;
  1972.             b1=2.0*h1*tempb;
  1973.             c1=tempa;
  1974.             d1=-2.0*k1*tempa;
  1975.             f1=-tempb*sqr(h1)+tempa*sqr(k1)-tempa*tempb;
  1976.         }
  1977.         else
  1978.         {
  1979.                            // line
  1980.             t=theta1/180*pi;
  1981.             a1=0.0;
  1982.             b1=sin(t);
  1983.             c1=0.0;
  1984.             d1=-cos(t);
  1985.             f1=-(b1*h1+d1*k1);
  1986.         }
  1987. //
  1988. // conic section parameters for second curve
  1989. //
  1990.         if ((type2==1))
  1991.         {// circle
  1992.             a2=1.0;
  1993.             b2=-2.0*h2;
  1994.             c2=1.0;
  1995.             d2=-2.0*k2;
  1996.             f2=sqr(h2)+sqr(k2)-sqr(radius2);
  1997.         }
  1998.         else if ((type2==2))
  1999.         {// ellipse
  2000.             tempa=sqr(xaxis2);
  2001.             tempb=sqr(yaxis2);
  2002.             a2=tempb;
  2003.             b2=-2.0*h2*tempb;
  2004.             c2=tempa;
  2005.             d2=-2.0*k2*tempa;
  2006.             f2=tempb*sqr(h2)+tempa*sqr(k2)-tempa*tempb;
  2007.         }
  2008.         else if ((type2==3))
  2009.         {// horizontal hyperbola
  2010.             tempa=sqr(xaxis2);
  2011.             tempb=sqr(yaxis2);
  2012.             a2=tempb;
  2013.             b2=-2.0*h2*tempb;
  2014.             c2=-tempa;
  2015.             d2=2.0*k2*tempa;
  2016.             f2=tempb*sqr(h2)-tempa*sqr(k2)-tempa*tempb;
  2017.         }
  2018.         else if ((type2==4))
  2019.         {// vertical hyperbola
  2020.             tempa=sqr(xaxis2);
  2021.             tempb=sqr(yaxis2);
  2022.             a2=-tempb;
  2023.             b2=2.0*h2*tempb;
  2024.             c2=tempa;
  2025.             d2=-2.0*k2*tempa;
  2026.             f2=-tempb*sqr(h2)+tempa*sqr(k2)-tempa*tempb;
  2027.         }
  2028.         else
  2029.         {
  2030.                            // line
  2031.             t=theta2/180*pi;
  2032.             a2=0.0;
  2033.             b2=sin(t);
  2034.             c2=0.0;
  2035.             d2=-cos(t);
  2036.             f2=-(b2*h2+d2*k2);
  2037.         }
  2038.     }
  2039.     void loop(void)
  2040.     {
  2041.         iter=iter+1;
  2042. //
  2043. // see how far iterate is from curves
  2044. //
  2045.         Var_x=real(z);
  2046.         Var_y=imag(z);
  2047.         err1=(a1*Var_x+b1)*Var_x+(c1*Var_y+d1)*Var_y+f1;
  2048.         err2=(a2*Var_x+b2)*Var_x+(c2*Var_y+d2)*Var_y+f2;
  2049.         temperr=err1+flip(err2);
  2050. //
  2051. // create distance metric and compare to current minimum
  2052. //
  2053.         if ((metrictype==0))
  2054.         {// magnitude
  2055.             cerr=cabs(temperr);
  2056.         }
  2057.         else if ((metrictype==1))
  2058.         {// manhattan metric
  2059.             cerr=cabs(err1)+cabs(err2);
  2060.         }
  2061.         else if ((metrictype==2))
  2062.         {// hyperbolic
  2063.             cerr=cabs(err1*err2);
  2064.         }
  2065.         else
  2066.         {
  2067.                           // |x-y|
  2068.             cerr=cabs(err1-err2);
  2069.         }  
  2070.         if ((cerr<cerrmin))
  2071.         {
  2072.             cerrmin=cerr;
  2073.             itermin=iter;
  2074.             zmin=z;
  2075.             zerrmin=temperr;
  2076.         }
  2077.     }
  2078.     void final(void)
  2079.     {
  2080. //
  2081. // set index according to colorby parameter
  2082. //
  2083.         if ((colorby==0))
  2084.         {// minimum magnitude
  2085.             index=0.5*cabs(log(cerrmin));
  2086.         }
  2087.         else if ((colorby==1))
  2088.         {// angle @ min
  2089.             t=atan2(zerrmin)/pi;
  2090.             if ((t<0.0))
  2091.             {
  2092.                 t=t+2.0;
  2093.             }
  2094.             index=0.5*t;
  2095.         }
  2096.         else if ((colorby==2))
  2097.         {// z angle @ min
  2098.             t=atan2(zmin)/pi;
  2099.             if ((t<0.0))
  2100.             {
  2101.                 t=t+2.0;
  2102.             }
  2103.             index=0.5*t;
  2104.         }
  2105.         else if ((colorby==3))
  2106.         {// z mag @ min
  2107.             index=cabs(zmin);
  2108.         }
  2109.         else if ((colorby==4))
  2110.         {// iteration # @ min
  2111.             index=0.01*itermin;
  2112.         }
  2113.         else
  2114.         {
  2115.                            // draw sections
  2116.             Var_x=real(pixel);
  2117.             Var_y=imag(pixel);
  2118.             err1=cabs((a1*Var_x+b1)*Var_x+(c1*Var_y+d1)*Var_y+f1);
  2119.             err2=cabs((a2*Var_x+b2)*Var_x+(c2*Var_y+d2)*Var_y+f2);
  2120.             if ((err1<err2))
  2121.             {
  2122.                 cerr=err1;
  2123.             }
  2124.             else
  2125.             {
  2126.  
  2127.                 cerr=err2;
  2128.             }
  2129.             index=0.5*cabs(log(cerr));
  2130.         }
  2131.     }
  2132.     void description(void)
  2133.     {
  2134.         this.title="2 Sections";
  2135.    
  2136.         type1.caption="section 1 type";
  2137.         type1.default=0;
  2138.         type1.enum="line\ncircle\nellipse\nhoriz. hyperbola\nvert. hyperbola";
  2139.   
  2140.    
  2141.         center1.caption="section 1 center";
  2142.         center1.default=(0.0,0.0);
  2143.   
  2144.    
  2145.         theta1.caption="section 1 angle";
  2146.         theta1.default=45.0;
  2147.         theta1.hint="angle of line to horizontal, degrees";
  2148.   
  2149.    
  2150.         radius1.caption="section 1 radius";
  2151.         radius1.default=1.0;
  2152.         radius1.min=0.0;
  2153.   
  2154.    
  2155.         xaxis1.caption="section 1 x axis";
  2156.         xaxis1.default=1.0;
  2157.         xaxis1.min=0.0;
  2158.         xaxis1.hint="for ellipses and hyperbolas";
  2159.   
  2160.    
  2161.         yaxis1.caption="section 1 y axis";
  2162.         yaxis1.default=1.0;
  2163.         yaxis1.min=0.0;
  2164.         yaxis1.hint="for ellipses and hyperbolas";
  2165.   
  2166.    
  2167.         type2.caption="section 2 type";
  2168.         type2.default=1;
  2169.         type2.enum="line\ncircle\nellipse\nhoriz. hyperbola\nvert. hyperbola";
  2170.   
  2171.    
  2172.         center2.caption="section 2 center";
  2173.         center2.default=(0.0,0.0);
  2174.   
  2175.    
  2176.         theta2.caption="section 2 angle";
  2177.         theta2.default=0.0;
  2178.         theta2.hint="angle of line to horizontal, degrees";
  2179.   
  2180.    
  2181.         radius2.caption="section 2 radius";
  2182.         radius2.default=1.0;
  2183.         radius2.min=0.0;
  2184.   
  2185.    
  2186.         xaxis2.caption="section 2 x axis";
  2187.         xaxis2.default=1.0;
  2188.         xaxis2.min=0.0;
  2189.         xaxis2.hint="for ellipses and hyperbolas";
  2190.   
  2191.    
  2192.         yaxis2.caption="section 2 y axis";
  2193.         yaxis2.default=1.0;
  2194.         yaxis2.min=0.0;
  2195.         yaxis2.hint="for ellipses and hyperbolas";
  2196.   
  2197.    
  2198.         metrictype.caption="metric";
  2199.         metrictype.default=0;
  2200.         metrictype.enum="x^2 + y^2\n|x| + |y|\n|x*y|\n|x-y|";
  2201.         metrictype.hint="how the minimum iterate is determined";
  2202.   
  2203.    
  2204.         colorby.caption="color by";
  2205.         colorby.default=0;
  2206.         colorby.enum="2 curve min\n2 curve angle\nz angle @ min\nz mag @ min\niteration # @ min\ndraw section";
  2207.         colorby.hint="see lkm-pub.ucl file for explanations";
  2208.   
  2209.     }
  2210. }
  2211.  
  2212.  
  2213. conic-lite-old { // Kerry Mitchell
  2214. //
  2215. // *** this has been superceded by "conic lite",
  2216. // *** but is offered for compatibility
  2217. //
  2218. // colors by relationship between orbit
  2219. // and conic section.  tastes great, less
  2220. // choices, less filling, easier to use.
  2221. //
  2222. real cerr;
  2223. real cerrmin;
  2224. real Var_x;
  2225. real Var_y;
  2226. real t;
  2227. int iter;
  2228. int itermin;
  2229. real h;
  2230. parameter complex Parm_center;
  2231. real k;
  2232. real aa;
  2233. real bb;
  2234. real cc;
  2235. real dd;
  2236. real ff;
  2237. real a2;
  2238. real b2;
  2239. complex zmin;
  2240. parameter int type;
  2241. parameter real radius;
  2242. parameter real xaxis;
  2243. parameter real yaxis;
  2244. parameter real theta;
  2245. parameter int colorby;
  2246. complex err;
  2247.  
  2248.     void init(void)
  2249.     {
  2250.         cerr=0.0;
  2251.         cerrmin=1.0e12;
  2252.         Var_x=0.0;
  2253.         Var_y=0.0;
  2254.         t=0.0;
  2255.         iter=0;
  2256.         itermin=0;
  2257.         h=real(Parm_center);
  2258.         k=imag(Parm_center);
  2259.         aa=0.0;
  2260.         bb=0.0;
  2261.         cc=0.0;
  2262.         dd=0.0;
  2263.         ff=0.0;
  2264.         a2=0.0;
  2265.         b2=0.0;
  2266.         zmin=(0.0,0.0);
  2267. //
  2268. // set up constants depending on chosen type of section
  2269. //
  2270.         if ((type==1))
  2271.         {// circle
  2272.             aa=1.0;
  2273.             bb=-2.0*h;
  2274.             cc=1.0;
  2275.             dd=-2.0*k;
  2276.             ff=sqr(h)+sqr(k)-sqr(radius);
  2277.         }
  2278.         else if ((type==2))
  2279.         {// ellipse
  2280.             a2=sqr(xaxis);
  2281.             b2=sqr(yaxis);
  2282.             aa=b2;
  2283.             bb=-2.0*h*b2;
  2284.             cc=a2;
  2285.             dd=-2.0*k*a2;
  2286.             ff=b2*sqr(h)+a2*sqr(k)-a2*b2;
  2287.         }
  2288.         else if ((type==3))
  2289.         {// horizontal hyperbola
  2290.             a2=sqr(xaxis);
  2291.             b2=sqr(yaxis);
  2292.             aa=b2;
  2293.             bb=-2.0*h*b2;
  2294.             cc=-a2;
  2295.             dd=2.0*k*a2;
  2296.             ff=b2*sqr(h)-a2*sqr(k)-a2*b2;
  2297.         }
  2298.         else if ((type==4))
  2299.         {// vertical hyperbola
  2300.             a2=sqr(xaxis);
  2301.             b2=sqr(yaxis);
  2302.             aa=-b2;
  2303.             bb=2.0*h*b2;
  2304.             cc=a2;
  2305.             dd=-2.0*k*a2;
  2306.             ff=-b2*sqr(h)+a2*sqr(k)-a2*b2;
  2307.         }
  2308.         else
  2309.         {
  2310.                           // line
  2311.             t=theta/180*pi;
  2312.             aa=0.0;
  2313.             bb=sin(t);
  2314.             cc=0.0;
  2315.             dd=-cos(t);
  2316.             ff=-(bb*h+dd*k);
  2317.         }
  2318.     }
  2319.     void loop(void)
  2320.     {
  2321.         iter=iter+1;
  2322.         Var_x=real(z);
  2323.         Var_y=imag(z);
  2324.         cerr=cabs((aa*Var_x+bb)*Var_x+(cc*Var_y+dd)*Var_y+ff);
  2325.         if ((cerr<cerrmin))
  2326.         {
  2327.             cerrmin=cerr;
  2328.             zmin=z;
  2329.             itermin=iter;
  2330.         }
  2331.     }
  2332.     void final(void)
  2333.     {
  2334.         if ((colorby==0))
  2335.         {// minimum distance
  2336.             index=cerrmin;
  2337.         }
  2338.         else if ((colorby==1))
  2339.         {// iteration @ min
  2340.             index=0.01*itermin;
  2341.         }
  2342.         else if ((colorby==2))
  2343.         {// angle @ min
  2344.             t=atan2(zmin)/pi;
  2345.             if ((t<0.0))
  2346.             {
  2347.                 t=t+2.0;
  2348.             }
  2349.             index=0.5*t;
  2350.         }
  2351.         else
  2352.         {
  2353.                           // draw section
  2354.             Var_x=real(pixel);
  2355.             Var_y=imag(pixel);
  2356.             err=(aa*Var_x+bb)*Var_x+(cc*Var_y+dd)*Var_y+ff;
  2357.             index=0.5*cabs(log(cabs(err)));
  2358.         }
  2359.     }
  2360.     void description(void)
  2361.     {
  2362.         this.title="Old Conic Lite";
  2363.    
  2364.         type.caption="section type";
  2365.         type.default=1;
  2366.         type.enum="line\ncircle\nellipse\nhoriz. hyperbola\nvert. hyperbola";
  2367.   
  2368.    
  2369.         Parm_center.caption="center";
  2370.         Parm_center.default=(0.0,0.0);
  2371.   
  2372.    
  2373.         theta.caption="angle of line";
  2374.         theta.default=45.0;
  2375.         theta.hint="angle to horizontal, degrees";
  2376.   
  2377.    
  2378.         radius.caption="radius";
  2379.         radius.default=1.0;
  2380.         radius.min=0.0;
  2381.   
  2382.    
  2383.         xaxis.caption="x axis";
  2384.         xaxis.default=1.5;
  2385.         xaxis.min=0.0;
  2386.         xaxis.hint="for ellipses and hyperbolas";
  2387.   
  2388.    
  2389.         yaxis.caption="y axis";
  2390.         yaxis.default=0.75;
  2391.         yaxis.min=0.0;
  2392.         yaxis.hint="for ellipses and hyperbolas";
  2393.   
  2394.    
  2395.         colorby.caption="color by";
  2396.         colorby.default=0;
  2397.         colorby.enum="minimum distance\niteration @ min\nangle @ min\ndraw section";
  2398.   
  2399.     }
  2400. }
  2401.  
  2402.  
  2403. comment { ; narrative copyright Kerry Mitchell 06feb99
  2404.  
  2405. The Bubble Method
  2406.  
  2407. The bubble method is an extension of Fractint's bof60 scheme.  In
  2408. bof60, the interior of the fractal is colored by how close the iterate
  2409. comes to the origin.  In the bubble method, a specific value is set as
  2410. the threshold.  At each duration, the magnitude of the iterate is compared
  2411. to the threshold.  If the current magnitude is smaller, it becomes the new
  2412. threshold level.  The effect is to cover the fractal with "bubbles",
  2413. circles the radius of the threshold.  Below a certain threshold value,
  2414. the image is a dust of small, disconnected bubbles.  At a particular
  2415. theshold value, which varies with the parameter c, the circles all
  2416. touch.  Beyond this, the circles squish into each other, like mounds
  2417. of soap bubbles.
  2418.  
  2419. When a new threshold level is set, the iterate and the iteration number
  2420. are stored.  At bailout, the final new values are available for use in
  2421. the coloring.  The index value is a weighted average of the final threshold,
  2422. the iteration number when the last threshold was set, and the polar angle
  2423. of the last threshold's iterate.  The weights of each contribution can be
  2424. individually set using the "mag. weight", "iteration weight", and "angle
  2425. weight" parameters.  Using only the magnitude to color results in a series
  2426. of concentric circles, and using only the angle results in a radial color
  2427. pattern.  Combining equal amounts of magnitude and angle gives a swirl
  2428. effect.  Changing the angle weight to a negative value will reverse the
  2429. direction of the swirl.  A judicious choice of color density will eliminate
  2430. the branch cuts that can be seen with the swirls.
  2431.  
  2432. }
  2433.  
  2434.  
  2435. bubbles { // Kerry Mitchell 06feb98
  2436. //
  2437. // colors by the "bubbles" variation of
  2438. // Fractint's bof60 and bof61 methods
  2439. //
  2440. real weighttotal;
  2441. parameter real weightr;
  2442. parameter real weightt;
  2443. parameter real weighti;
  2444. real wr;
  2445. real wt;
  2446. real wi;
  2447. real twopi;
  2448. real rz;
  2449. real rmin;
  2450. parameter real threshold;
  2451. real tmin;
  2452. complex zmin;
  2453. bool minset;
  2454. real iter;
  2455. real itermin;
  2456.  
  2457.     void init(void)
  2458.     {
  2459.         weighttotal=weightr+cabs(weightt)+weighti;
  2460.         if ((weighttotal==0.0))
  2461.         {
  2462.             weighttotal=1.0;
  2463.         }
  2464.         wr=weightr/weighttotal;
  2465.         wt=cabs(weightt)/weighttotal;
  2466.         wi=weighti/weighttotal;
  2467.         twopi=2.0*pi;
  2468.         rz=0.0;
  2469.         rmin=threshold;
  2470.         tmin=0.0;
  2471.         zmin=(0.0,0.0);
  2472.         minset=false;
  2473.         iter=0.0;
  2474.         itermin=0.0;
  2475.     }
  2476.     void loop(void)
  2477.     {
  2478.         iter=iter+1;
  2479.         rz=cabs(z);
  2480.         if ((rz<rmin))
  2481.         {
  2482.             minset=true;
  2483.             rmin=rz;
  2484.             zmin=z;
  2485.             itermin=iter;
  2486.         }
  2487.     }
  2488.     void final(void)
  2489.     {
  2490.         if ((minset==true))
  2491.         {
  2492.             rmin=rmin/threshold;
  2493.             tmin=atan2(zmin);
  2494.             if ((tmin<0.0))
  2495.             {
  2496.                 tmin=tmin+twopi;
  2497.             }
  2498.             tmin=tmin/twopi;
  2499.             if ((weightt<0.0))
  2500.             {
  2501.                 tmin=1.0-tmin;
  2502.             }
  2503.             iter=itermin/iter;
  2504.             index=cabs(wr*rmin+wt*tmin+wi*iter);
  2505.         }
  2506.         else
  2507.         {
  2508.  
  2509.             index=0.0;
  2510.             solid=true;
  2511.         }
  2512.     }
  2513.     void description(void)
  2514.     {
  2515.         this.title="Bubbles";
  2516.    
  2517.         threshold.caption="bubble radius";
  2518.         threshold.default=1.0;
  2519.         threshold.min=0.0;
  2520.   
  2521.    
  2522.         weightr.caption="mag. weight";
  2523.         weightr.default=1.0;
  2524.         weightr.hint="relative weight of magnitude component";
  2525.   
  2526.    
  2527.         weightt.caption="angle weight";
  2528.         weightt.default=1.0;
  2529.         weightt.hint="relative weight of polar angle";
  2530.   
  2531.    
  2532.         weighti.caption="iteration weight";
  2533.         weighti.default=1.0;
  2534.         weighti.hint="relative weight of iteration count";
  2535.   
  2536.     }
  2537. }
  2538.  
  2539.  
  2540. comment { ; narrative copyright Kerry Mitchell 21feb99
  2541.  
  2542. Range
  2543.  
  2544. In the range coloring schemes, the pixels are only colored when the
  2545. iterate (or a component of it) falls within a specified range.
  2546. (Otherwise, the #solid flag is set to true.)  The range is given in
  2547. terms of the center and width.  For example, setting the center to
  2548. 1.0 and the range to 0.1 would yield a range of 0.95 to 1.05.
  2549.  
  2550. The simplest case is shown in the "Range Lite" formula.  Here, the
  2551. orbit is monitored until the magnitude of the iterate falls within
  2552. a specified range.  When this occurs, that iterate is saved.  Upon
  2553. bailout (either escape or maximum iterations), the point can be colored
  2554. according to either the magnitude or the polar angle of the iterate.
  2555. Either the first iterate to fall into the range or the last iterate
  2556. can be used.  The difference is in the overlapping of the rings of
  2557. color.  Using the first iterate gives the appearance of the "earlier"
  2558. rings (from lower iteration numbers) stacked on top of the "later"
  2559. rings.  Using the laster iterate reverses the order of the stacking.
  2560. Depending on the range chosen, the results can be circular rings,
  2561. pinched loops (figure "8"), or open loops.  The shapes are definitely
  2562. non-fractal, but are assembled in such a way to recover the underlying
  2563. fractal structure.
  2564.  
  2565. This method opens itself up to many variations, which can be explored
  2566. using the full "Range" coloring.  In essence, some variable is monitored
  2567. to see when it falls in the specified range.  When it does, another
  2568. variable is used for coloring.  There are several options for the
  2569. "range variable", the variable that is checked against the range:
  2570. the magnitude of z, its real or imaginary part, and its polar angle.
  2571. Plus, any of the standard functions can be used on z, and the real
  2572. or imaginary parts used.  A final choice, "heart", is a combination
  2573. of the magnitude and polar angle, that covers the image with heart
  2574. shapes.  The same choices are available for the "coloring variable",
  2575. the variable used to set #index.
  2576.  
  2577. Since #index takes on values from 0.0 to 1.0, the coloring variable
  2578. may need adjusting before being used as the #index.  If the coloring
  2579. variable is the same as the range variable, then the range parameters
  2580. are used to scale the variable into #index.  Otherwise, the coloring
  2581. variable can be easily scaled into the #index variable.  Specifically,
  2582.  
  2583. #index = slope * scale_function(coloring_variable) + offset.
  2584.  
  2585. For example, if real(z) is used as the coloring variable, then the
  2586. tanh() function can scale real(z) to -1.0 to 1.0.  Then, using slope
  2587. of 0.5 and an offset of 0.5 will give the final range of 0.0 to 1.0
  2588. for the #index.
  2589.  
  2590. Finally, the "color by" parameter determines which iterate or iterates
  2591. are used in the coloring.  Using the "first" or "last" settings will
  2592. vary the apparant stacking of the color rings.  The "average" setting
  2593. will cause all the coloring variables for which the range variables
  2594. fall into the range to be averaged together, and that mean used for
  2595. the coloring.  If the range width is set fairly small, then there won't
  2596. be much difference between "average" and "first" or "last".  But there
  2597. can be a quite significant change if the range width is large.  The
  2598. last choice, "fraction in range", simply uses the ratio of number of
  2599. times the range variable falls within the range, to the total number of
  2600. iterations for that pixel.
  2601.  
  2602. }
  2603.  
  2604.  
  2605. range-lite { // Kerry Mitchell 21feb99
  2606. //
  2607. // Simplified version of "Range" coloring.
  2608. // Colors by magnitude or angle when magnitude
  2609. // of z falls in prescribed range.
  2610. //
  2611. int rangeiter;
  2612. real rangemin;
  2613. parameter real rangecenter;
  2614. parameter real rangewidth;
  2615. real rangemax;
  2616. real rz;
  2617. real twopi;
  2618. real r1;
  2619. real rn;
  2620. real t1;
  2621. real tn;
  2622. parameter int colorby;
  2623.  
  2624.     void init(void)
  2625.     {
  2626.         rangeiter=0;
  2627.         rangemin=rangecenter-0.5*rangewidth;
  2628.         rangemax=rangemin+rangewidth;
  2629.         rz=0.0;
  2630.         twopi=2.0*pi;
  2631.         r1=0.0;
  2632.         rn=0.0;
  2633.         t1=0.0;
  2634.         tn=0.0;
  2635.     }
  2636.     void loop(void)
  2637.     {
  2638.         rz=cabs(z);
  2639.         if (((rz>=rangemin)&&(rz<=rangemax)))
  2640.         {
  2641.             rangeiter=rangeiter+1;
  2642.             rn=rz;
  2643.             tn=atan2(z);
  2644.             if ((rangeiter==1))
  2645.             {
  2646.                 r1=rn;
  2647.                 t1=tn;
  2648.             }
  2649.         }
  2650.     }
  2651.     void final(void)
  2652.     {
  2653.         if ((rangeiter==0))
  2654.         {
  2655.             solid=true;
  2656.         }
  2657.         else
  2658.         {
  2659.  
  2660.             if ((colorby==0))
  2661.             {// first mag
  2662.                 r1=(r1-rangemin)/(rangemax-rangemin);
  2663.                 index=r1;
  2664.             }
  2665.             else if ((colorby==1))
  2666.             {// last mag
  2667.                 rn=(rn-rangemin)/(rangemax-rangemin);
  2668.                 index=rn;
  2669.             }
  2670.             else if ((colorby==2))
  2671.             {// first angle
  2672.                 if ((t1<0.0))
  2673.                 {
  2674.                     t1=t1+twopi;
  2675.                 }
  2676.                 t1=t1/twopi;
  2677.                 index=t1;
  2678.             }
  2679.             else if ((colorby==3))
  2680.             {// last angle
  2681.                 if ((tn<0.0))
  2682.                 {
  2683.                     tn=tn+twopi;
  2684.                 }
  2685.                 tn=tn/twopi;
  2686.                 index=tn;
  2687.             }
  2688.         }
  2689.     }
  2690.     void description(void)
  2691.     {
  2692.         this.title="Range Lite";
  2693.    
  2694.         rangecenter.caption="range center";
  2695.         rangecenter.default=1.0;
  2696.   
  2697.    
  2698.         rangewidth.caption="range width";
  2699.         rangewidth.default=0.1;
  2700.   
  2701.    
  2702.         colorby.caption="color by";
  2703.         colorby.default=3;
  2704.         colorby.enum="first mag\nlast mag\nfirst angle\nlast angle";
  2705.   
  2706.     }
  2707. }
  2708.  
  2709.  
  2710. range { // Kerry Mitchell 21feb99
  2711. //
  2712. // Colors by 2nd number when 1st
  2713. // number falls in prescribed range.
  2714. // Entirely too many choices for 1st
  2715. // and 2nd numbers.  :-)
  2716. //
  2717. int rangeiter;
  2718. real rangemin;
  2719. parameter real rangecenter;
  2720. parameter real rangewidth;
  2721. real rangemax;
  2722. real rvar;
  2723. real cvar;
  2724. real cvar1;
  2725. real cvarn;
  2726. real cvarave;
  2727. real twopi;
  2728. parameter int rangevar;
  2729. parameter int colorvar;
  2730. parameter real slope;
  2731. parameter real offset;
  2732. parameter int colorby;
  2733.  
  2734.     void init(void)
  2735.     {
  2736.         rangeiter=0;
  2737.         rangemin=rangecenter-0.5*rangewidth;
  2738.         rangemax=rangemin+rangewidth;
  2739.         rvar=0.0;
  2740.         cvar=0.0;
  2741.         cvar1=0.0;
  2742.         cvarn=0.0;
  2743.         cvarave=0.0;
  2744.         twopi=2.0*pi;
  2745.     }
  2746.     void loop(void)
  2747.     {
  2748.         if ((rangevar==0))
  2749.         {
  2750.             rvar=cabs(z);
  2751.         }
  2752.         else if ((rangevar==1))
  2753.         {
  2754.             rvar=real(z);
  2755.         }
  2756.         else if ((rangevar==2))
  2757.         {
  2758.             rvar=imag(z);
  2759.         }
  2760.         else if ((rangevar==3))
  2761.         {
  2762.             rvar=atan2(z);
  2763.         }
  2764.         else if ((rangevar==4))
  2765.         {
  2766.             rvar=real(rangefunc(z));
  2767.         }
  2768.         else if ((rangevar==5))
  2769.         {
  2770.             rvar=imag(rangefunc(z));
  2771.         }
  2772.         else if ((rangevar==6))
  2773.         {
  2774.             rvar=cabs(atan2(z))/pi-cabs(z);
  2775.         }
  2776.         if (((rvar>=rangemin)&&(rvar<=rangemax)))
  2777.         {
  2778.             rangeiter=rangeiter+1;
  2779.             if ((colorvar==0))
  2780.             {
  2781.                 cvar=cabs(z);
  2782.             }
  2783.             else if ((colorvar==1))
  2784.             {
  2785.                 cvar=real(z);
  2786.             }
  2787.             else if ((colorvar==2))
  2788.             {
  2789.                 cvar=imag(z);
  2790.             }
  2791.             else if ((colorvar==3))
  2792.             {
  2793.                 cvar=atan2(z);
  2794.                 if ((cvar<0.0))
  2795.                 {
  2796.                     cvar=cvar+twopi;
  2797.                 }
  2798.                 cvar=cvar/twopi;
  2799.             }
  2800.             else if ((colorvar==4))
  2801.             {
  2802.                 cvar=real(colorfunc(z));
  2803.             }
  2804.             else if ((colorvar==5))
  2805.             {
  2806.                 cvar=imag(colorfunc(z));
  2807.             }
  2808.             else if ((colorvar==6))
  2809.             {
  2810.                 cvar=cabs(atan2(z))/pi-cabs(z);
  2811.             }
  2812.             if ((colorvar==rangevar))
  2813.             {
  2814.                 cvarn=(cvar-rangemin)/(rangemax-rangemin);
  2815.             }
  2816.             else
  2817.             {
  2818.  
  2819.                 cvarn=slope*real(scalefunc(cvar))+offset;
  2820.             }
  2821.             if ((rangeiter==1))
  2822.             {
  2823.                 cvar1=cvarn;
  2824.             }
  2825.             cvarave=cvarave+cvarn;
  2826.         }
  2827.     }
  2828.     void final(void)
  2829.     {
  2830.         if ((rangeiter==0))
  2831.         {
  2832.             solid=true;
  2833.         }
  2834.         else
  2835.         {
  2836.  
  2837.             if ((colorby==0))
  2838.             {// first
  2839.                 index=cvar1;
  2840.             }
  2841.             else if ((colorby==1))
  2842.             {// average
  2843.                 index=cvarave/rangeiter;
  2844.             }
  2845.             else if ((colorby==2))
  2846.             {// last
  2847.                 index=cvarn;
  2848.             }
  2849.             else if ((colorby==3))
  2850.             {// % in range
  2851.                 index=rangeiter/numiter;
  2852.             }
  2853.         }
  2854.     }
  2855.     void description(void)
  2856.     {
  2857.         this.title="Range";
  2858.    
  2859.         rangecenter.caption="range center";
  2860.         rangecenter.default=1.0;
  2861.   
  2862.    
  2863.         rangewidth.caption="range width";
  2864.         rangewidth.default=0.1;
  2865.   
  2866.    
  2867.         rangevar.caption="range variable";
  2868.         rangevar.default=0;
  2869.         rangevar.enum="magnitude\nreal(z)\nimag(z)\npolar angle\nreal f(z)\nimag f(z)\nheart";
  2870.   
  2871.    
  2872.         colorvar.caption="coloring variable";
  2873.         colorvar.default=0;
  2874.         colorvar.enum="magnitude\nreal(z)\nimag(z)\npolar angle\nreal f(z)\nimag f(z)\nheart";
  2875.   
  2876.    
  2877.         slope.caption="slope";
  2878.         slope.default=1.0;
  2879.         slope.hint="for adjusting coloring variable into 0.0 - 1.0 range for #index; index=slope*fn(var))+offset";
  2880.   
  2881.    
  2882.         offset.caption="offset";
  2883.         offset.default=0.0;
  2884.         offset.hint="for adjusting coloring variable into 0.0 - 1.0 range for #index; index=slope*fn(var))+offset";
  2885.   
  2886.    
  2887.         colorby.caption="color by";
  2888.         colorby.default=2;
  2889.         colorby.enum="first\naverage\nlast\nfraction in range";
  2890.   
  2891.    
  2892.         scalefunc.caption="scaling function";
  2893.         scalefunc.default="ident" ;
  2894.         scalefunc.hint="for adjusting coloring variable into 0.0 - 1.0 range for #index; index=slope*fn(var))+offset";
  2895.   
  2896.    
  2897.         rangefunc.caption="range function";
  2898.         rangefunc.default="sqr" ;
  2899.         rangefunc.hint="for creating new range variables";
  2900.   
  2901.    
  2902.         colorfunc.caption="coloring function";
  2903.         colorfunc.default="sqr" ;
  2904.         colorfunc.hint="for creating new coloring variables";
  2905.   
  2906.     }
  2907. }
  2908.  
  2909.  
  2910. passthru { // Kerry Mitchell 02jul99
  2911. //
  2912. // Special purpose coloring, designed to be used with the 
  2913. // "Quadrilateral Color" transform.
  2914. //
  2915. // Reads the x and y pixel flags, and determines an #index
  2916. // value from them.
  2917. //
  2918. int xflag;
  2919. int yflag;
  2920. parameter real xytype;
  2921. parameter real n;
  2922. parameter real m;
  2923.  
  2924.     void init(void)
  2925.     {
  2926.         xflag=round(real(pixel)/20);
  2927.         yflag=round(imag(pixel)/20);
  2928.     }
  2929.     void loop(void)
  2930.     {
  2931.     }
  2932.     void final(void)
  2933.     {
  2934.         if ((xytype==1))
  2935.         {
  2936.             index=yflag/n;
  2937.         }
  2938.         else if ((xytype==2))
  2939.         {
  2940.             index=(m*xflag+yflag)/n;
  2941.         }
  2942.         else if ((xytype==3))
  2943.         {
  2944.             index=(m*yflag+xflag)/n;
  2945.         }
  2946.         else
  2947.         {
  2948.  
  2949.             index=xflag/n;
  2950.         }
  2951.     }
  2952.     void description(void)
  2953.     {
  2954.         this.title="Passthru";
  2955.    
  2956.         xytype.caption="flag type";
  2957.         xytype.enum="x\ny\nm*x+y\nm*y+x";
  2958.         xytype.default=0;
  2959.   
  2960.    
  2961.         m.caption="m: flag factor";
  2962.         m.default=1.0;
  2963.         m.hint="use with 'm*x+y' and 'm*y+x' flag types";
  2964.   
  2965.    
  2966.         n.caption="flag scale";
  2967.         n.default=1.0;
  2968.         n.hint="#index = flag/scale";
  2969.   
  2970.     }
  2971. }
  2972.  
  2973.  
  2974. distance-point { // Kerry Mitchell 06feb00
  2975. //
  2976. // Colors by the distance from the orbit to a specified
  2977. // point.  Offers 7 different ways to determine the distance,
  2978. // and colors by the closest approach, the furthest approach,
  2979. // or combinations thereof.
  2980. //
  2981. // See the helpfile for more information.
  2982. //
  2983. real Var_x;
  2984. real Var_y;
  2985. real d;
  2986. real dfirst;
  2987. real dlast;
  2988. real dmin;
  2989. real dmax;
  2990. real dsum;
  2991. real dproduct;
  2992. real temp;
  2993. real temp2;
  2994. real twooverpi;
  2995. real pio2;
  2996. complex tempc;
  2997. int iter;
  2998. real x0e;
  2999. parameter complex point;
  3000. parameter real r;
  3001. real cosy0e;
  3002. real siny0e;
  3003. real x0h;
  3004. real y0h;
  3005. real r0h;
  3006. parameter int metric;
  3007. parameter real power;
  3008. parameter int colorby;
  3009.  
  3010.     void init(void)
  3011.     {
  3012.         Var_x=0.0;
  3013.         Var_y=0.0;
  3014.         d=0.0;
  3015.         dfirst=0.0;
  3016.         dlast=0.0;
  3017.         dmin=1e20;
  3018.         dmax=0.0;
  3019.         dsum=0.0;
  3020.         dproduct=1.0;
  3021.         temp=0.0;
  3022.         temp2=0.0;
  3023.         twooverpi=2.0/pi;
  3024.         pio2=0.5*pi;
  3025.         tempc=(0,0);
  3026.         iter=0;
  3027. //
  3028. // reference point for elliptical geometry:
  3029. //   x becomes theta (longitude)
  3030. //   y becomes phi (latitude)
  3031. //   (spherical coordinates)
  3032. //
  3033.         x0e=real(point)/r*pi;
  3034.         temp=imag(point)/r*pio2;
  3035.         cosy0e=cos(temp);
  3036.         siny0e=sin(temp);
  3037. //
  3038. // reference point for hyperbolic geometry
  3039. //
  3040.         x0h=real(point)/r;
  3041.         y0h=imag(point)/r;
  3042.         r0h=sqrt(1-sqr(x0h)-sqr(y0h));
  3043.  
  3044.     }
  3045.     void loop(void)
  3046.     {
  3047.         iter=iter+1;
  3048. //
  3049. // determine distance based on metric choice
  3050. //
  3051.         if ((metric==1))
  3052.         {// elliptic geometry
  3053. //
  3054. // spherical coordinates:
  3055. //   x becomes longitude, y becomes latitude
  3056. //
  3057.             Var_x=real(z)/r*pi;
  3058.             Var_y=imag(z)/r*pio2;
  3059.             temp=cos(Var_y)*cosy0e*cos(Var_x-x0e)+sin(Var_y)*siny0e;
  3060. //
  3061. // use atan to find angle between reference and field points
  3062. //
  3063.             temp2=sqrt(1.0-temp*temp);
  3064.             if ((temp>0.0))
  3065.             {
  3066.                 d=atan(temp2/temp);
  3067.             }
  3068.             else if ((temp<0.0))
  3069.             {
  3070.                 d=atan(temp2/temp)+pi;
  3071.             }
  3072.             else
  3073.             {
  3074.  
  3075.                 d=pio2;
  3076.             }
  3077. //
  3078. // distance = radius * angle
  3079. //
  3080.             d=r*d;
  3081.         }
  3082.         else if ((metric==2))
  3083.         {// hyperbolic geometry
  3084.             Var_x=real(z)/r;
  3085.             Var_y=imag(z)/r;
  3086.             temp=(1.0-Var_x*x0h-Var_y*y0h);
  3087.             temp=temp/(r0h*sqrt(1-sqr(Var_x)-sqr(Var_y)));
  3088. //
  3089. //  distance = radius * angle
  3090. //
  3091.             d=r*acosh(temp);
  3092.         }
  3093.         else if ((metric==3))
  3094.         {// minimum
  3095. //
  3096. // uses minimum of delta-x and delta-y
  3097. //   not a true distance, but included anyway
  3098. //
  3099.             Var_x=abs(real(z-point));
  3100.             Var_y=abs(imag(z-point));
  3101.             if ((Var_x<Var_y))
  3102.             {
  3103.                 d=Var_x;
  3104.             }
  3105.             else
  3106.             {
  3107.  
  3108.                 d=Var_y;
  3109.             }
  3110.         }
  3111.         else if ((metric==4))
  3112.         {// maximum
  3113. //
  3114. // uses maximum of delta-x and delta-y
  3115. //
  3116.             Var_x=abs(real(z-point));
  3117.             Var_y=abs(imag(z-point));
  3118.             if ((Var_x>Var_y))
  3119.             {
  3120.                 d=Var_x;
  3121.             }
  3122.             else
  3123.             {
  3124.  
  3125.                 d=Var_y;
  3126.             }
  3127.         }
  3128.         else if ((metric==5))
  3129.         {// sum
  3130. //
  3131. // uses sum of delta-x and delta-y
  3132. //
  3133.             Var_x=abs(real(z-point));
  3134.             Var_y=abs(imag(z-point));
  3135.             d=Var_x+Var_y;
  3136.         }
  3137.         else if ((metric==6))
  3138.         {// product
  3139. //
  3140. // uses product of delta-x and delta-y
  3141. //   not a true distance, but included anyway
  3142. //
  3143.             Var_x=abs(real(z-point));
  3144.             Var_y=abs(imag(z-point));
  3145.             d=sqrt(Var_x*Var_y);
  3146.         }
  3147.         else
  3148.         {
  3149.                        // euclidean
  3150. //
  3151. // generalized pythagorean theorem
  3152. //
  3153.             Var_x=abs(real(z-point));
  3154.             Var_y=abs(imag(z-point));
  3155.             d=(Var_x^power+Var_y^power)^(1/power);
  3156.         }
  3157. //
  3158. // fill variables for different coloring types
  3159. //
  3160.         if ((iter==1))
  3161.         {
  3162.             dfirst=d;
  3163.         }
  3164.         if ((d<dmin))
  3165.         {
  3166.             dmin=d;
  3167.         }
  3168.         if ((d>dmax))
  3169.         {
  3170.             dmax=d;
  3171.         }
  3172.         dsum=dsum+d;
  3173.         dproduct=dproduct*d;
  3174.  
  3175.     }
  3176.     void final(void)
  3177.     {
  3178.         dlast=d;
  3179.         if ((colorby==0))
  3180.         {// first
  3181.             index=dfirst;
  3182.         }
  3183.         else if ((colorby==1))
  3184.         {// last
  3185.             index=dlast;
  3186.         }
  3187.         else if ((colorby==2))
  3188.         {// first/last angle
  3189.             tempc=dfirst+flip(dlast);
  3190.             temp=atan2(tempc);
  3191.             index=temp*twooverpi;
  3192.         }
  3193.         else if ((colorby==3))
  3194.         {// minimum
  3195.             index=dmin;
  3196.         }
  3197.         else if ((colorby==4))
  3198.         {// maximum
  3199.             index=dmax;
  3200.         }
  3201.         else if ((colorby==5))
  3202.         {// min/max angle
  3203.             tempc=dmin+flip(dmax);
  3204.             temp=atan2(tempc);
  3205.             index=temp*twooverpi;
  3206.         }
  3207.         else if ((colorby==6))
  3208.         {// arithmetic mean
  3209.             index=dsum/iter;
  3210.         }
  3211.         else if ((colorby==7))
  3212.         {// geometric mean
  3213.             temp=log(dproduct)/iter;
  3214.             index=exp(temp);
  3215.         }
  3216.         else if ((colorby==8))
  3217.         {// amean/gmean angle
  3218.             temp=dsum/iter;
  3219.             temp2=log(dproduct)/iter;
  3220.             temp2=exp(temp2);
  3221.             tempc=temp+flip(temp2);
  3222.             temp=atan2(tempc);
  3223.             index=temp*twooverpi;
  3224.         }      
  3225.     }
  3226.     void description(void)
  3227.     {
  3228.         this.title="Distance to a Point";
  3229.         this.helpfile="lkm-help\lkm-distance.html";
  3230.    
  3231.         point.caption="reference point";
  3232.         point.default=(0,0);
  3233.         point.hint="Point from which distance is measured.";
  3234.   
  3235.    
  3236.         metric.caption="distance metric";
  3237.         metric.default=0;
  3238.         metric.enum="Euclidean\nelliptic\nhyperbolic\nminimum\nmaximum\nsum\nproduct";
  3239.         metric.hint="What type of formula is used to figure the distance.";
  3240.   
  3241.    
  3242.         colorby.caption="color by:";
  3243.         colorby.default=3;
  3244.         colorby.enum="1st distance\nlast distance\n1st/last combo\nminimum\nmaximum\nmin/max combo\narithmetic mean\ngeometric mean\na/g combo";
  3245.         colorby.hint="Combinations plot the angle using the first variable as the x, and the 2nd as the y.";
  3246.   
  3247.    
  3248.         power.caption="power";
  3249.         power.default=2.0;
  3250.         power.min=1.0;
  3251.         power.hint="Exponent used with 'power' metric.  Must be at least 1.  Use 2 for standard Pythagorean distance.";
  3252.   
  3253.    
  3254.         r.caption="radius";
  3255.         r.default=4.0;
  3256.         r.hint="Used with 'elliptic' & 'hyperbolic' metrics.  Should be larger than the bailout.";
  3257.   
  3258.     }
  3259. }
  3260.  
  3261.  
  3262. pythagorean-triple { // Kerry Mitchell 06feb00
  3263. //
  3264. // Colors by the approach of the orbit to a Pythagorean
  3265. // triple:  when x, y, and r are all integers.  Uses
  3266. // several different ways to find the closest integer
  3267. // to determine the distance.  Colors according to 
  3268. // the closest approach, the furthest approach, or 
  3269. // combinations thereof.
  3270. //
  3271. // See the helpfile for more information.
  3272. //
  3273. real rx;
  3274. real ry;
  3275. real rr;
  3276. real r;
  3277. real rmin;
  3278. real rmax;
  3279. real rsum;
  3280. real rproduct;
  3281. real temp;
  3282. real temp2;
  3283. int iter;
  3284. int itermin;
  3285. int itermax;
  3286. complex zmin;
  3287. complex zmax;
  3288. parameter int inttype;
  3289. parameter int rtype;
  3290. parameter real power;
  3291. parameter int colorby;
  3292.  
  3293.     void init(void)
  3294.     {
  3295.         rx=0.0;
  3296.         ry=0.0;
  3297.         rr=0.0;
  3298.         r=0.0;
  3299.         rmin=1.0e12;
  3300.         rmax=0.0;
  3301.         rsum=0.0;
  3302.         rproduct=1.0;
  3303.         temp=0.0;
  3304.         temp2=0.0;
  3305.         iter=0;
  3306.         itermin=0;
  3307.         itermax=0;
  3308.         zmin=(0.0,0.0);
  3309.         zmax=(0.0,0.0);
  3310.  
  3311.     }
  3312.     void loop(void)
  3313.     {
  3314.         iter=iter+1;
  3315. //
  3316. // generate closest integer
  3317. //
  3318.         if ((inttype==0))
  3319.         {// round
  3320.             temp=cabs(z);
  3321.             rr=abs(temp-round(temp));
  3322.             temp=real(z);
  3323.             rx=abs(temp-round(temp));
  3324.             temp=imag(z);
  3325.             ry=abs(temp-round(temp));
  3326.         }
  3327.         else if ((inttype==1))
  3328.         {// trunc
  3329.             temp=cabs(z);
  3330.             rr=abs(temp-trunc(temp));
  3331.             temp=real(z);
  3332.             rx=abs(temp-trunc(temp));
  3333.             temp=imag(z);
  3334.             ry=abs(temp-trunc(temp));
  3335.         }
  3336.         else if ((inttype==2))
  3337.         {// ceiling
  3338.             temp=cabs(z);
  3339.             rr=abs(temp-ceil(temp));
  3340.             temp=real(z);
  3341.             rx=abs(temp-ceil(temp));
  3342.             temp=imag(z);
  3343.             ry=abs(temp-ceil(temp));
  3344.         }
  3345.         else if ((inttype==3))
  3346.         {// floor
  3347.             temp=cabs(z);
  3348.             rr=abs(temp-floor(temp));
  3349.             temp=real(z);
  3350.             rx=abs(temp-floor(temp));
  3351.             temp=imag(z);
  3352.             ry=abs(temp-floor(temp));
  3353.         }
  3354. //
  3355. // find distance to integer
  3356. //
  3357.         if ((rtype==1))
  3358.         {// minimum
  3359.             r=rr;
  3360.             if ((rx<r))
  3361.             {
  3362.                 r=rx;
  3363.             }
  3364.             if ((ry<r))
  3365.             {
  3366.                 r=ry;
  3367.             }
  3368.         }
  3369.         else if ((rtype==2))
  3370.         {// maximum
  3371.             r=rr;
  3372.             if ((rx>r))
  3373.             {
  3374.                 r=rx;
  3375.             }
  3376.             if ((ry>r))
  3377.             {
  3378.                 r=ry;
  3379.             }
  3380.         }
  3381.         else if ((rtype==3))
  3382.         {// sum
  3383.             r=rr+rx+ry;
  3384.         }
  3385.         else if ((rtype==4))
  3386.         {// product
  3387.             r=(rr*rx*ry)^(1/3);
  3388.         }
  3389.         else
  3390.         {
  3391.                        // euclidean
  3392.             r=(rx^power+ry^power+rr^power)^(1/power);
  3393.         }
  3394. //
  3395. // find min, max & build tallies for means
  3396. //
  3397.         rsum=rsum+r;
  3398.         rproduct=rproduct*r;
  3399.         if ((r<rmin))
  3400.         {
  3401.             rmin=r;
  3402.             zmin=z;
  3403.             itermin=iter;
  3404.         }
  3405.         if ((r>rmax))
  3406.         {
  3407.             rmax=r;
  3408.             zmax=z;
  3409.             itermax=iter;
  3410.         }
  3411.  
  3412.     }
  3413.     void final(void)
  3414.     {
  3415.         if ((colorby==0))
  3416.         {// minimum distance
  3417.             index=rmin;
  3418.         }
  3419.         else if ((colorby==1))
  3420.         {// iteration @ min
  3421.             index=0.01*itermin;
  3422.         }
  3423.         else if ((colorby==2))
  3424.         {// angle @ min
  3425.             temp=atan2(zmin)/pi;
  3426.             if ((temp<0.0))
  3427.             {
  3428.                 temp=temp+2.0;
  3429.             }
  3430.             index=0.5*temp;
  3431.         }
  3432.         else if ((colorby==3))
  3433.         {// maximum distance
  3434.             index=rmax;
  3435.         }
  3436.         else if ((colorby==4))
  3437.         {// iteration @ max
  3438.             index=0.01*itermax;
  3439.         }
  3440.         else if ((colorby==5))
  3441.         {// angle @ max
  3442.             temp=atan2(zmax)/pi;
  3443.             if ((temp<0.0))
  3444.             {
  3445.                 temp=temp+2.0;
  3446.             }
  3447.             index=0.5*temp;
  3448.         }
  3449.         else if ((colorby==6))
  3450.         {// min/max distance angle
  3451.             zmin=rmin+flip(rmax);
  3452.             temp=atan2(zmin)/pi;
  3453.             if ((temp<0.0))
  3454.             {
  3455.                 temp=temp+2.0;
  3456.             }
  3457.             index=0.5*temp;
  3458.         }
  3459.         else if ((colorby==7))
  3460.         {// arithmetic mean
  3461.             index=rsum/iter;
  3462.         }
  3463.         else if ((colorby==8))
  3464.         {// geometric mean
  3465.             temp=log(rproduct)/iter;
  3466.             index=exp(temp);
  3467.         }
  3468.         else if ((colorby==9))
  3469.         {// amean/gmean angle
  3470.             temp=rsum/iter;
  3471.             temp2=log(rproduct)/iter;
  3472.             temp2=exp(temp2);
  3473.             zmax=temp+flip(temp2);
  3474.             temp=atan2(zmax)/pi;
  3475.             if ((temp<0.0))
  3476.             {
  3477.                 temp=temp+2.0;
  3478.             }
  3479.             index=0.5*temp;
  3480.         }
  3481.     }
  3482.     void description(void)
  3483.     {
  3484.         this.title="Pythagorean Triple";
  3485.         this.helpfile="lkm-help\lkm-pythagorean.html";
  3486.    
  3487.         inttype.caption="integer type";
  3488.         inttype.default=0;
  3489.         inttype.enum="round\ntrunc\nceil\nfloor";
  3490.   
  3491.    
  3492.         rtype.caption="distance type";
  3493.         rtype.default=0;
  3494.         rtype.enum="Euclidean\nminimum\nmaximum\nsum\nproduct";
  3495.         rtype.hint="How the distance to the integer is calculated:  'Euclidean' is like the regular Pythagorean distance, 'minimum' takes the smallest of the 3 components, 'maximum' takes the largest, 'sum' adds them, and 'product' multiplies them.";
  3496.   
  3497.    
  3498.         colorby.caption="color by";
  3499.         colorby.default=0;
  3500.         colorby.enum="minimum distance\niteration @ min\nangle @ min\nmaximum distance\niteration @ max\nangle @ max\nmin/max combo\narithmetic mean\ngeometric mean\namean/gmean combo";
  3501.         colorby.hint="How the color is set; the combos use the 1st quantity for the x and the 2nd for the y, and color by the angle.";
  3502.   
  3503.    
  3504.         power.caption="power";
  3505.         power.default=2.0;
  3506.         power.hint="Exponent for the 'Euclidean' type. Use 2 for standard Pythagorean distance.";
  3507.   
  3508.     }
  3509. }
  3510.  
  3511.  
  3512. bezier-curve { // Kerry Mitchell 08apr00
  3513. //
  3514. // Colors by the orbit's closest approach to a user-defined Bezier curve.
  3515. // The curve is determined by specifying beginning and ending anchor points,
  3516. // through which the curve passes, and 2 control points, which influence the
  3517. // shape of the curve.
  3518. //
  3519. real x0;
  3520. parameter complex z0;
  3521. real y0;
  3522. real x1;
  3523. parameter complex z1;
  3524. real y1;
  3525. real x2;
  3526. parameter complex z2;
  3527. real y2;
  3528. real x3;
  3529. parameter complex z3;
  3530. real y3;
  3531. real cx;
  3532. real bx;
  3533. real ax;
  3534. real cy;
  3535. real by;
  3536. real ay;
  3537. real t;
  3538. real r;
  3539. real Var_x;
  3540. real Var_y;
  3541. real u;
  3542. real v;
  3543. int iter;
  3544. real rmin;
  3545. int itermin;
  3546. complex zmin;
  3547. parameter real dt;
  3548. parameter int colorby;
  3549. parameter real nexp;
  3550.  
  3551.     void init(void)
  3552.     {
  3553.         x0=real(z0);
  3554.         y0=imag(z0);
  3555.         x1=real(z1);
  3556.         y1=imag(z1);
  3557.         x2=real(z2);
  3558.         y2=imag(z2);
  3559.         x3=real(z3);
  3560.         y3=imag(z3);
  3561.         cx=3*(x1-x0);
  3562.         bx=3*(x2-x1)-cx;
  3563.         ax=x3-x0-cx-bx;
  3564.         cy=3*(y1-y0);
  3565.         by=3*(y2-y1)-cy;
  3566.         ay=y3-y0-cy-by;
  3567.         t=0.0;
  3568.         r=0.0;
  3569.         Var_x=0.0;
  3570.         Var_y=0.0;
  3571.         u=0.0;
  3572.         v=0.0;
  3573.         iter=0;
  3574.         rmin=1.0e20;
  3575.         itermin=0;
  3576.         zmin=(0.0,0.0);
  3577.     }
  3578.     void loop(void)
  3579.     {
  3580.         iter=iter+1;
  3581.         u=real(z);
  3582.         v=imag(z);
  3583. //
  3584. // The curve is parameterized with x(t) and y(t).  Step through several t
  3585. // values to find the nearest approach of the orbit to the curve.
  3586. //
  3587.         t=0.0;
  3588.         while ((t<=1.0))
  3589.         {
  3590.             Var_x=((ax*t+bx)*t+cx)*t+x0;
  3591.             Var_y=((ay*t+by)*t+cy)*t+y0;
  3592.             r=(Var_x-u)*(Var_x-u)+(Var_y-v)*(Var_y-v);
  3593.             if ((r<rmin))
  3594.             {
  3595.                 rmin=r;
  3596.                 itermin=iter;
  3597.                 zmin=z;
  3598.             }
  3599.             t=t+dt;
  3600.         }
  3601.     }
  3602.     void final(void)
  3603.     {
  3604.         if ((colorby==1))
  3605.         {// iteration @ min
  3606.             index=0.01*itermin;
  3607.         }
  3608.         else if ((colorby==2))
  3609.         {// angle @ min
  3610.             t=atan2(zmin);
  3611.             t=t/pi;
  3612.             if ((t<0.0))
  3613.             {
  3614.                 t=t+2.0;
  3615.             }
  3616.             index=0.5*t;
  3617.         }
  3618.         else if ((colorby==3))
  3619.         {// draw section
  3620.             u=real(pixel);
  3621.             v=imag(pixel);
  3622.             t=0.0;
  3623.             rmin=1e20;
  3624.             while ((t<=1.0))
  3625.             {
  3626.                 Var_x=((ax*t+bx)*t+cx)*t+x0;
  3627.                 Var_y=((ay*t+by)*t+cy)*t+y0;
  3628.                 r=(Var_x-u)*(Var_x-u)+(Var_y-v)*(Var_y-v);
  3629.                 if ((r<rmin))
  3630.                 {
  3631.                     rmin=r;
  3632.                 }
  3633.                 t=t+dt;
  3634.             }
  3635.             index=rmin^nexp;
  3636.         }
  3637.         else
  3638.         {
  3639.                        // minimum distance
  3640.             index=rmin^nexp;
  3641.         }
  3642.     }
  3643.     void description(void)
  3644.     {
  3645.         this.title="Bezier Curve";
  3646.         this.helpfile="lkm-help\lkm-bezier.html";
  3647.    
  3648.         z0.caption="1st anchor point";
  3649.         z0.default=(1.0,0.0);
  3650.         z0.hint="Curve starts at this point.";
  3651.   
  3652.    
  3653.         z1.caption="1st control point";
  3654.         z1.default=(1.0,1.0);
  3655.         z1.hint="Influences the shape of the curve.";
  3656.   
  3657.    
  3658.         z2.caption="2nd control point";
  3659.         z2.default=(0.0,0.0);
  3660.         z2.hint="Influences the shape of the curve.";
  3661.   
  3662.    
  3663.         z3.caption="2nd anchor point";
  3664.         z3.default=(0.0,1.0);
  3665.         z3.hint="Curve ends at this point.";
  3666.   
  3667.    
  3668.         dt.caption="step size";
  3669.         dt.default=0.1;
  3670.         dt.hint="Decrease for smoother line, increase to see dots.  Should be between 0 & 1.";
  3671.         dt.min=0.0;
  3672.         dt.max=1.0;
  3673.   
  3674.    
  3675.         nexp.caption="power";
  3676.         nexp.default=0.1;
  3677.         nexp.min=0.0;
  3678.         nexp.hint="Decrease to make thinner lines. Use with 'minimum distance' coloring.";
  3679.   
  3680.    
  3681.         colorby.caption="color by";
  3682.         colorby.default=0;
  3683.         colorby.enum="minimum distance\niteration @ min\nangle @ min\nshow curve";
  3684.   
  3685.     }
  3686. }
  3687.  
  3688.  
  3689. rose-range-lite {
  3690. int rangeiter;
  3691. real rminfac;
  3692. parameter real scale;
  3693. parameter real rangewidth;
  3694. real rmaxfac;
  3695. real rz;
  3696. real tz;
  3697. real twopi;
  3698. real rmin;
  3699. real rmax;
  3700. real r1;
  3701. real rn;
  3702. real t1;
  3703. real tn;
  3704. real rotangle;
  3705. parameter real rot;
  3706. parameter real ac;
  3707. parameter real bc;
  3708. parameter real as;
  3709. parameter real bs;
  3710. parameter complex curvecenter;
  3711. parameter int colorby;
  3712.  
  3713.     void init(void)
  3714.     {
  3715.         rangeiter=0;
  3716.         rminfac=scale*(1.0-0.5*rangewidth);
  3717.         rmaxfac=scale*(1.0+0.5*rangewidth);
  3718.         rz=0.0;
  3719.         tz=0.0;
  3720.         twopi=2.0*pi;
  3721.         rmin=0.0;
  3722.         rmax=0.0;
  3723.         r1=0.0;
  3724.         rn=0.0;
  3725.         t1=0.0;
  3726.         tn=0.0;
  3727.         rotangle=-rot/180.0*pi;
  3728.     }
  3729.     void loop(void)
  3730.     {
  3731.         tz=atan2(z)+rotangle;
  3732.         rz=ac*cos(bc*tz)+as*sin(bs*tz);
  3733.         rmin=rz*rminfac;
  3734.         rmax=rz*rmaxfac;
  3735.         rz=cabs(z-curvecenter);
  3736.         if (((rz>=rmin)&&(rz<=rmax)))
  3737.         {
  3738.             rangeiter=rangeiter+1;
  3739.             rn=(rz-rmin)/(rmax-rmin);
  3740.             tn=tz;
  3741.             if ((rangeiter==1))
  3742.             {
  3743.                 r1=rn;
  3744.                 t1=tn;
  3745.             }
  3746.         }
  3747.     }
  3748.     void final(void)
  3749.     {
  3750.         if ((rangeiter==0))
  3751.         {
  3752.             solid=true;
  3753.         }
  3754.         else
  3755.         {
  3756.  
  3757.             if ((colorby==0))
  3758.             {// first mag
  3759.                 index=r1;
  3760.             }
  3761.             else if ((colorby==1))
  3762.             {// last mag
  3763.                 index=rn;
  3764.             }
  3765.             else if ((colorby==2))
  3766.             {// first angle
  3767.                 if ((t1<0.0))
  3768.                 {
  3769.                     t1=t1+twopi;
  3770.                 }
  3771.                 t1=t1/twopi;
  3772.                 index=t1;
  3773.             }
  3774.             else if ((colorby==3))
  3775.             {// last angle
  3776.                 if ((tn<0.0))
  3777.                 {
  3778.                     tn=tn+twopi;
  3779.                 }
  3780.                 tn=tn/twopi;
  3781.                 index=tn;
  3782.             }
  3783.         }
  3784.     }
  3785.     void description(void)
  3786.     {
  3787.         this.title="Rose Range Lite";
  3788.         this.helpfile="lkm-help\lkm-roserange.html";
  3789.    
  3790.         scale.caption="range scale";
  3791.         scale.default=1.0;
  3792.   
  3793.    
  3794.         rangewidth.caption="range width";
  3795.         rangewidth.default=0.1;
  3796.   
  3797.    
  3798.         colorby.caption="color by";
  3799.         colorby.default=3;
  3800.         colorby.enum="first magnitude\nlast magnitude\nfirst angle\nlast angle";
  3801.   
  3802.    
  3803.         ac.caption="cos amplitude";
  3804.         ac.default=1.0;
  3805.   
  3806.    
  3807.         bc.caption="cos frequency";
  3808.         bc.default=3.0;
  3809.   
  3810.    
  3811.         as.caption="sin amplitude";
  3812.         as.default=0.0;
  3813.   
  3814.    
  3815.         bs.caption="sin frequency";
  3816.         bs.default=0.0;
  3817.   
  3818.    
  3819.         curvecenter.caption="curve center";
  3820.         curvecenter.default=(0.0,0.0);
  3821.   
  3822.    
  3823.         rot.caption="rotation angle";
  3824.         rot.default=0.0;
  3825.         rot.hint="degrees";
  3826.   
  3827.     }
  3828. }
  3829.  
  3830.  
  3831. spiral { // Kerry Mitchell 13may00
  3832. //
  3833. // Colors by the orbit's closest approach to a user-defined spiral
  3834. //
  3835. // The spiral is given as theta = f(r), where r is the distance from the
  3836. // center of the spiral.
  3837. //
  3838. real r;
  3839. real rmin;
  3840. real tspiral;
  3841. complex zspiral;
  3842. real rotangle;
  3843. parameter real rot;
  3844. int iter;
  3845. int itermin;
  3846. complex zmin;
  3847. parameter complex spiralcenter;
  3848. parameter real Parm_rmin;
  3849. parameter real rmax;
  3850. parameter real rpower;
  3851. parameter real spiralfactor;
  3852. parameter int colorby;
  3853.  
  3854.     void init(void)
  3855.     {
  3856.         r=0.0;
  3857.         rmin=1e20;
  3858.         tspiral=0.0;
  3859.         zspiral=(0,0);
  3860.         rotangle=rot/180.0*pi;
  3861.         iter=0;
  3862.         itermin=0;
  3863.         zmin=(0,0);
  3864.     }
  3865.     void loop(void)
  3866.     {
  3867.         iter=iter+1;
  3868. //
  3869. // find r, the distance from the center of the spiral
  3870. //   then determine the angle as a function of r
  3871. //
  3872.         r=cabs(z-spiralcenter);
  3873.         if (((r>=Parm_rmin)&&(r<=rmax)))
  3874.         {
  3875.             tspiral=real(rfunc(r))^rpower;
  3876.             tspiral=spiralfactor*tspiral+rotangle;
  3877. //
  3878. // find the x- and y-coordinates of the point on the spiral
  3879. //   with the same r value as the current iterate
  3880. //
  3881.             zspiral=r*(cos(tspiral)+flip(sin(tspiral)))+spiralcenter;
  3882. //
  3883. // check the difference between the spiral and the current point
  3884. //   update the minimum values
  3885. //
  3886.             r=cabs(z-zspiral);
  3887.             if ((r<rmin))
  3888.             {
  3889.                 rmin=r;
  3890.                 itermin=iter;
  3891.                 zmin=z;
  3892.             }
  3893.         }
  3894.     }
  3895.     void final(void)
  3896.     {
  3897.         if ((colorby==1))
  3898.         {// iteration number at minimum
  3899.             index=itermin/maxiter;
  3900.         }
  3901.         else if ((colorby==2))
  3902.         {// angle at minimum
  3903.             tspiral=atan2(zmin)/pi;
  3904.             if ((tspiral<0.0))
  3905.             {
  3906.                 tspiral=tspiral+2.0;
  3907.             }
  3908.             index=0.5*tspiral;
  3909.         }
  3910.         else if ((colorby==3))
  3911.         {// magnitude at minimum
  3912.             index=cabs(zmin);
  3913.         }
  3914.         else if ((colorby==4))
  3915.         {// draw spiral
  3916.             r=cabs(pixel-spiralcenter);
  3917.             if (((r>=Parm_rmin)&&(r<=rmax)))
  3918.             {
  3919.                 tspiral=real(rfunc(r))^rpower;
  3920.                 tspiral=spiralfactor*tspiral+rotangle;
  3921.                 zspiral=r*(cos(tspiral)+flip(sin(tspiral)))+spiralcenter;
  3922.                 r=cabs(pixel-zspiral);
  3923.             }
  3924.             index=r;
  3925.         }
  3926.         else
  3927.         {
  3928.                        // minimum distance
  3929.             index=rmin;
  3930.         }
  3931.     }
  3932.     void description(void)
  3933.     {
  3934.         this.title="Spiral";
  3935.         this.helpfile="lkm-help\lkm-spiral.html";
  3936.    
  3937.         spiralfactor.caption="spiral factor";
  3938.         spiralfactor.default=8.0;
  3939.         spiralfactor.hint="Increase to make the spiral tighter; use negative values to reverse the direction.";
  3940.   
  3941.    
  3942.         rpower.caption="spiral power";
  3943.         rpower.default=1.0;
  3944.         rpower.hint="Increase in magnitude to make the spiral tighter; try negative values, too.";
  3945.   
  3946.    
  3947.         spiralcenter.caption="spiral center";
  3948.         spiralcenter.default=(0,0);
  3949.   
  3950.    
  3951.         rot.caption="rotation angle";
  3952.         rot.default=0.0;
  3953.         rot.hint="degrees";
  3954.   
  3955.    
  3956.         Parm_rmin.caption="minimum r";
  3957.         Parm_rmin.default=0.0;
  3958.         Parm_rmin.hint="To keep the spiral from going too far in.";
  3959.   
  3960.    
  3961.         rmax.caption="maximum r";
  3962.         rmax.default=1e20;
  3963.         rmax.hint="To keep the spiral from going too far out.";
  3964.   
  3965.    
  3966.         colorby.caption="color by";
  3967.         colorby.default=0;
  3968.         colorby.enum="min. distance\niteration @ min\nangle @ min\nmagnitude @ min\ndraw spiral";
  3969.   
  3970.    
  3971.         rfunc.caption="r function";
  3972.         rfunc.default="ident" ;
  3973.         rfunc.hint="theta = size * [f(r)]^power";
  3974.   
  3975.     }
  3976. }
  3977.  
  3978.  
  3979. grid { // Kerry Mitchell 30aug2000
  3980. //
  3981. // Colors by the orbit's closest approach to a rectangular grid
  3982. //
  3983. real cerr;
  3984. real cerrmin;
  3985. real Var_x;
  3986. real Var_y;
  3987. real t;
  3988. int iter;
  3989. int itermin;
  3990. complex zmin;
  3991. parameter real tdeg;
  3992. complex rot;
  3993. complex temp;
  3994. parameter complex gridcenter;
  3995. parameter real Parm_width;
  3996. parameter real Parm_height;
  3997. parameter int colorby;
  3998.  
  3999.     void init(void)
  4000.     {
  4001.         cerr=0.0;
  4002.         cerrmin=1.0e12;
  4003.         Var_x=0.0;
  4004.         Var_y=0.0;
  4005.         t=0.0;
  4006.         iter=0;
  4007.         itermin=0;
  4008.         zmin=(0.0,0.0);
  4009.         t=tdeg*pi/180;
  4010.         rot=cos(t)-flip(sin(t));
  4011.     }
  4012.     void loop(void)
  4013.     {
  4014.         iter=iter+1;
  4015.         temp=(z-gridcenter)*rot;
  4016.         Var_x=(real(temp)%Parm_width)/Parm_width;
  4017.         Var_x=(Var_x+2)%1;
  4018.         Var_x=2*abs(0.5-Var_x);
  4019.         Var_y=(imag(temp)%Parm_height)/Parm_height;
  4020.         Var_y=(Var_y+2)%1;
  4021.         Var_y=2*abs(0.5-Var_y);
  4022.         if ((Var_x<Var_y))
  4023.         {
  4024.             cerr=Var_y;
  4025.         }
  4026.         else
  4027.         {
  4028.  
  4029.             cerr=Var_x;
  4030.         }
  4031.         if ((cerr<cerrmin))
  4032.         {
  4033.             cerrmin=cerr;
  4034.             zmin=z;
  4035.             itermin=iter;
  4036.         }
  4037.     }
  4038.     void final(void)
  4039.     {
  4040.         if ((colorby==0))
  4041.         {// minimum distance
  4042.             index=cerrmin;
  4043.         }
  4044.         else if ((colorby==1))
  4045.         {// iteration @ min
  4046.             index=0.01*itermin;
  4047.         }
  4048.         else if ((colorby==2))
  4049.         {// angle @ min
  4050.             t=atan2(zmin)/pi;
  4051.             if ((t<0.0))
  4052.             {
  4053.                 t=t+2.0;
  4054.             }
  4055.             index=0.5*t;
  4056.         }
  4057.     }
  4058.     void description(void)
  4059.     {
  4060.         this.title="Grid";
  4061.    
  4062.         gridcenter.caption="center";
  4063.         gridcenter.default=(0.0,0.0);
  4064.   
  4065.    
  4066.         Parm_height.caption="height";
  4067.         Parm_height.default=1.0;
  4068.         Parm_height.hint="height of each cell";
  4069.   
  4070.    
  4071.         Parm_width.caption="width";
  4072.         Parm_width.default=1.0;
  4073.         Parm_width.hint="width of each cell";
  4074.   
  4075.    
  4076.         tdeg.caption="rotation, deg";
  4077.         tdeg.default=0.0;
  4078.   
  4079.    
  4080.         colorby.caption="color by";
  4081.         colorby.default=0;
  4082.         colorby.enum="minimum distance\niteration @ min\nangle @ min";
  4083.   
  4084.     }
  4085. }
  4086.  
  4087.  
  4088. single-truchet { // Kerry Mitchell 08nov00
  4089. //
  4090. // Colors the fractal randomly with truchet tiles
  4091. //
  4092. real Var_x;
  4093. real Var_y;
  4094. int intx;
  4095. int inty;
  4096. real r;
  4097. real r0;
  4098. real r1;
  4099. real rmax;
  4100. parameter real n;
  4101. parameter real Parm_width;
  4102. int tiletype;
  4103. int randint;
  4104. int modbase;
  4105. int multiplier;
  4106. int offset;
  4107. int niter;
  4108. int randiter;
  4109. parameter real tdeg;
  4110. complex scale;
  4111. parameter real scalefac;
  4112. complex temp;
  4113. parameter complex shift;
  4114. parameter real seed;
  4115.  
  4116.     void init(void)
  4117.     {
  4118.         Var_x=0.0;
  4119.         Var_y=0.0;
  4120.         intx=0;
  4121.         inty=0;
  4122.         r=0.0;
  4123.         r0=0.0;
  4124.         r1=0.0;
  4125.         rmax=0.5*(2^(1/n)-1)*Parm_width;
  4126.         tiletype=0;
  4127.         randint=0;
  4128.         modbase=2147483647;
  4129.         multiplier=1103515245;
  4130.         offset=12345;
  4131.         niter=0;
  4132.         randiter=0;
  4133.         r=-tdeg*pi/180;
  4134.         scale=(cos(r)+flip(sin(r)))/scalefac;
  4135.     }
  4136.     void loop(void)
  4137.     {
  4138.     }
  4139.     void final(void)
  4140.     {
  4141. //
  4142. // find fractional x and y from final z
  4143. //
  4144.         temp=z*scale-shift;
  4145.         Var_x=real(temp)+0.5;
  4146.         Var_y=imag(temp)+0.5;
  4147.         intx=round(Var_x);
  4148.         inty=round(Var_y);
  4149.         r=Var_x-intx;
  4150.         if ((r<0.0))
  4151.         {
  4152.             Var_x=1+r;
  4153.         }
  4154.         else
  4155.         {
  4156.  
  4157.             Var_x=r;
  4158.         }
  4159.         r=Var_y-inty;
  4160.         if ((r<0.0))
  4161.         {
  4162.             Var_y=1+r;
  4163.         }
  4164.         else
  4165.         {
  4166.  
  4167.             Var_y=r;
  4168.         }
  4169. //
  4170. // pick tile type
  4171. //
  4172.         if ((seed==0))
  4173.         {// force type 0
  4174.             tiletype=0;
  4175.         }
  4176.         else if ((seed==1))
  4177.         {// force type 1
  4178.             tiletype=1;
  4179.         }
  4180.         else
  4181.         {
  4182.                        // choose randomly
  4183.             intx=round(real(temp));
  4184.             inty=round(imag(temp));
  4185.             niter=abs(intx+inty+intx*inty);
  4186.             randint=seed+niter;
  4187.             randiter=0;
  4188.             while ((randiter<niter))
  4189.             {
  4190.                 randiter=randiter+1;
  4191.                 randint=(randint*multiplier+offset)%modbase;
  4192.             }
  4193.             tiletype=randint%2;
  4194.         }
  4195. //
  4196. // determine radial distances based on tile type
  4197. //
  4198.         if ((tiletype==1))
  4199.         {
  4200.             r0=(abs(Var_x)^n+abs(Var_y)^n)^(1/n);
  4201.             r1=(abs(Var_x-1)^n+abs(Var_y-1)^n)^(1/n);
  4202.         }
  4203.         else
  4204.         {
  4205.  
  4206.             r0=(abs(Var_x-1)^n+abs(Var_y)^n)^(1/n);
  4207.             r1=(abs(Var_x)^n+abs(Var_y-1)^n)^(1/n);
  4208.         }
  4209. //
  4210. // find radial distance and set index color
  4211. //
  4212. //   solid background
  4213. //
  4214.         solid=true;
  4215. //
  4216. //   gradation inside arc 0
  4217. //
  4218.         r=abs(r0-0.5)/rmax;
  4219.         if ((r<1))
  4220.         {
  4221.             solid=false;
  4222.             index=r;
  4223.         }
  4224. //
  4225. //   gradation inside arc 1
  4226. //
  4227.         r=abs(r1-0.5)/rmax;
  4228.         if ((r<1))
  4229.         {
  4230.             solid=false;
  4231.             index=r;
  4232.         }
  4233.     }
  4234.     void description(void)
  4235.     {
  4236.         this.title="Single Truchet";
  4237.    
  4238.         shift.caption="shift";
  4239.         shift.default=(0,0);
  4240.         shift.hint="Use to shift the center of the tiling pattern.";
  4241.   
  4242.    
  4243.         scalefac.caption="size";
  4244.         scalefac.default=1.0;
  4245.         scalefac.hint="Increase or decrease the size of the pattern.";
  4246.   
  4247.    
  4248.         tdeg.caption="rotation";
  4249.         tdeg.default=0.0;
  4250.         tdeg.hint="Rotate the pattern, +ccw, -cw, in degrees.";
  4251.   
  4252.    
  4253.         Parm_width.caption="arc width";
  4254.         Parm_width.default=0.5;
  4255.         Parm_width.min=0.0;
  4256.         Parm_width.max=1.0;
  4257.         Parm_width.hint="a fraction from 0 to 1";
  4258.   
  4259.    
  4260.         n.caption="exponent";
  4261.         n.default=2.0;
  4262.         n.min=0.0;
  4263.         n.hint="Use 2 for circular arcs, 1 for straight lines, and less than 1 for astroid arcs.";
  4264.   
  4265.    
  4266.         seed.caption="random seed";
  4267.         seed.default=12345;
  4268.         seed.min=0;
  4269.         seed.hint="Use 0 or 1 to force either tile; otherwise, use a large, odd integer.";
  4270.   
  4271.     }
  4272. }
  4273.  
  4274.  
  4275. double-truchet { // Kerry Mitchell 12nov2000
  4276. //
  4277. // Colors the fractal randomly with truchet tiles using 4 arcs
  4278. //
  4279. real Var_x;
  4280. real Var_y;
  4281. int intx;
  4282. int inty;
  4283. real r;
  4284. real r0;
  4285. real r1;
  4286. real r2;
  4287. real r3;
  4288. real ra;
  4289. real rb;
  4290. real rc;
  4291. real rd;
  4292. real rmax;
  4293. parameter real Parm_width;
  4294. real rcutoff;
  4295. int tiletype;
  4296. int randint;
  4297. int modbase;
  4298. int multiplier;
  4299. int offset;
  4300. int niter;
  4301. int randiter;
  4302. int seedy;
  4303. parameter real tdeg;
  4304. complex scale;
  4305. parameter real scalefac;
  4306. real recipn;
  4307. parameter real n;
  4308. real r2o2;
  4309. real omr2o2;
  4310. int overtype;
  4311. complex temp;
  4312. parameter complex shift;
  4313. parameter real seed;
  4314. parameter bool nozero;
  4315.  
  4316.     void init(void)
  4317.     {
  4318.         Var_x=0.0;
  4319.         Var_y=0.0;
  4320.         intx=0;
  4321.         inty=0;
  4322.         r=0.0;
  4323.         r0=0.0;
  4324.         r1=0.0;
  4325.         r2=0.0;
  4326.         r3=0.0;
  4327.         ra=0.0;
  4328.         rb=0.0;
  4329.         rc=0.0;
  4330.         rd=0.0;
  4331.         rmax=Parm_width;
  4332.         rcutoff=0.0;
  4333.         tiletype=0;
  4334.         randint=0;
  4335.         modbase=32768;
  4336.         multiplier=13821;
  4337.         offset=0;
  4338.         niter=0;
  4339.         randiter=0;
  4340.         seedy=0;
  4341.         r=-tdeg*pi/180;
  4342.         scale=(cos(r)+flip(sin(r)))/scalefac;
  4343.         recipn=1/n;
  4344.         r2o2=0.5*sqrt(2);
  4345.         omr2o2=1-0.5*sqrt(2);
  4346.         overtype=0;
  4347.     }
  4348.     void loop(void)
  4349.     {
  4350.     }
  4351.     void final(void)
  4352.     {
  4353. //
  4354. // find fractional x and y from final z
  4355. //
  4356.         temp=z*scale-shift;
  4357.         Var_x=real(temp)+0.5;
  4358.         Var_y=imag(temp)+0.5;
  4359.         intx=round(Var_x);
  4360.         inty=round(Var_y);
  4361.         r=Var_x-intx;
  4362.         if ((r<0.0))
  4363.         {
  4364.             Var_x=1+r;
  4365.         }
  4366.         else
  4367.         {
  4368.  
  4369.             Var_x=r;
  4370.         }
  4371.         r=Var_y-inty;
  4372.         if ((r<0.0))
  4373.         {
  4374.             Var_y=1+r;
  4375.         }
  4376.         else
  4377.         {
  4378.  
  4379.             Var_y=r;
  4380.         }
  4381. //
  4382. // pick tile type
  4383. //
  4384.         if ((seed==0))
  4385.         {// force type 0
  4386.             tiletype=0;
  4387.         }
  4388.         else if ((seed==1))
  4389.         {// force type 1
  4390.             tiletype=1;
  4391.         }
  4392.         else if ((seed==2))
  4393.         {// force type 2
  4394.             tiletype=2;
  4395.         }
  4396.         else if ((seed==3))
  4397.         {// force type 3
  4398.             tiletype=3;
  4399.         }
  4400.         else
  4401.         {
  4402.                        // choose randomly
  4403.             niter=0;
  4404.             seedy=2*seed+1;
  4405.             intx=round(real(temp))*2;
  4406.             if ((intx<=0))
  4407.             {
  4408.                 intx=1-intx;
  4409.                 niter=niter+1;
  4410.             }
  4411.             inty=round(imag(temp))*2;
  4412.             if ((inty<=0))
  4413.             {
  4414.                 inty=1-inty;
  4415.                 niter=niter+2;
  4416.             }
  4417.             niter=niter+intx+inty+intx*inty;
  4418.             randint=seedy+niter;
  4419.             randiter=0;
  4420.             while ((randiter<niter))
  4421.             {
  4422.                 randiter=randiter+1;
  4423.                 randint=(randint*multiplier+offset)%modbase;
  4424.             }
  4425.             tiletype=(randint%seedy)%4;
  4426.             if ((nozero==true))
  4427.             {
  4428.                 tiletype=((randint%seedy)%3)+1;
  4429.             }
  4430.             randint=(randint*multiplier+offset)%modbase;
  4431.             overtype=(randint%seedy)%4;
  4432.         }
  4433. //
  4434. // determine radial distances based on tile type
  4435. //
  4436.         if ((tiletype==1))
  4437.         {
  4438.             ra=((abs(Var_x-0.5))^n+(abs(Var_y))^n)^recipn;
  4439.             rb=((abs(Var_x-1))^n+(abs(Var_y-0.5))^n)^recipn;
  4440.             rc=((abs(Var_x-0.5))^n+(abs(Var_y-1))^n)^recipn;
  4441.             rd=((abs(Var_x))^n+(abs(Var_y-0.5))^n)^recipn;
  4442.             rcutoff=r2o2-0.5;
  4443.         }
  4444.         else if ((tiletype==2))
  4445.         {
  4446.             ra=((abs(Var_x))^n+(abs(Var_y))^n)^recipn;
  4447.             rb=((abs(Var_x-1))^n+(abs(Var_y))^n)^recipn;
  4448.             rc=((abs(Var_x-1))^n+(abs(Var_y-1))^n)^recipn;
  4449.             rd=((abs(Var_x))^n+(abs(Var_y-1))^n)^recipn;
  4450.             rcutoff=omr2o2;
  4451.         }
  4452.         else if ((tiletype==3))
  4453.         {
  4454.             ra=((abs(Var_x))^n+(abs(Var_y))^n)^recipn;
  4455.             rb=((abs(Var_x-1))^n+(abs(Var_y-1))^n)^recipn;
  4456.             rc=((abs(Var_x-1))^n+(abs(Var_y))^n)^recipn;
  4457.             rd=((abs(Var_x))^n+(abs(Var_y-1))^n)^recipn;
  4458.             rcutoff=r2o2;
  4459.         }
  4460.         else
  4461.         {
  4462.  
  4463.             ra=abs(Var_x-omr2o2);
  4464.             rb=abs(Var_y-omr2o2);
  4465.             rc=abs(Var_x-r2o2);
  4466.             rd=abs(Var_y-r2o2);
  4467.             rcutoff=0;
  4468.         }
  4469. //
  4470. // determine which arc is over which
  4471. //
  4472.         if ((overtype==1))
  4473.         {
  4474.             r1=ra;
  4475.             r2=rb;
  4476.             r3=rc;
  4477.             r0=rd;
  4478.         }
  4479.         else if ((overtype==2))
  4480.         {
  4481.             r2=ra;
  4482.             r3=rb;
  4483.             r0=rc;
  4484.             r1=rd;
  4485.         }
  4486.         else if ((overtype==2))
  4487.         {
  4488.             r3=ra;
  4489.             r0=rb;
  4490.             r1=rc;
  4491.             r2=rd;
  4492.         }
  4493.         else
  4494.         {
  4495.  
  4496.             r0=ra;
  4497.             r1=rb;
  4498.             r2=rc;
  4499.             r3=rd;
  4500.         }
  4501. //
  4502. // find radial distance and set index color
  4503. //
  4504. //   solid background
  4505. //
  4506.         solid=true;
  4507. //
  4508. //   gradation inside arc 0
  4509. //
  4510.         r=abs(r0-rcutoff)/rmax;
  4511.         if ((r<=1))
  4512.         {
  4513.             solid=false;
  4514.             index=r;
  4515.         }
  4516. //
  4517. //   gradation inside arc 1
  4518. //
  4519.         r=abs(r1-rcutoff)/rmax;
  4520.         if ((r<=1))
  4521.         {
  4522.             solid=false;
  4523.             index=r;
  4524.         }
  4525. //
  4526. //   gradation inside arc 2
  4527. //
  4528.         r=abs(r2-rcutoff)/rmax;
  4529.         if ((r<=1))
  4530.         {
  4531.             solid=false;
  4532.             index=r;
  4533.         }
  4534. //
  4535. //   gradation inside arc 3
  4536. //
  4537.         r=abs(r3-rcutoff)/rmax;
  4538.         if ((r<=1))
  4539.         {
  4540.             solid=false;
  4541.             index=r;
  4542.         }
  4543.     }
  4544.     void description(void)
  4545.     {
  4546.         this.title="Double Truchet";
  4547.    
  4548.         shift.caption="shift";
  4549.         shift.default=(0,0);
  4550.         shift.hint="Use to shift the center of the tiling pattern.";
  4551.   
  4552.    
  4553.         scalefac.caption="size";
  4554.         scalefac.default=1.0;
  4555.         scalefac.hint="Increase or decrease the size of the pattern.";
  4556.   
  4557.    
  4558.         tdeg.caption="rotation";
  4559.         tdeg.default=0.0;
  4560.         tdeg.hint="Rotate the pattern, +ccw, -cw, in degrees.";
  4561.   
  4562.    
  4563.         Parm_width.caption="arc width";
  4564.         Parm_width.default=0.15;
  4565.         Parm_width.min=0.0;
  4566.         Parm_width.max=1.0;
  4567.         Parm_width.hint="From 0 to 1.";
  4568.   
  4569.    
  4570.         n.caption="exponent";
  4571.         n.default=2.0;
  4572.         n.min=0.0;
  4573.         n.hint="Use 2 for circular arcs, 1 for straight lines, and less than 1 for astroid arcs.";
  4574.   
  4575.    
  4576.         seed.caption="random seed";
  4577.         seed.default=123;
  4578.         seed.min=0;
  4579.         seed.hint="Use 0, 1, 2, or 3 to force either tile; otherwise, use a large integer.";
  4580.   
  4581.    
  4582.         nozero.caption="exclude tile 0?";
  4583.         nozero.default=false;
  4584.         nozero.hint="Check to exclude the straight arc tile.";
  4585.   
  4586.     }
  4587. }
  4588.  
  4589.  
  4590. string-art-rose { // Kerry Mitchell 21mar01
  4591. //
  4592. // "Sting Art" coloring, in which the "nails" are placed around
  4593. // a rose curve.
  4594. //
  4595. real Var_x;
  4596. real Var_y;
  4597. real theta;
  4598. real theta0;
  4599. parameter real t0deg;
  4600. real dtheta;
  4601. parameter real m;
  4602. parameter real n;
  4603. real r;
  4604. real rmin;
  4605. real rlast;
  4606. real rfirst;
  4607. complex t;
  4608. complex z1;
  4609. complex z2;
  4610. complex zfirst;
  4611. complex zlast;
  4612. parameter real trdeg;
  4613. complex rot;
  4614. complex zrot;
  4615. int itheta;
  4616. int nin;
  4617. parameter real ac;
  4618. parameter real bc;
  4619. parameter real as;
  4620. parameter real bs;
  4621. parameter complex curvecenter;
  4622. parameter real rangewidth;
  4623. parameter int colorby;
  4624. parameter real power;
  4625.  
  4626.     void init(void)
  4627.     {
  4628.         Var_x=0.0;
  4629.         Var_y=0.0;
  4630.         theta=0.0;
  4631.         theta0=t0deg*pi/180;
  4632.         dtheta=m/n*2*pi;
  4633.         r=0.0;
  4634.         rmin=1e20;
  4635.         rlast=0.0;
  4636.         rfirst=0.0;
  4637.         t=(0,0);
  4638.         z1=(0,0);
  4639.         z2=(0,0);
  4640.         zfirst=(0,0);
  4641.         zlast=(0,0);
  4642.         theta=trdeg*pi/180;
  4643.         rot=cos(theta)-flip(sin(theta));
  4644.         zrot=(0,0);
  4645.         itheta=0;
  4646.         nin=0;
  4647.     }
  4648.     void loop(void)
  4649.     {
  4650.         zrot=z*rot;// rotate z instead of the curve
  4651. //
  4652. // set up 1st line endpoint
  4653. //
  4654.         theta=theta0;
  4655.         r=ac*cos(bc*theta)+as*sin(bs*theta);
  4656.         z1=r*(cos(theta)+flip(sin(theta)))+curvecenter;
  4657. //
  4658. // loop through the rest of the points on the curve:
  4659. // next point in the loop becomes the new 2nd line endpoint
  4660. //
  4661.         itheta=0;
  4662.         while ((itheta<n))
  4663.         {
  4664.             itheta=itheta+1;
  4665.             theta=itheta*dtheta+theta0;
  4666.             r=ac*cos(bc*theta)+as*sin(bs*theta);
  4667.             z2=r*(cos(theta)+flip(sin(theta)))+curvecenter;
  4668. //
  4669. // find distance from z to the line
  4670. //
  4671.             t=(zrot-z1)/(z2-z1);
  4672.             Var_x=real(t);
  4673.             Var_y=sqr(imag(t));
  4674.             if ((Var_x<0.0))
  4675.             {
  4676.                 r=sqr(Var_x)+Var_y;
  4677.             }
  4678.             else if ((Var_x>1.0))
  4679.             {
  4680.                 r=sqr(Var_x-1.0)+Var_y;
  4681.             }
  4682.             else
  4683.             {
  4684.  
  4685.                 r=Var_y;
  4686.             }
  4687.             r=sqrt(r)*cabs(z2-z1);// scale lines to have same width
  4688. //
  4689. // check to see if this point is closer to line, or falls in range
  4690. //
  4691.             if ((r<rmin))
  4692.             {
  4693.                 rmin=r;
  4694.             }
  4695.             if ((r<=rangewidth))
  4696.             {
  4697.                 nin=nin+1;
  4698.                 rlast=r;
  4699.                 zlast=z;
  4700.                 if ((nin==1))
  4701.                 {
  4702.                     rfirst=r;
  4703.                     zfirst=z;
  4704.                 }
  4705.             }
  4706.             z1=z2;// update 1st endpoint
  4707.         }
  4708.     }
  4709.     void final(void)
  4710.     {
  4711.         if ((colorby==1))
  4712.         {// first mag
  4713.             if ((nin==0))
  4714.             {
  4715.                 solid=true;
  4716.             }
  4717.             else
  4718.             {
  4719.  
  4720.                 index=rfirst/rangewidth;
  4721.             }
  4722.         }
  4723.         else if ((colorby==2))
  4724.         {// first angle
  4725.             if ((nin==0))
  4726.             {
  4727.                 solid=true;
  4728.             }
  4729.             else
  4730.             {
  4731.  
  4732.                 theta=atan2(zfirst)/pi;
  4733.                 if ((theta<0.0))
  4734.                 {
  4735.                     theta=theta+2;
  4736.                 }
  4737.                 index=theta/2;
  4738.             }
  4739.         }
  4740.         else if ((colorby==3))
  4741.         {// last mag
  4742.             if ((nin==0))
  4743.             {
  4744.                 solid=true;
  4745.             }
  4746.             else
  4747.             {
  4748.  
  4749.                 index=rlast/rangewidth;
  4750.             }
  4751.         }
  4752.         else if ((colorby==4))
  4753.         {// last angle
  4754.             if ((nin==0))
  4755.             {
  4756.                 solid=true;
  4757.             }
  4758.             else
  4759.             {
  4760.  
  4761.                 theta=atan2(zlast)/pi;
  4762.                 if ((theta<0.0))
  4763.                 {
  4764.                     theta=theta+2;
  4765.                 }
  4766.                 index=theta/2;
  4767.             }
  4768.         }
  4769.         else
  4770.         {
  4771.                        // minimum dist.
  4772.             index=rmin^power;
  4773.         }
  4774.     }
  4775.     void description(void)
  4776.     {
  4777.         this.title="Rose Curve String Art";
  4778.    
  4779.         n.caption="# of points";
  4780.         n.default=7;
  4781.         n.hint="Both #'s should be coprime, like 7 & 3 or 16 & 9.";
  4782.   
  4783.    
  4784.         m.caption="# skipped";
  4785.         m.default=3;
  4786.         m.hint="Both #'s should be coprime, like 7 & 3 or 16 & 9.";
  4787.   
  4788.    
  4789.         curvecenter.caption="curve center";
  4790.         curvecenter.default=(0,0);
  4791.   
  4792.    
  4793.         t0deg.caption="line rotation";
  4794.         t0deg.default=0.0;
  4795.         t0deg.hint="Rotates the start of the lines, in degrees, +ccw.";
  4796.   
  4797.    
  4798.         trdeg.caption="curve rotation";
  4799.         trdeg.default=0.0;
  4800.         trdeg.hint="Rotates the curve, in degrees, +ccw.";
  4801.   
  4802.    
  4803.         ac.caption="cosine amplitude";
  4804.         ac.default=1.0;
  4805.   
  4806.    
  4807.         bc.caption="cosine frequency";
  4808.         bc.default=2.0;
  4809.   
  4810.    
  4811.         as.caption="sine amplitude";
  4812.         as.default=0.0;
  4813.   
  4814.    
  4815.         bs.caption="sine frequency";
  4816.         bs.default=0.0;
  4817.   
  4818.    
  4819.         colorby.caption="color by:";
  4820.         colorby.default=0;
  4821.         colorby.enum="minimum dist.\nfirst mag\nfirst angle\nlast mag\nlast angle";
  4822.   
  4823.    
  4824.         rangewidth.caption="range width";
  4825.         rangewidth.default=0.1;
  4826.         rangewidth.hint="Use with all but 'minimum dist.' 'color by:' choices.";
  4827.   
  4828.    
  4829.         power.caption="power";
  4830.         power.default=1.0;
  4831.         power.hint="Use with color density to control line thickness.  Use with 'minimum dist.' 'color by:' choice.";
  4832.   
  4833.     }
  4834. }
  4835.  
  4836.  
  4837. string-art-astroid { // Kerry Mitchell 21mar2001
  4838. //
  4839. // "Sting Art" coloring, in which the "nails" are placed around
  4840. // an astroid curve.
  4841. //
  4842. real Var_x;
  4843. real Var_y;
  4844. real theta;
  4845. real theta0;
  4846. parameter real t0deg;
  4847. real dtheta;
  4848. parameter real m;
  4849. parameter real n;
  4850. real r;
  4851. real rmin;
  4852. real rlast;
  4853. real rfirst;
  4854. real fac;
  4855. real recipn;
  4856. parameter real astroidn;
  4857. complex t;
  4858. complex z1;
  4859. complex z2;
  4860. complex zfirst;
  4861. complex zlast;
  4862. parameter real trdeg;
  4863. complex rot;
  4864. complex zrot;
  4865. int itheta;
  4866. int nin;
  4867. parameter real astroida;
  4868. parameter complex curvecenter;
  4869. parameter real rangewidth;
  4870. parameter int colorby;
  4871. parameter real power;
  4872.  
  4873.     void init(void)
  4874.     {
  4875.         Var_x=0.0;
  4876.         Var_y=0.0;
  4877.         theta=0.0;
  4878.         theta0=t0deg*pi/180;
  4879.         dtheta=m/n*2*pi;
  4880.         r=0.0;
  4881.         rmin=1e20;
  4882.         rlast=0.0;
  4883.         rfirst=0.0;
  4884.         fac=0.0;
  4885.         recipn=-1/astroidn;
  4886.         t=(0,0);
  4887.         z1=(0,0);
  4888.         z2=(0,0);
  4889.         zfirst=(0,0);
  4890.         zlast=(0,0);
  4891.         theta=trdeg*pi/180;
  4892.         rot=cos(theta)-flip(sin(theta));
  4893.         zrot=(0,0);
  4894.         itheta=0;
  4895.         nin=0;
  4896.     }
  4897.     void loop(void)
  4898.     {
  4899.         zrot=z*rot;// rotate z instead of the curve
  4900. //
  4901. // set up 1st line endpoint
  4902. //
  4903.         theta=theta0;
  4904.         Var_x=abs(cos(theta))^astroidn;
  4905.         Var_y=abs(sin(theta))^astroidn;
  4906.         fac=(Var_x+Var_y)^recipn;
  4907.         r=fac*astroida;
  4908.         z1=r*(cos(theta)+flip(sin(theta)))+curvecenter;
  4909. //
  4910. // loop through the rest of the points on the curve:
  4911. // next point in the loop becomes the new 2nd line endpoint
  4912. //
  4913.         itheta=0;
  4914.         while ((itheta<n))
  4915.         {
  4916.             itheta=itheta+1;
  4917.             theta=itheta*dtheta+theta0;
  4918.             Var_x=abs(cos(theta))^astroidn;
  4919.             Var_y=abs(sin(theta))^astroidn;
  4920.             fac=(Var_x+Var_y)^recipn;
  4921.             r=fac*astroida;
  4922.             z2=r*(cos(theta)+flip(sin(theta)))+curvecenter;
  4923. //
  4924. // find distance from z to the line
  4925. //
  4926.             t=(zrot-z1)/(z2-z1);
  4927.             Var_x=real(t);
  4928.             Var_y=sqr(imag(t));
  4929.             if ((Var_x<0.0))
  4930.             {
  4931.                 r=sqr(Var_x)+Var_y;
  4932.             }
  4933.             else if ((Var_x>1.0))
  4934.             {
  4935.                 r=sqr(Var_x-1.0)+Var_y;
  4936.             }
  4937.             else
  4938.             {
  4939.  
  4940.                 r=Var_y;
  4941.             }
  4942.             r=sqrt(r)*cabs(z2-z1);// scale lines to have same width
  4943. //
  4944. // check to see if this point is closer to line, or falls in range
  4945. //
  4946.             if ((r<rmin))
  4947.             {
  4948.                 rmin=r;
  4949.             }
  4950.             if ((r<=rangewidth))
  4951.             {
  4952.                 nin=nin+1;
  4953.                 rlast=r;
  4954.                 zlast=z;
  4955.                 if ((nin==1))
  4956.                 {
  4957.                     rfirst=r;
  4958.                     zfirst=z;
  4959.                 }
  4960.             }
  4961.             z1=z2;// update 1st endpoint
  4962.         }
  4963.     }
  4964.     void final(void)
  4965.     {
  4966.         if ((colorby==1))
  4967.         {// first mag
  4968.             if ((nin==0))
  4969.             {
  4970.                 solid=true;
  4971.             }
  4972.             else
  4973.             {
  4974.  
  4975.                 index=rfirst/rangewidth;
  4976.             }
  4977.         }
  4978.         else if ((colorby==2))
  4979.         {// first angle
  4980.             if ((nin==0))
  4981.             {
  4982.                 solid=true;
  4983.             }
  4984.             else
  4985.             {
  4986.  
  4987.                 theta=atan2(zfirst)/pi;
  4988.                 if ((theta<0.0))
  4989.                 {
  4990.                     theta=theta+2;
  4991.                 }
  4992.                 index=theta/2;
  4993.             }
  4994.         }
  4995.         else if ((colorby==3))
  4996.         {// last mag
  4997.             if ((nin==0))
  4998.             {
  4999.                 solid=true;
  5000.             }
  5001.             else
  5002.             {
  5003.  
  5004.                 index=rlast/rangewidth;
  5005.             }
  5006.         }
  5007.         else if ((colorby==4))
  5008.         {// last angle
  5009.             if ((nin==0))
  5010.             {
  5011.                 solid=true;
  5012.             }
  5013.             else
  5014.             {
  5015.  
  5016.                 theta=atan2(zlast)/pi;
  5017.                 if ((theta<0.0))
  5018.                 {
  5019.                     theta=theta+2;
  5020.                 }
  5021.                 index=theta/2;
  5022.             }
  5023.         }
  5024.         else
  5025.         {
  5026.                        // nearest
  5027.             index=rmin^power;
  5028.         }
  5029.     }
  5030.     void description(void)
  5031.     {
  5032.         this.title="Astroid String Art";
  5033.    
  5034.         n.caption="# of points";
  5035.         n.default=8;
  5036.         n.hint="Both #'s should be coprime, like 8 & 3 or 16 & 9.";
  5037.   
  5038.    
  5039.         m.caption="# skipped";
  5040.         m.default=3;
  5041.         m.hint="Both #'s should be coprime, like 8 & 3 or 16 & 9.";
  5042.   
  5043.    
  5044.         curvecenter.caption="curve center";
  5045.         curvecenter.default=(0,0);
  5046.   
  5047.    
  5048.         t0deg.caption="line rotation";
  5049.         t0deg.default=0.0;
  5050.         t0deg.hint="Rotates the start of the lines, in degrees, +ccw.";
  5051.   
  5052.    
  5053.         trdeg.caption="curve rotation";
  5054.         trdeg.default=0.0;
  5055.         trdeg.hint="Rotates the curve, in degrees, +ccw.";
  5056.   
  5057.    
  5058.         astroidn.caption="astroid power";
  5059.         astroidn.default=0.5;
  5060.         astroidn.min=0.0;
  5061.         astroidn.max=256.0;
  5062.         astroidn.hint="< 1 for a true astroid, 1 for a diamond, 2 for a circle, 256 for a near square.";
  5063.   
  5064.    
  5065.         astroida.caption="astroid scale";
  5066.         astroida.default=1.0;
  5067.         astroida.min=0.0;
  5068.         astroida.hint="Increase to make the curve larger.";
  5069.   
  5070.    
  5071.         colorby.caption="color by:";
  5072.         colorby.default=0;
  5073.         colorby.enum="minimum dist.\nfirst mag\nfirst angle\nlast mag\nlast angle";
  5074.   
  5075.    
  5076.         rangewidth.caption="range width";
  5077.         rangewidth.default=0.1;
  5078.         rangewidth.hint="Use with all but 'minimum dist.' 'color by:' choices.";
  5079.   
  5080.    
  5081.         power.caption="power";
  5082.         power.default=1.0;
  5083.         power.hint="Use with color density to control line thickness.  Use with 'minimum dist.' 'color by:' choice.";
  5084.   
  5085.     }
  5086. }
  5087.  
  5088.  
  5089. crosshatch { // Kerry Mitchell 23may2001
  5090. //
  5091. // "Colors" the fractal by drawing lines, grids, squares or triangles
  5092. // with the variation in spacing relaying the "color" information.
  5093. //
  5094. real space;
  5095. real size;
  5096. parameter real sizefac;
  5097. real Var_x;
  5098. real Var_y;
  5099. real t;
  5100. real r1;
  5101. real r2;
  5102. real r3;
  5103. real cost;
  5104. real sint;
  5105. real p;
  5106. parameter real randseed;
  5107. real colorz;
  5108. real count;
  5109. int iter;
  5110. complex zvalue;
  5111. complex zfirst;
  5112. complex zmean;
  5113. parameter int ztype;
  5114. parameter real tdeg;
  5115. parameter int shape;
  5116. parameter int colorby;
  5117. parameter real numsect;
  5118. parameter real density;
  5119. parameter real offset;
  5120. parameter int transfertype;
  5121.  
  5122.     void init(void)
  5123.     {
  5124.         space=0.0;
  5125.         size=0.01*sizefac/magn;
  5126.         Var_x=real(pixel);
  5127.         Var_y=imag(pixel);
  5128.         t=0.0;
  5129.         r1=0.0;
  5130.         r2=0.0;
  5131.         r3=0.0;
  5132.         cost=0.0;
  5133.         sint=0.0;
  5134.         p=randseed;
  5135.         colorz=0.0;
  5136.         count=0.0;
  5137.         iter=0;
  5138.         zvalue=(0,0);
  5139.         zfirst=(0,0);
  5140.         zmean=(0,0);
  5141.     }
  5142.     void loop(void)
  5143.     {
  5144.         iter=iter+1;
  5145.         if ((iter==1))
  5146.         {
  5147.             zfirst=z;
  5148.         }
  5149.         zmean=zmean+z;
  5150.         p=4*p*(1-p);
  5151.     }
  5152.     void final(void)
  5153.     {
  5154. //
  5155. // determine count
  5156. //
  5157.         if ((ztype==1))
  5158.         {// first z
  5159.             zvalue=zfirst;
  5160.         }
  5161.         else if ((ztype==2))
  5162.         {// last z
  5163.             zvalue=z;
  5164.         }
  5165.         else if ((ztype==3))
  5166.         {// average
  5167.             zvalue=zmean/iter;
  5168.         }
  5169.         else
  5170.         {
  5171.                        // pixel
  5172.             zvalue=pixel;
  5173.         }
  5174. //
  5175. // set up lines
  5176. //
  5177.         Var_x=real(zvalue);
  5178.         Var_y=imag(zvalue);
  5179.         t=tdeg*pi/180;
  5180.         cost=cos(t);
  5181.         sint=sin(t);
  5182.         r1=cost*Var_y-sint*Var_x;
  5183.         r2=sint*Var_y+cost*Var_x;
  5184.         if (((shape==2)||(shape==4)))
  5185.         {// triangular grid
  5186.             t=(tdeg+120)*pi/180;
  5187.             cost=cos(t);
  5188.             sint=sin(t);
  5189.             r2=cost*Var_y-sint*Var_x;
  5190.             t=(tdeg+240)*pi/180;
  5191.             cost=cos(t);
  5192.             sint=sin(t);
  5193.             r3=cost*Var_y-sint*Var_x;
  5194.         }
  5195.         if ((colorby==1))
  5196.         {// log(last magnitude)
  5197.             count=log(cabs(z));
  5198.             if ((numsect>0))
  5199.             {
  5200.                 count=trunc(count*numsect)/numsect;
  5201.             }
  5202.         }
  5203.         else if ((colorby==2))
  5204.         {// last angle
  5205.             count=atan2(z);
  5206.             if ((numsect>0))
  5207.             {
  5208.                 count=trunc(count*numsect)/numsect;
  5209.             }
  5210.         }
  5211.         else
  5212.         {
  5213.                        // iterations
  5214.             count=iter;
  5215.         }
  5216. //
  5217. // determine index (colorz)
  5218. //
  5219.         t=count*density+offset;
  5220.         if ((transfertype==1))
  5221.         {// sawtooth
  5222.             if ((t<0.0))
  5223.             {
  5224.                 t=t+round(2-t);
  5225.             }
  5226.             colorz=t%1.0;
  5227.         }
  5228.         else
  5229.         {
  5230.                        // sinusoidal
  5231.             colorz=(1-cos(t))/2;
  5232.         }
  5233. //
  5234. // build lines
  5235. //
  5236.         if ((colorz>0.0))
  5237.         {
  5238.             if ((shape==1))
  5239.             {// square grid
  5240.                 space=size/colorz;
  5241.                 space=(space-size)*2+size;
  5242.                 if ((r1<0.0))
  5243.                 {
  5244.                     t=round(2-r1/space)+p;
  5245.                 }
  5246.                 else
  5247.                 {
  5248.  
  5249.                     t=p;
  5250.                 }
  5251.                 r1=(r1+t*space)%space;
  5252.                 if ((r2<0.0))
  5253.                 {
  5254.                     t=round(2-r2/space)+p;
  5255.                 }
  5256.                 else
  5257.                 {
  5258.  
  5259.                     t=p;
  5260.                 }
  5261.                 r2=(r2+t*space)%space;
  5262.                 if (((r1<=size)||(r2<=size)))
  5263.                 {
  5264.                     r1=r1/size;
  5265.                     r2=r2/size;
  5266.                     if ((r2>r1))
  5267.                     {
  5268.                         index=r2;
  5269.                     }
  5270.                     else
  5271.                     {
  5272.  
  5273.                         index=r1;
  5274.                     }
  5275.                 }
  5276.                 else
  5277.                 {
  5278.  
  5279.                     solid=true;
  5280.                 }
  5281.             }
  5282.             else if ((shape==2))
  5283.             {// triangular grid
  5284.                 space=size/colorz;
  5285.                 space=(space-size)*3+size;
  5286.                 if ((r1<0.0))
  5287.                 {
  5288.                     t=round(2-r1/space)+p;
  5289.                 }
  5290.                 else
  5291.                 {
  5292.  
  5293.                     t=p;
  5294.                 }
  5295.                 r1=(r1+t*space)%space;
  5296.                 if ((r2<0.0))
  5297.                 {
  5298.                     t=round(2-r2/space)+p;
  5299.                 }
  5300.                 else
  5301.                 {
  5302.  
  5303.                     t=p;
  5304.                 }
  5305.                 r2=(r2+t*space)%space;
  5306.                 if ((r3<0.0))
  5307.                 {
  5308.                     t=round(2-r3/space)+p;
  5309.                 }
  5310.                 else
  5311.                 {
  5312.  
  5313.                     t=p;
  5314.                 }
  5315.                 r3=(r3+t*space)%space;
  5316.                 if (((r1<=size)||(r2<=size)||(r3<=size)))
  5317.                 {
  5318.                     r1=r1/size;
  5319.                     r2=r2/size;
  5320.                     r3=r3/size;
  5321.                     if (((r1>=r2)&&(r1>=r3)))
  5322.                     {
  5323.                         index=r1;
  5324.                     }
  5325.                     if (((r2>=r1)&&(r2>=r3)))
  5326.                     {
  5327.                         index=r2;
  5328.                     }
  5329.                     if (((r3>=r1)&&(r3>=r2)))
  5330.                     {
  5331.                         index=r3;
  5332.                     }
  5333.                 }
  5334.                 else
  5335.                 {
  5336.  
  5337.                     solid=true;
  5338.                 }
  5339.             }
  5340.             else if ((shape==3))
  5341.             {// squares
  5342.                 space=size/colorz;
  5343.                 space=(space-size)/3+size;
  5344.                 if ((r1<0.0))
  5345.                 {
  5346.                     t=round(2-r1/space)+p;
  5347.                 }
  5348.                 else
  5349.                 {
  5350.  
  5351.                     t=p;
  5352.                 }
  5353.                 r1=(r1+t*space)%space;
  5354.                 if ((r2<0.0))
  5355.                 {
  5356.                     t=round(2-r2/space)+p;
  5357.                 }
  5358.                 else
  5359.                 {
  5360.  
  5361.                     t=p;
  5362.                 }
  5363.                 r2=(r2+t*space)%space;
  5364.                 if (((r1<=size)&&(r2<=size)))
  5365.                 {
  5366.                     r1=r1/size;
  5367.                     r2=r2/size;
  5368.                     if ((r2>r1))
  5369.                     {
  5370.                         index=r2;
  5371.                     }
  5372.                     else
  5373.                     {
  5374.  
  5375.                         index=r1;
  5376.                     }
  5377.                 }
  5378.                 else
  5379.                 {
  5380.  
  5381.                     solid=true;
  5382.                 }
  5383.             }
  5384.             else if ((shape==4))
  5385.             {// triangles
  5386.                 space=size/colorz;
  5387.                 space=(space-size)/5+size;
  5388.                 if ((r1<0.0))
  5389.                 {
  5390.                     t=round(2-r1/space)+p;
  5391.                 }
  5392.                 else
  5393.                 {
  5394.  
  5395.                     t=p;
  5396.                 }
  5397.                 r1=(r1+t*space)%space;
  5398.                 if ((r2<0.0))
  5399.                 {
  5400.                     t=round(2-r2/space)+p;
  5401.                 }
  5402.                 else
  5403.                 {
  5404.  
  5405.                     t=p;
  5406.                 }
  5407.                 r2=(r2+t*space)%space;
  5408.                 if ((r3<0.0))
  5409.                 {
  5410.                     t=round(2-r3/space)+p;
  5411.                 }
  5412.                 else
  5413.                 {
  5414.  
  5415.                     t=p;
  5416.                 }
  5417.                 r3=(r3+t*space)%space;
  5418.                 if (((r1<=size)&&(r2<=size)&&(r3<=size)))
  5419.                 {
  5420.                     r1=r1/size;
  5421.                     r2=r2/size;
  5422.                     r3=r3/size;
  5423.                     if (((r1>=r2)&&(r1>=r3)))
  5424.                     {
  5425.                         index=r1;
  5426.                     }
  5427.                     if (((r2>=r1)&&(r2>=r3)))
  5428.                     {
  5429.                         index=r2;
  5430.                     }
  5431.                     if (((r3>=r1)&&(r3>=r2)))
  5432.                     {
  5433.                         index=r3;
  5434.                     }
  5435.                 }
  5436.                 else
  5437.                 {
  5438.  
  5439.                     solid=true;
  5440.                 }
  5441.             }
  5442.             else
  5443.             {
  5444.                      // line
  5445.                 space=size/colorz;
  5446.                 if ((r1<0.0))
  5447.                 {
  5448.                     t=round(2-r1/space)+p;
  5449.                 }
  5450.                 else
  5451.                 {
  5452.  
  5453.                     t=p;
  5454.                 }
  5455.                 r1=(r1+t*space)%space;
  5456.                 if ((r1<=size))
  5457.                 {
  5458.                     r1=r1/size;
  5459.                     index=r1;
  5460.                 }
  5461.                 else
  5462.                 {
  5463.  
  5464.                     solid=true;
  5465.                 }
  5466.             }
  5467.         }
  5468.         else
  5469.         {
  5470.  
  5471.             solid=true;
  5472.         }
  5473.     }
  5474.     void description(void)
  5475.     {
  5476.         this.title="Crosshatch";
  5477.         this.helpfile="lkm-help\lkm-crosshatch.html";
  5478.    
  5479.         ztype.caption="variable";
  5480.         ztype.default=0;
  5481.         ztype.enum="pixel\nfirst z\nlast z\naverage";
  5482.         ztype.hint="The plane in which the crosshatching is done.";
  5483.   
  5484.    
  5485.         colorby.caption="color by";
  5486.         colorby.default=0;
  5487.         colorby.enum="iterations\nlog(last mag)\nlast angle";
  5488.         colorby.hint="What to use to determine color.";
  5489.   
  5490.    
  5491.         numsect.caption="# sections";
  5492.         numsect.default=0;
  5493.         numsect.min=0;
  5494.         numsect.hint="Use to discretize magnitude or angle; use '0' to turn off.";
  5495.   
  5496.    
  5497.         shape.caption="shape";
  5498.         shape.default=0;
  5499.         shape.enum="line\nsquare grid\ntriangular grid\nsquare\ntriangle";
  5500.         shape.hint="What shape to use to color the regions.";
  5501.   
  5502.    
  5503.         sizefac.caption="size";
  5504.         sizefac.default=1.0;
  5505.         sizefac.min=0.0;
  5506.         sizefac.hint="The relative size of the lines.";
  5507.   
  5508.    
  5509.         tdeg.caption="rotation, deg";
  5510.         tdeg.default=45.0;
  5511.         tdeg.hint="Rotation of the shape, + ccw.";
  5512.   
  5513.    
  5514.         density.caption="density";
  5515.         density.default=0.25;
  5516.         density.hint="How quickly the 'colors' change; like the 'color density' parameter.";
  5517.   
  5518.    
  5519.         offset.caption="offset";
  5520.         offset.default=0.0;
  5521.         offset.hint="Use to rotate the 'color' distribution; like the 'gradient offset' parameter.";
  5522.   
  5523.    
  5524.         transfertype.caption="transfer function";
  5525.         transfertype.default=0;
  5526.         transfertype.enum="sinusoidal\nsawtooth";
  5527.         transfertype.hint="How the count gets reduced to a value between 0 & 1.";
  5528.   
  5529.    
  5530.         randseed.caption="random seed";
  5531.         randseed.default=0.1;
  5532.         randseed.min=0.0;
  5533.         randseed.hint="Use to offset the lines randomly in each band; use '0' to turn off.";
  5534.   
  5535.     }
  5536. }
  5537.  
  5538.  
  5539. hilbert-curve { // Kerry Mitchell 15jul2001
  5540. //
  5541. // Draws a Hilbert curve in the #z plane and colors by the
  5542. // orbit's relationship to the curve.  Only uses the last
  5543. // iterate.  Allows you to change the locations of the 4
  5544. // sub-square centers, and the point where the curve enters
  5545. // and exits the block of 4 squares.
  5546. //
  5547. real Var_x;
  5548. real Var_y;
  5549. real r;
  5550. real rmin;
  5551. real u;
  5552. real v;
  5553. real msb;
  5554. complex t;
  5555. int iter;
  5556. int nlast;
  5557. int n;
  5558. int fac3;
  5559. int fac4;
  5560. int power4;
  5561. complex zh;
  5562. complex zh0;
  5563. real h;
  5564. parameter real fourcorners;
  5565. real ooh;
  5566. real ooomh;
  5567. real hoomh;
  5568. complex z0a;
  5569. parameter real enterexit;
  5570. complex z0b;
  5571. parameter complex centerll;
  5572. complex z1;
  5573. parameter complex centerul;
  5574. complex z2;
  5575. parameter complex centerur;
  5576. complex z3;
  5577. parameter complex centerlr;
  5578. complex z4;
  5579. complex z5;
  5580. parameter real niter;
  5581. parameter int colorby;
  5582. complex z0;
  5583.  
  5584.     void init(void)
  5585.     {
  5586.         Var_x=0.0;
  5587.         Var_y=0.0;
  5588.         r=0.0;
  5589.         rmin=1e20;
  5590.         u=0.0;
  5591.         v=0.0;
  5592.         msb=0.0;
  5593.         t=(0,0);
  5594.         iter=0;
  5595.         nlast=0;
  5596.         n=0;
  5597.         fac3=0;
  5598.         fac4=0;
  5599.         power4=0;
  5600.         zh=(0,0);
  5601.         zh0=(0,0);
  5602. //
  5603. // set up endpoints for the lines
  5604. //
  5605.         h=fourcorners;
  5606.         ooh=1/h;
  5607.         ooomh=1/(1-h);
  5608.         hoomh=h/(1-h);
  5609.         z0a=enterexit*h;
  5610.         z0b=flip(enterexit*h);
  5611.         Var_x=real(centerll)*h;
  5612.         Var_y=imag(centerll)*h;
  5613.         z1=Var_x+flip(Var_y);
  5614.         Var_x=real(centerul)*h;
  5615.         Var_y=imag(centerul)*(1-h)+h;
  5616.         z2=Var_x+flip(Var_y);
  5617.         Var_x=real(centerur)*(1-h)+h;
  5618.         Var_y=imag(centerur)*(1-h)+h;
  5619.         z3=Var_x+flip(Var_y);
  5620.         Var_x=real(centerlr)*(1-h)+h;
  5621.         Var_y=imag(centerlr)*h;
  5622.         z4=Var_x+flip(Var_y);
  5623.         z5=1+flip(enterexit*h);
  5624.     }
  5625.     void loop(void)
  5626.     {
  5627.     }
  5628.     void final(void)
  5629.     {
  5630.         iter=0;
  5631.         zh0=z*0.25+(0.5,0.5);
  5632.         zh=zh0;
  5633.         while ((iter<niter))
  5634.         {
  5635.             iter=iter+1;
  5636.             Var_x=real(zh);
  5637.             Var_y=imag(zh);
  5638. //
  5639. // lower left sub-square:  shrink, flip horizontally, rotate by -90 degrees
  5640. //
  5641.             if (((Var_x<h)&&(Var_y<h)))
  5642.             {
  5643.                 nlast=3;
  5644.                 u=ooh*Var_y;
  5645.                 v=ooh*Var_x;
  5646. //
  5647. // upper left sub-square:  just shrink
  5648. //
  5649.             }
  5650.             else if (((Var_x<h)&&(Var_y>=h)))
  5651.             {
  5652.                 nlast=2;
  5653.                 u=ooh*Var_x;
  5654.                 v=ooomh*Var_y-hoomh;
  5655. //
  5656. // upper right sub-square:  shrink & flip horizontally
  5657. //
  5658.             }
  5659.             else if (((Var_x>=h)&&(Var_y>=h)))
  5660.             {
  5661.                 nlast=1;
  5662.                 u=ooomh-ooomh*Var_x;
  5663.                 v=ooomh*Var_y-hoomh;
  5664. //
  5665. // lower right sub-square:  shrink, rotate by 90 degrees
  5666. //
  5667.             }
  5668.             else if (((Var_x>=h)&&(Var_y<h)))
  5669.             {
  5670.                 nlast=4;
  5671.                 u=ooh*Var_y;
  5672.                 v=ooomh-ooomh*Var_x;
  5673.             }
  5674.             else
  5675.             {
  5676.  
  5677.                 nlast=-1;
  5678.                 u=Var_x;
  5679.                 v=Var_y;
  5680.             }
  5681.             zh=u+flip(v);
  5682.             msb=(msb+nlast-1)/4;
  5683.             n=n*4+nlast-1;
  5684.         }
  5685.         if ((n<0))
  5686.         {
  5687.             solid=true;
  5688.         }
  5689.         else
  5690.         {
  5691.  
  5692.             if ((colorby==1))
  5693.             {// least significant bit
  5694.                 index=n/(4^niter);
  5695.             }
  5696.             else if ((colorby==2))
  5697.             {// most significat bit
  5698.                 index=msb;
  5699.             }
  5700.             else if ((colorby==3))
  5701.             {// distance from initial z
  5702.                 index=cabs(zh-zh0);
  5703.             }
  5704.             else if ((colorby==4))
  5705.             {// angle from initial z
  5706.                 r=atan2(zh-zh0)/pi;
  5707.                 if ((r<0.0))
  5708.                 {
  5709.                     r=r+2;
  5710.                 }
  5711.                 index=r/2;
  5712.             }
  5713.             else
  5714.             {
  5715.                      // distance to curve
  5716. //
  5717. // determine how to start line 0-1
  5718. //
  5719.                 z0=z0a;
  5720.                 iter=0;
  5721.                 fac3=2;
  5722.                 fac4=1;
  5723.                 power4=4;
  5724.                 while ((iter<niter))
  5725.                 {
  5726.                     iter=iter+1;
  5727.                     if ((iter%2==1))
  5728.                     {
  5729.                         if ((n%power4==fac3))
  5730.                         {
  5731.                             z0=z0b;
  5732.                         }
  5733.                     }
  5734.                     else
  5735.                     {
  5736.  
  5737.                         if ((n%power4==fac3))
  5738.                         {
  5739.                             z0=z0a;
  5740.                         }
  5741.                     }
  5742.                     power4=4*power4;
  5743.                     fac4=4*fac4;
  5744.                     fac3=fac3+2*fac4;
  5745.                 }
  5746. //
  5747. // line from enter to lower left sub-square
  5748. //
  5749.                 t=(zh-z0)/(z1-z0);
  5750.                 Var_x=real(t);
  5751.                 Var_y=imag(t);
  5752.                 if ((Var_x<0.0))
  5753.                 {
  5754.                     r=sqr(Var_x)+sqr(Var_y);
  5755.                 }
  5756.                 else if ((Var_x>1.0))
  5757.                 {
  5758.                     r=sqr(Var_x-1.0)+sqr(Var_y);
  5759.                 }
  5760.                 else
  5761.                 {
  5762.  
  5763.                     r=sqr(Var_y);
  5764.                 }
  5765.                 r=sqrt(r)*cabs(z1-z0);
  5766.                 if ((r<rmin))
  5767.                 {
  5768.                     rmin=r;
  5769.                 }
  5770. //
  5771. // line from lower left to upper left sub-squares
  5772. //
  5773.                 t=(zh-z1)/(z2-z1);
  5774.                 Var_x=real(t);
  5775.                 Var_y=imag(t);
  5776.                 if ((Var_x<0.0))
  5777.                 {
  5778.                     r=sqr(Var_x)+sqr(Var_y);
  5779.                 }
  5780.                 else if ((Var_x>1.0))
  5781.                 {
  5782.                     r=sqr(Var_x-1.0)+sqr(Var_y);
  5783.                 }
  5784.                 else
  5785.                 {
  5786.  
  5787.                     r=sqr(Var_y);
  5788.                 }
  5789.                 r=sqrt(r)*cabs(z2-z1);
  5790.                 if ((r<rmin))
  5791.                 {
  5792.                     rmin=r;
  5793.                 }
  5794. //
  5795. // line from upper left to upper right sub-squares
  5796. //
  5797.                 t=(zh-z2)/(z3-z2);
  5798.                 Var_x=real(t);
  5799.                 Var_y=imag(t);
  5800.                 if ((Var_x<0.0))
  5801.                 {
  5802.                     r=sqr(Var_x)+sqr(Var_y);
  5803.                 }
  5804.                 else if ((Var_x>1.0))
  5805.                 {
  5806.                     r=sqr(Var_x-1.0)+sqr(Var_y);
  5807.                 }
  5808.                 else
  5809.                 {
  5810.  
  5811.                     r=sqr(Var_y);
  5812.                 }
  5813.                 r=sqrt(r)*cabs(z3-z2);
  5814.                 if ((r<rmin))
  5815.                 {
  5816.                     rmin=r;
  5817.                 }
  5818. //
  5819. // line from upper right to lower right sub-squares
  5820. //
  5821.                 t=(zh-z3)/(z4-z3);
  5822.                 Var_x=real(t);
  5823.                 Var_y=imag(t);
  5824.                 if ((Var_x<0.0))
  5825.                 {
  5826.                     r=sqr(Var_x)+sqr(Var_y);
  5827.                 }
  5828.                 else if ((Var_x>1.0))
  5829.                 {
  5830.                     r=sqr(Var_x-1.0)+sqr(Var_y);
  5831.                 }
  5832.                 else
  5833.                 {
  5834.  
  5835.                     r=sqr(Var_y);
  5836.                 }
  5837.                 r=sqrt(r)*cabs(z4-z3);
  5838.                 if ((r<rmin))
  5839.                 {
  5840.                     rmin=r;
  5841.                 }
  5842. //
  5843. // line from lower right sub-square to exit
  5844. //
  5845.                 t=(zh-z4)/(z5-z4);
  5846.                 Var_x=real(t);
  5847.                 Var_y=imag(t);
  5848.                 if ((Var_x<0.0))
  5849.                 {
  5850.                     r=sqr(Var_x)+sqr(Var_y);
  5851.                 }
  5852.                 else if ((Var_x>1.0))
  5853.                 {
  5854.                     r=sqr(Var_x-1.0)+sqr(Var_y);
  5855.                 }
  5856.                 else
  5857.                 {
  5858.  
  5859.                     r=sqr(Var_y);
  5860.                 }
  5861.                 r=sqrt(r)*cabs(z5-z4);
  5862.                 if ((r<rmin))
  5863.                 {
  5864.                     rmin=r;
  5865.                 }
  5866. //
  5867.                 index=rmin;
  5868.             }
  5869.         }
  5870.     }
  5871.     void description(void)
  5872.     {
  5873.         this.title="Hilbert curve";
  5874.    
  5875.         centerll.caption="lower left center";
  5876.         centerll.default=(0.5,0.5);
  5877.         centerll.hint="Center of the lower left sub-square. Make both coordinates between 0 & 1; use (0.5,0.5) for standard Hilbert curve.";
  5878.   
  5879.    
  5880.         centerul.caption="upper left center";
  5881.         centerul.default=(0.5,0.5);
  5882.         centerul.hint="Center of the upper left sub-square. Make both coordinates between 0 & 1; use (0.5,0.5) for standard Hilbert curve.";
  5883.   
  5884.    
  5885.         centerur.caption="upper right center";
  5886.         centerur.default=(0.5,0.5);
  5887.         centerur.hint="Center of the upper right sub-square. Make both coordinates between 0 & 1; use (0.5,0.5) for standard Hilbert curve.";
  5888.   
  5889.    
  5890.         centerlr.caption="lower right center";
  5891.         centerlr.default=(0.5,0.5);
  5892.         centerlr.hint="Center of the lower right sub-square. Make both coordinates between 0 & 1; use (0.5,0.5) for standard Hilbert curve.";
  5893.   
  5894.    
  5895.         enterexit.caption="enter/exit";
  5896.         enterexit.default=0.5;
  5897.         enterexit.min=0.0;
  5898.         enterexit.max=1.0;
  5899.         enterexit.hint="Where the curve enters and exits the block of 4 sub-squares. Between 0 & 1; use 0.5 for standard Hilbert curve.";
  5900.   
  5901.    
  5902.         fourcorners.caption="4 corners";
  5903.         fourcorners.default=0.5;
  5904.         fourcorners.hint="Where the 4 corners meet.  Between 0 & 1; use 0.5 for standard Hilbert curve.";
  5905.   
  5906.    
  5907.         niter.caption="iterations";
  5908.         niter.default=0;
  5909.         niter.min=0;
  5910.   
  5911.    
  5912.         colorby.caption="color by";
  5913.         colorby.default=0;
  5914.         colorby.enum="distance\nlast = lsb\nlast = msb\ndistance from z\nangle from z";
  5915.   
  5916.     }
  5917. }
  5918.  
  5919.  
  5920. line { // Kerry Mitchell 15jul2001
  5921. //
  5922. // Just draws a line between 2 points
  5923. //
  5924. real Var_x;
  5925. real Var_y;
  5926. real r;
  5927. complex t;
  5928. parameter complex z1;
  5929. parameter complex z2;
  5930.  
  5931.     void init(void)
  5932.     {
  5933.         Var_x=0.0;
  5934.         Var_y=0.0;
  5935.         r=0.0;
  5936.         t=(0,0);
  5937.     }
  5938.     void loop(void)
  5939.     {
  5940.     }
  5941.     void final(void)
  5942.     {
  5943.         t=(z-z1)/(z2-z1);
  5944.         Var_x=real(t);
  5945.         Var_y=imag(t);
  5946.         if ((Var_x<0.0))
  5947.         {
  5948.             r=sqr(Var_x)+sqr(Var_y);
  5949.         }
  5950.         else if ((Var_x>1.0))
  5951.         {
  5952.             r=sqr(Var_x-1.0)+sqr(Var_y);
  5953.         }
  5954.         else
  5955.         {
  5956.  
  5957.             r=sqr(Var_y);
  5958.         }
  5959.         r=sqrt(r)*cabs(z2-z1);
  5960.         index=r;
  5961.     }
  5962.     void description(void)
  5963.     {
  5964.         this.title="Line";
  5965.    
  5966.         z1.caption="1st endpoint";
  5967.         z1.default=(0,0);
  5968.   
  5969.    
  5970.         z2.caption="2nd endpoint";
  5971.         z2.default=(1,1);
  5972.   
  5973.     }
  5974. }
  5975.  
  5976.  
  5977.