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.
}