motiffleur { ;martine.girard3@wanadoo.fr ;demo voir gmc.upr init: float dmax = -1E160 float dmin = 1E160 ;z=#z loop: float d = cabs(#z) if (d < dmin) dmin = d endif if (d > dmax) dmax = d endif final: ;int iter=1 ;while iter<#numiter ;z=oldz (iter) ;iter=iter+1 ;endwhile float x=log(abs(log(abs(log(abs(real(#z))))))) float y=log(abs(log(abs(log(abs(imag(#z))))))) float m=log(abs(log(abs(cabs(#z))))) tt=log(abs(log(abs(atan(imag(#z)/real(#z)))))) float t=((atan2(#z))) t=t/pi if(t<0.0) t=t+2.0 endif if #numiter<@fin if(@colorear==1) float t=((atan2(#z))) t=t/pi if(t<0.0) t=t+2.0 endif #index=cabs(@a*@gradi(t*t ))+(#numiter-@miniter)*@k elseif(@colorear==2) ; magnitude #index=cabs(@a*@gradi(m*m ))+(#numiter-@miniter)*@k elseif(@colorear==3) ; real(z) #index=cabs(@a*@gradi(x*x ))+(#numiter-@miniter)*@k elseif(@colorear==4) ; imag(z) #index=cabs(@a*@gradi(y*y))+ (#numiter-@miniter)*@k elseif(@colorear==5) #index=cabs(@a*@gradi(tt*tt))+ (#numiter-@miniter)*@k elseif(@colorear==6) #index=cabs(@a*@gradi(@a*dmin*dmin ))+ (#numiter-@miniter)*@k elseif(@colorear==7) #index=cabs(@a*@gradi(cabs(#pixel) ))+ (#numiter-@miniter)*@k elseif(@colorear==8 ) ;trefle if abs(real(#z))>=abs(imag(#z)) #index=cabs(@a*@gradi(y*y))+(#numiter-@miniter)*@k else #index=cabs(@a*@gradi(x*x))+(#numiter-@miniter)*@k endif elseif(@colorear==9) ; onde #index=cabs(@a*@gradi(y*x))+(#numiter-@miniter)*@k else #index=cabs(@a*@gradi( #numiter * #numiter )) endif if real(#z)>@module && #numiter< @finmot #index=log(abs(@kmodule*log(abs(real(#z)))))+2*#numiter endif endif if #numiter>=@fin #index=@k1*log(#numiter) endif default: title = "fleur" param colorear caption = "0 type de motif" default = 3 enum = \ "iteration" \ "angle" \ "|z|" \ "real(z)" \ "imag(z)" \ "angle2" \ "|z| min" \ "pixel" \ "trefle" \ "onde" endparam param a caption = "1 couleur fleur" default = 3.1 endparam param miniter caption = "2 miniter" default = 0 endparam param k caption = "3 gradient coul n" default = 2.5 endparam param fin caption = "4 fin de motif 1" default = 150 endparam param k1 caption = "5 grad sup a fin" default = 2.0 endparam param module caption = "6 dimen motif 2 " default = 80 endparam param kmodule caption = "7 couleur motif 2 " default = 50 endparam param finmot caption = "8 fin motif 2 " default = 5 endparam func gradi caption = "Transform" default = sqrt() endfunc } motiffleur2 { ;martine.girard3@wanadoo.fr ;demo voir gmc.upr init: float dmax = -1E160 float dmin = 1E160 loop: float d = cabs(#z) if (d < dmin) dmin = d endif if (d > dmax) dmax = d endif final: float x=log(abs(log(abs(log(abs(real(#z))))))) float y=log(abs(log(abs(log(abs(imag(#z))))))) float m=log(abs(log(abs(cabs(#z))))) tt=log(abs(log(abs(atan(imag(#z)/real(#z)))))) float t=((atan2(#z))) t=t/pi if(t<0.0) t=t+2.0 endif if #numiter<@fin if(@colorear==1) float t=((atan2(#z))) t=t/pi if(t<0.0) t=t+2.0 endif #index=cabs(@a*@gradi(t*t*0.1/(log(#numiter+2))^@b+log(10*#numiter*@k/#maxiter))) elseif(@colorear==2) ; magnitude #index=cabs(@a*@gradi(m*m*0.1/(log(#numiter+2))^@b+log(10*#numiter*@k/#maxiter))) elseif(@colorear==3) ; real(z) #index=cabs(@a*@gradi(x*x*1e-1/(log(#numiter+2))^@b+log(10*#numiter*@k/#maxiter))) elseif(@colorear==4) ; imag(z) #index=cabs(@a*@gradi(y*y*0.1/(log(#numiter+2))^@b+log(10*#numiter*@k/#maxiter))) elseif(@colorear==5) #index=cabs(@a*@gradi(tt*tt*0.1/(log(#numiter+2))^@b+log(10*#numiter*@k/#maxiter))) elseif(@colorear==6) #index=cabs(@a*@gradi(dmin*dmin ))+log(10*#numiter*@k/#maxiter) elseif(@colorear==7) #index=cabs(@a*@gradi(cabs(#pixel) ) )+log(10*#numiter*@k/#maxiter) elseif(@colorear==8 ) ;trefle if abs(real(#z))>=abs(imag(#z)) #index=cabs(@a*@gradi(y*y*0.1/(log(#numiter+12))^@b+log(10*#numiter*@k/#maxiter))) else #index=cabs(@a*@gradi(x*x*0.1/(log(#numiter+12))^@b+log(10*#numiter*@k/#maxiter))) endif elseif(@colorear==9) ; onde #index=cabs(@a*@gradi(x*y*0.1/(log(#numiter+2))^@b+log(10*#numiter*@k/#maxiter))) else #index=cabs(@a*@gradi( #numiter )) endif if real(#z)>@module && #numiter< @finmot #index=@kmodule/10*log(abs(log(abs(real(#z)))))+@b*#numiter+@kmodule endif endif if #numiter>=@fin #index=@k1*log(#numiter) endif default: title = "fleur-log" param colorear caption = "0 type de motif" default = 8 enum = \ "iteration" \ "angle" \ "|z|" \ "real(z)" \ "imag(z)" \ "angle2" \ "|z| min" \ "pixel" \ "trefle" \ "onde" endparam param a caption = "1 couleur fleur" default = 3000.1 endparam param b caption = "2 pente fleur" default = 0.5 endparam ; param miniter ; caption = "2 miniter" ; default = 0 ; endparam param k caption = "3 gradient coul n" default = 1.0 endparam param fin caption = "4 fin de motif 1" default = 150 endparam param k1 caption = "5 grad sup a fin" default = 2.0 endparam param module caption = "6 dimen motif 2 " default = 80 endparam param kmodule caption = "7 couleur motif 2 " default = 50 endparam param finmot caption = "8 fin motif 2 " default = 10 endparam func gradi caption = "Transform" default = sqrt() endfunc } motiffleur3 { ;martine.girard3@wanadoo.fr ;demo voir gmc.upr init: float dmax = -1E160 float dmin = 1E160 loop: float d = cabs(#z) if (d < dmin) dmin = d endif if (d > dmax) dmax = d endif final: float x=log(abs(log(abs(log(abs(real(#z))))))) float y=log(abs(log(abs(log(abs(imag(#z))))))) float m=log(abs(log(abs(cabs(#z))))) tt=log(abs(log(abs(atan(imag(#z)/real(#z)))))) float t=((atan2(#z))) t=t/pi if(t<0.0) t=t+2.0 endif if #numiter<@fin if(@colorear==1) float t=((atan2(#z))) t=t/pi if(t<0.0) t=t+2.0 endif #index=cabs(@a*@gradi(t*t ))+ sqr(#numiter)*@k elseif(@colorear==2) ; magnitude #index=cabs(@a*@gradi(m*m ))+ sqr(#numiter)*@k elseif(@colorear==3) ; real(z) #index=cabs(@a*@gradi(x*x ))+ sqr(#numiter)*@k elseif(@colorear==4) ; imag(z) #index=cabs(@gradi(@a*y*y))+ sqr(#numiter)*@k elseif(@colorear==5) #index=cabs(@a*@gradi(tt*tt))+ sqr(#numiter)*@k elseif(@colorear==6) #index=cabs(@a*@gradi(dmin*dmin ))+ sqr(#numiter)*@k elseif(@colorear==7) #index=cabs(@a*@gradi(cabs(#pixel) ))+ sqr(#numiter)*@k elseif(@colorear==8 ) ;trefle if abs(real(#z))>=abs(imag(#z)) #index=cabs(@a*@gradi(y*y ))+sqr( #numiter)*@k else #index=cabs(@a*@gradi(x*x ))+sqr( #numiter)*@k endif elseif(@colorear==9) ; onde #index=cabs(@a*@gradi(y*x))+ sqr(#numiter)*@k else #index=cabs(@a*@gradi( #numiter ))+ sqr(#numiter)*@k endif if real(#z)>@module && #numiter< @finmot #index=log(abs(@kmodule*log(abs(real(#z)))))+2*#numiter endif endif if #numiter>=@fin #index=@k1*log(#numiter) endif default: title = "fleur x^2" param colorear caption = "0 type de motif" default = 1 enum = \ "iteration" \ "angle" \ "|z|" \ "real(z)" \ "imag(z)" \ "angle2" \ "|z| min" \ "pixel" \ "trefle" \ "onde" endparam param a caption = "1 couleur fleur" default = 70.1 endparam ; param miniter ; caption = "2 miniter" ; default = 0 ; endparam param k caption = "3 gradient coul n" default = 1.5 endparam param fin caption = "4 fin de motif 1" default = 150 endparam param k1 caption = "5 grad sup a fin" default = 2.0 endparam param module caption = "6 dimen motif 2 " default = 80 endparam param kmodule caption = "7 couleur motif 2 " default = 50 endparam param finmot caption = "8 fin motif 2 " default = 10 endparam func gradi caption = "Transform" default = sqrt() endfunc } motiffleur4 { ;martine.girard3@wanadoo.fr ;demo voir gmc.upr init: float dmax = -1E160 float dmin = 1E160 loop: float d = cabs(#z) if (d < dmin) dmin = d endif if (d > dmax) dmax = d endif final: float x=log(abs(log(abs(log(abs(real(#z))))))) float y=log(abs(log(abs(log(abs(imag(#z))))))) float m=log(abs(log(abs(cabs(#z))))) tt=log(abs(log(abs(atan(imag(#z)/real(#z)))))) float t=((atan2(#z))) t=t/pi if(t<0.0) t=t+2.0 endif if #numiter<@fin if(@colorear==1) float t=((atan2(#z))) t=t/pi if(t<0.0) t=t+2.0 endif #index=cabs(@a*@gradi(t*t ))+sqr( #numiter-@miniter)*@k elseif(@colorear==2) ; magnitude #index=cabs(@a*@gradi(m*m ))+sqr( #numiter-@miniter)*@k elseif(@colorear==3) ; real(z) #index=cabs(@a*@gradi(x*x ))+sqr( #numiter-@miniter)*@k elseif(@colorear==4) ; imag(z) #index=cabs(@a*@gradi(y*y))+sqr( #numiter-@miniter)*@k elseif(@colorear==5) #index=cabs(@a*@gradi(tt*tt))+sqr( #numiter-@miniter)*@k elseif(@colorear==6) #index=cabs(@a*@gradi(dmin*dmin ))+sqr( #numiter-@miniter)*@k elseif(@colorear==7) #index=cabs(@gradi(@a*cabs(#pixel) ))+sqr( #numiter-@miniter)*@k elseif(@colorear==8 ) ;trefle if abs(real(#z))>=abs(imag(#z)) #index=cabs(@a*@gradi(y*y ))+sqr( #numiter-@miniter)*@k else #index=cabs(@a*@gradi(x*x ))+sqr( #numiter-@miniter)*@k endif elseif(@colorear==9) ; onde #index=cabs(@a*@gradi(y*x))+sqr( #numiter-@miniter)*@k else #index=cabs(@gradi(@a * #numiter * #numiter )) endif if real(#z)>@module && #numiter< @finmot #index=log(abs(@kmodule*log(abs(real(#z)))))+2*#numiter endif endif if #numiter>=@fin #index=@k1*log(#numiter) endif default: title = "fleur-racine" param colorear caption = "0 type de motif" default = 9 enum = \ "iteration" \ "angle" \ "|z|" \ "real(z)" \ "imag(z)" \ "angle2" \ "|z| min" \ "pixel" \ "trefle" \ "onde" endparam param a caption = "1 couleur fleur" default = 30.1 endparam param miniter caption = "2 miniter" default = 0 endparam param k caption = "3 gradient coul n" default = 1.0 endparam param fin caption = "4 fin de motif 1" default = 150 endparam param k1 caption = "5 grad sup a fin" default = 2.0 endparam param module caption = "6 dimen motif 2 " default = 80 endparam param kmodule caption = "7 couleur motif 2 " default = 50 endparam param finmot caption = "8 fin motif 2 " default = 10 endparam func gradi caption = "Transform" default = sqrt() endfunc } comment { Coloring schemes developed by Kerry Mitchell Includes: Basic Basic Plus Emboss Gaussian Integer Statistics Polar Curves Astroid 5 Point Star Conic Sections Conic Lite 2 Sections Conic Lite Old Bubbles Range Passthru Distance to a Point Pythagorean Triple Compilation dated 06feb00 } comment { ; narrative copyright Kerry Mitchell 20sep98 Gaussian Integer Coloring Gaussian integers are complex numbers such that both the real and imaginary parts are integers. Examples are: (0,0), (-2,3), (17,-5), and (1000000,123456789). The gaussian scheme is concerned with how the orbit behaves relative to a Gaussian integer. To find the Gaussian integer which the orbit most closely approaches, the built-in function round() is used. Round(z) returns a complex number whose components are the rounded components of z. This is a Gaussian integer. The distance from z to round(z) is simply the magnitude of z - round(z). The "minimum distance" method tracks this distance and records its smallest value. The "iteration @ min" colors by the iteration number when this minimum is reached, and the "angle @ min" methods colors by the polar angle of z when the minimum was reached. The corresponding "maximum" methods ("maximum distance", "iteration @ max", and "angle @ max") work in a similar fashion for the maximum value of z - round(z). The final method, "average distance", simply colors by the mean of the distance over the course of the orbit. Note that the angle used here is the actual polar angle, with a range of 360 degrees, instead of the angle returned by the built-in "atan" function, which only has a range of 180 degrees. These methods essentially overlay a 1x1 square grid onto the complex plane and ask how close (or far) the orbit comes to a node in the grid. Two options allow varying the size of the grid; these are called the "normalization" methods. The first is to normalize z by the #pixel. This has the effect of asking how close the orbit comes to Gaussian integer multiples of the #pixel value (or, z/#pixel = has integer real and imaginary parts). The other normalization method employs a user- specified complex factor. Then, the coloring is performed according to how close the orbit comes to Gaussian integer multiples of this factor. For example, if the factor was set to (1.2,5.1), then the methods would be coloring by the orbits approach to nodes of a rectangular grid that was 1.2 units long by 5.1 units high. This might be useful with Julia set images, as the factor can be set to the Julia parameter. The default, "none" normalization, uses a factor of 1. } comment { ; copyright Kerry Mitchell 04nov98 Statistics This started out with an article written by Stephen Ferguson on an analysis of fractal dimension, which he based on an algorithm by Holger Jaenisch. The formulas here modify Stephen's analysis and add other standard statistical measures. Since the measures are typically used with bounded datasets, this coloring method may be more applicable as an "inside" scheme, but there's nothing stopping a user from employing it as an "outside" scheme as well. The statistical measures implemented are: minimum, maximum, range, mean, standard deviation, coefficient of variation, and fractal dimension. All are defined only for real variables, so there are 4 choices for reducing the complex #z to a real number: real(#z), imag(#z), the magnitude of #z, and imag(#z)/real(#z). The last method is an attempt to capture the polar angle of #z, without the discontinuities involved in actually using the angle arg(#z). Once the choice of variable has been made, the first 3 measures are simple enough to compute. Simply monitor the orbit, updating the minimum and maximum as they change. Once the iteration has ceased, the range is just (maximum - minimum). The mean is computed by keeping a running sum of the variable, then dividing it by the number of iterations. The standard deviation is a measure of the spread of the data, and is defined in terms of the sum of the squared differences between each datum and the mean. This can also be computed by keeping a running sum of the square of the variable. This sum is used with the sum for the mean to determine the standard deviation. The coefficient of variation is a normalized standard deviation: it's the ratio of the standard deviation to the mean. Finally, the "fractal dimension" computed here is not the true fractal dimension, but an approximation to it. It's the standard deviation normalized by the range. } interieurfleur { init: int iter=0 float r=0.0 float rmin=1e12 float rmax=-rmin float sumsum=0.0 float sum=0.0 loop: iter=iter+1 if(@vartype==0) ; real(z) r=real(#z) elseif(@vartype==1) ; imag(z) r=imag(#z) elseif(@vartype==2) ; magnitude(z) r=cabs(#z) else ; imag(z)/real(z) r=imag(#z)/real(#z) endif sum=sum+r sumsum=sumsum+r*r if(rrmax) rmax=r endif final: if(@stattype==0) ; minimum #index=rmin elseif(@stattype==1) ; maximum #index=rmax elseif(@stattype==2) ; range #index=rmax-rmin elseif(@stattype==3) ; mean #index=sum/iter elseif(@stattype==4) ; standard deviation #index=sqrt(sumsum-sum*sum/iter) elseif(@stattype==5) ; coefficient of variation #index=sqrt(sumsum-sum*sum/iter)/sum*iter else ; fractal dimension #index=sqrt(sumsum-sum*sum/iter)/(rmax-rmin) endif if #numiter>@fin #index=log(#numiter) endif default: title="interieur fleur" param fin caption = "fin de motif" default = 10050 endparam param vartype caption="variable" default=2 enum="real(z)" "imag(z)" "magnitude" "imag/real" hint="variable for which statistics will be calculated" endparam param stattype caption="statistic" default=6 enum="minimum" "maximum" "range" "mean" \ "std. deviation" "variation" "fractal dimension" hint="statistic that will be calculated" endparam } comment { ; copyright Kerry Mitchell 15nov98 Polar Curves Typically, points in a plane are thought of in terms of their x- and y-coordinates, that is, how far away (and on which side) the point is from the horizontal x-axis and the vertical y-axis. Another way of looking at the point is with polar coordinates, which specify the distance of the point from the origin (r) and its direction (t). The two methods are equivalent: x = r*cos(t), y=r*sin(t), or r^2 = x^2 + y^2, tan(t) = y/x. Polar curves are curves that specify r as a function of t, instead of y as a function of x. The curve used in this coloring method is: r = [a * f(b*t)]^n + r0, where f is one of UltraFractal's builtin functions (e.g., sin, cos, exp, etc.), a is an amplitude scaling factor, and b is a frequency factor. The exponent n is useful for making the curve wider or thinner, and r0 is a expansion or contraction constant. Some special curves can be generated using this function. Spirals can be made by using the "ident" function. Here, the exponent n controls how tightly wound the spiral is. However, only one revolution of the spiral will be drawn, as t is limited to the range 0 to 2*pi. "Rose" curves are made by using either sin or cos functions. The parameter a controls the size of the curve. The number of "petals" is b, so long as b is a positive integer. Increasing n from 1 will make the petals thinner; decreasing it toward 0 will make them thicker. Leave r0=0 for the standard rose curve, where the petals all join at the origin. Since the sin and cos functions generate negative values, the "rose" curves will have some regions of negative r. How this is handled depends on r0 and "negrflag", the negative r flag. Setting negrflag to 1 will make the routine ignore negative r values. This, with r0 is set to 0, will cause the rose curve to have "b" number of petals, all of them the same size. Setting negrflag=2 will make the routine consider negative r's the same as positive r's. Thus, the rose curve will have 2*b petals. Increasing r0 from 0 will make r positive more often than negative. This will also increase the number of petals from b to 2*b, but half of the petals will be small and half will be large. The best way to see the effects of the parameter choices is to use the "draw curves" setting of the "color by" parameter. Here, the image isn't a fractal, but rather the polar curve determined by a, b, n, r0, the chosen function, and the negative r flag. The other "color by" settings use polar curves to color fractals. There are 2 basic rendering methods: how close the orbit comes to the polar curve, and how often the orbit is inside the polar curve. The minimum approach method also has a few variants: iteration number when the minimum was reached, and angle of #z when the minimum was reached. } comment { ; copyright Kerry Mitchell 15nov98 Astroid The astroid is a figure from analytic geometry, resembling a four- pointed star with concave sides. Its defining equation is: x^(2/3) + y^(2/3) = a^(2/3) where a determines the size of the figure, similar to the radius of a circle. This equation can be generalized by changing the exponent of 2/3 to any value n. If n is between 0 and 1, the figure resembles the standard astroid. The sides go from being straight lines for n=1 to lying atop of the coordinates axes as n approaches 0. For n>1, the figure becomes convex, and is a circle for n=2. As n approaches infinity, the figure approaches a square. The astroid is further generalized by allowing it to be placed somewhere other than at the center of the complex plane. The figure's orientation and location in the plane are determined by a "center" and "rotation angle" parameters. This generalized astroid is the basis of this coloring scheme. As with other plane figures, the astroid can be compared to the Mandelbrot and Julia orbits. The image can be colored by how close the orbit comes to the astroid or how often the orbit lands inside the astroid. A final choice of the "colorby" parameter draws the astroid only, so the effects of the parameter choices can be seen. } comment { ; narrative copyright Kerry Mitchell 25nov98 Seeing Stars Most fractal images involve circles in some respect: either stopping the iteration when the orbit moves outside of a given circle, or coloring by how close the orbit comes to a certain circle, or some variation. This formula uses a 5 point star instead of a circle. The fractal can be colored by how close the orbit comes to a star, or how often the orbit lands inside the star. The star is represented by the 5 outer points. These are equally spaced on a circle. The center and size of the circle are user-specified, as is the rotation angle of the star. How z at any iteration relates to the star (inside, outside, how close) is determined by looking at each of the 10 sides, one at a time. Each side can be represented by a line A*x + B*y + C = 0, where A, B, and C come from the coordinates of the 2 outer points that are joined to make the side. Given the numbers A, B, and C, the quantity q = A*real(z) + B*imag(z) + C is computed. If q is positive, then z is on one side of the line, and if q is negative, then z is on the other side of the line. If |q| is very small, that means that z is very close to that side of the star. Taking the signs of q for all 10 sides will determine if z is inside or outside of the star. Using the smallest value of |q| gives the distance from z to the star. To see this in action, use the "draw star" setting of the "color by" parameter. The outline of a star will be drawn, with the position, orientation and size that you choose. This setting along with the "minimum distance" setting, uses a logarithmic transfer function from distance to #index. This helps highlight the star without needing to find out if the point is exactly on the star or not. The "in fraction" will count how many times the orbit lands inside the star, then set #index to the ratio of inside hits to total iterations for that pixel. } comment { ; copyright Kerry Mitchell 20dec98 Conic Sections Conic sections are sections of cones. Specifically, take a double-ended cone, like 2 funnels placed tip-to-tip. Then, form the intersection of the (double) cone with a plane. The intersection, usually one or two curves, is a conic section. Conic sections can be a point, one line, two lines, a parabola, an ellipse, a circle, or a hyperbola, depending on the orientation of the plane relative to the cone. Analytically, they can all be expressed by the same formula: Ax^2 + Bx + Cy^2 + Dy + Exy + F = 0, where the parameters A through F determine the shape of the section, and x and y are the 2 spatial coordinates. For example, the line y=x can be represented as x - y = 0, or A = 0, B = 1, C = 0, D = -1, E = 0, F = 0. A circle centered at (1,0) with a radius of 2 would have the equation (x - 1)^2 + y^2 = 4, or x^2 - 2x + y^2 - 3 = 0, giving A = 1, B = -2, C = 1, D = 0, E = 0, F = -3. How can these shapes be used to render fractals? Firstly, the "draw section" setting simply draws the section determined by the six parameters A - F, to give the user an idea of how the parameter choices affect the section generated. These coloring formulas record how the orbit interacts with the given section. In "Conic Sections", all six section parameters are input to determine the curve. Then, the image can be colored according to the distance of the orbit's approach to the section or how often the orbit landed inside the section. Here's how the "colorby" parameters work in "Conic Sections": "minimum distance": closest approach to section "iteration @ min": iteration number at minimum approach "angle @ min": polar angle of z at minimum approach "maximum distance": furthest approach from section "iteration @ max": iteration number at maximum approach "angle @ max": polar angle of z at maximum approach "in fraction": how many times orbit was inside section, as a fraction of the total number of iterations "in/out ratio": ration of number of times orbit was inside the section to the number of times the orbit was outside of the section "lsb binary": builds up a binary index, adding a bit to the right for each iteration, "1" if the orbit was inside the section and "0" if it was outside "msb binary": builds up a binary index, adding a bit to the left for each iteration, "1" if the orbit was inside the section and "0" if it was outside "draw section": simply draws the chosen conic section While using all six section parameters is very powerful, it is less than user-friendly. Hence "Conic Lite". Here, the user chooses the type of section, and only enters the relevant geometric characteristics. The choices are: "line": enter angle of line to horizontal, and point through which line passes "circle": enter center and radius "ellipse" enter semi-major and semi-minor axes and center "horiz. hyperbola": enter semi-major and semi-minor axes and center "vert. hyperbola": enter semi-major and semi-minor axes and center The coloring options have also been reduced, to: "minimum distance": closest approach to section "iteration @ min": iteration number at minimum approach "angle @ min": polar angle of z at minimum approach "draw section": simply draws the chosen conic section The "2 Sections" coloring method combines the results from 2 conic sections into one. The choices of sections are the same as in "Conic Lite". At each iteration, the distance from the first curve (call it x) and the distance from the second curve (call it y) are computed. From these, an overall distance metric is determined: "x^2 + y^2": standard magnitude "|x| + |y|": manhattan metric "|x*y|": hyperbolic "|x-y|": umm, call it "|x-y|" When the chosen metric is at its smallest value, the x and y values are combined into a complex number, zerrmin. Also, the iterate z is stored as zmin. The coloring options ("color by" parameter) are: "2 curve min": magnitude of zerrmin "2 curve angle": polar angle of zerrmin "z angle @ min": polar angle of zmin "z mag @ min": magnitude of zmin "iteration # @ min": iteration number at metric minimum "draw section": simply draws the 2 sections The standard forms of the conic sections are given below. With a bit of algebraic twiddling, they can be transformed into the general form, for use in the coloring formulas. point (h,k) x=h, y=k; or (x-h)^2 + (y-k)^2 = 0 [circle of radius 0 centered at (h,k)]. vertical line through (h,k): x=h non-vertical line with slope m, through (h,k): y-k = m*(x-h) parabola, opening up or down, with vertex at (h,k): y-k = 4*p*(x-h)^2 [p determines width; +/up, -/down] parabola, opening left or right, with vertex at (h,k): x-h = 4*p*(y-k)^2 [p determines width; +/right, -/left] ellipse centered at (h,k), semimajor axis alpha, semiminor axis beta: (x-h)^2/alpha^2 + (y-k)^2/beta^2 = 1 circle centered at (h,k), with radius r: (x-h)^2 + (y-k)^2 = r^2 hyperbola centered at (h,k), semimajor axis alpha, semiminor axis beta, opening left/right: (x-h)^2/alpha^2 - (y-k)^2/beta^2 = 1 hyperbola centered at (h,k), semimajor axis alpha, semiminor axis beta, opening up/down: (y-k)^2/beta^2 - (x-h)^2/alpha^2 = 1 coordinate rotation, from (u,v) to (x,y), through an angle theta: u = x*cos(theta) + y*sin(theta) v = -x*sin(theta) + y*cos(theta) [rotating sections is how to generate non-zero E parameters] } comment { ; narrative copyright Kerry Mitchell 06feb99 The Bubble Method The bubble method is an extension of Fractint's bof60 scheme. In bof60, the interior of the fractal is colored by how close the iterate comes to the origin. In the bubble method, a specific value is set as the threshold. At each duration, the magnitude of the iterate is compared to the threshold. If the current magnitude is smaller, it becomes the new threshold level. The effect is to cover the fractal with "bubbles", circles the radius of the threshold. Below a certain threshold value, the image is a dust of small, disconnected bubbles. At a particular theshold value, which varies with the parameter c, the circles all touch. Beyond this, the circles squish into each other, like mounds of soap bubbles. When a new threshold level is set, the iterate and the iteration number are stored. At bailout, the final new values are available for use in the coloring. The index value is a weighted average of the final threshold, the iteration number when the last threshold was set, and the polar angle of the last threshold's iterate. The weights of each contribution can be individually set using the "mag. weight", "iteration weight", and "angle weight" parameters. Using only the magnitude to color results in a series of concentric circles, and using only the angle results in a radial color pattern. Combining equal amounts of magnitude and angle gives a swirl effect. Changing the angle weight to a negative value will reverse the direction of the swirl. A judicious choice of color density will eliminate the branch cuts that can be seen with the swirls. } bubbles { ; Kerry Mitchell 06feb98 ; ; colors by the "bubbles" variation of ; Fractint's bof60 and bof61 methods ; init: float weighttotal=@weightr+cabs(@weightt)+@weighti if(weighttotal==0.0) weighttotal=1.0 endif float wr=@weightr/weighttotal float wt=cabs(@weightt)/weighttotal float wi=@weighti/weighttotal float twopi=2.0*#pi float rz=0.0 float rmin=@threshold float tmin=0.0 zmin=(0.0,0.0) bool minset=false float iter=0.0 float itermin=0.0 loop: iter=iter+1 rz=cabs(#z) if(rz=@fin ; #index=log(iter) ;endif default: title="Bubbles" param threshold caption="bubble radius" default=1.0 min=0.0 endparam param weightr caption="mag. weight" default=1.0 hint="relative weight of magnitude component" endparam param weightt caption="angle weight" default=1.0 hint="relative weight of polar angle" endparam param weighti caption="iteration weight" default=1.0 hint="relative weight of iteration count" endparam ; param fin ; caption = "4 fin de motif " ; default = 75 ;endparam } comment { ; narrative copyright Kerry Mitchell 21feb99 Range In the range coloring schemes, the pixels are only colored when the iterate (or a component of it) falls within a specified range. (Otherwise, the #solid flag is set to true.) The range is given in terms of the center and width. For example, setting the center to 1.0 and the range to 0.1 would yield a range of 0.95 to 1.05. The simplest case is shown in the "Range Lite" formula. Here, the orbit is monitored until the magnitude of the iterate falls within a specified range. When this occurs, that iterate is saved. Upon bailout (either escape or maximum iterations), the point can be colored according to either the magnitude or the polar angle of the iterate. Either the first iterate to fall into the range or the last iterate can be used. The difference is in the overlapping of the rings of color. Using the first iterate gives the appearance of the "earlier" rings (from lower iteration numbers) stacked on top of the "later" rings. Using the laster iterate reverses the order of the stacking. Depending on the range chosen, the results can be circular rings, pinched loops (figure "8"), or open loops. The shapes are definitely non-fractal, but are assembled in such a way to recover the underlying fractal structure. This method opens itself up to many variations, which can be explored using the full "Range" coloring. In essence, some variable is monitored to see when it falls in the specified range. When it does, another variable is used for coloring. There are several options for the "range variable", the variable that is checked against the range: the magnitude of z, its real or imaginary part, and its polar angle. Plus, any of the standard functions can be used on z, and the real or imaginary parts used. A final choice, "heart", is a combination of the magnitude and polar angle, that covers the image with heart shapes. The same choices are available for the "coloring variable", the variable used to set #index. Since #index takes on values from 0.0 to 1.0, the coloring variable may need adjusting before being used as the #index. If the coloring variable is the same as the range variable, then the range parameters are used to scale the variable into #index. Otherwise, the coloring variable can be easily scaled into the #index variable. Specifically, #index = slope * scale_function(coloring_variable) + offset. For example, if real(z) is used as the coloring variable, then the tanh() function can scale real(z) to -1.0 to 1.0. Then, using slope of 0.5 and an offset of 0.5 will give the final range of 0.0 to 1.0 for the #index. Finally, the "color by" parameter determines which iterate or iterates are used in the coloring. Using the "first" or "last" settings will vary the apparant stacking of the color rings. The "average" setting will cause all the coloring variables for which the range variables fall into the range to be averaged together, and that mean used for the coloring. If the range width is set fairly small, then there won't be much difference between "average" and "first" or "last". But there can be a quite significant change if the range width is large. The last choice, "fraction in range", simply uses the ratio of number of times the range variable falls within the range, to the total number of iterations for that pixel. }