Andrew, you might like to check out my ray-traced fractals made from infinite reflections inside a stack of mirrored spheres. I think these pictures show something impossible to reproduce in the real world, because of the perturbation introduced by a real camera. This seems related to the uncertainty principle, I guess.... The virtual camera overcomes this obstacle. Best regards, Miguel Fliguer . Buenos Aires, Argentina Franktal Gallery - http://www.geocities.com/franktal2002
From: "Andrew Coppin" <orphi69@hotmail.com> <snip> I've come up with the "hall of mirrors" analogy. Have you ever been to a department store where they have mirrors on the columns supporting the roof? If you stand between two columns (assuming both have mirrors), you can see an infinite number of reflections of yourself! But, of course, the mirrors are always slightly greenish (never any other colou... mmm....) and never completely flat.
The Julia sets are the same. It seems that the infinite progression of spirals/forks/dust are mirror images of one single such feature.
_________________________________________________________________ Chat with friends online, try MSN Messenger: http://messenger.msn.com
At 02:29 20/05/2002, Franktal Gallery wrote:
Andrew, you might like to check out my ray-traced fractals made from infinite reflections inside a stack of mirrored spheres. I think these pictures show something impossible to reproduce in the real world, because of the perturbation introduced by a real camera. This seems related to the uncertainty principle, I guess.... The virtual camera overcomes this obstacle.
I think it's probably more likely due to the difficulty of manufacturing optics, mirrored spheres, and CCDs/film emulsions to the required precision/resolution. My fairly ancient box would beg for mercy if I attempted something like these (which is not to say I don't want to); so I've been looking at such "inversion groups" (aka. "kleinian groups") with Fractint: 6Klein_Group(XYAXIS){ pi3=pi/3 c1=(0,2) c2=2*(sin(pi3)+flip(cos(pi3))) c3=2*(sin(2*pi3)+flip(cos(2*pi3))) c4=(0,-2) c5=2*(sin(4*pi3)+flip(cos(4*pi3))) c6=2*(sin(5*pi3)+flip(cos(5*pi3))) z=pixel inside=1: IF(cabs(z-c1)<1) z=conj(1/(z-c1))+c1 inside=1 ELSEIF(cabs(z-c2)<1) z=conj(1/(z-c2))+c2 inside=1 ELSEIF(cabs(z-c3)<1) z=conj(1/(z-c3))+c3 inside=1 ELSEIF(cabs(z-c4)<1) z=conj(1/(z-c4))+c4 inside=1 ELSEIF(cabs(z-c5)<1) z=conj(1/(z-c5))+c5 inside=1 ELSEIF(cabs(z-c6)<1) z=conj(1/(z-c6))+c6 inside=1 ELSE inside=0 ENDIF inside} In this example the accumulation points (where the images pile up on each other) all lie on a single circle. This is an accident due to the symmetry of the original mirrors' arrangement. In general, the curve is "nowhere-differentiable" in the jargon of a mid-1960s text where I first came across the subject. Modern terminology would use "fractal". I've just started on another where each pixel is coloured according to how many reflections a ray starting from that point goes through before escaping the system, but at the moment it's still a bit buggy: threecircles1 { ; three circles located at the cube roots of 1 ; real(p1) specifies their common radius - note that they're tangent to ; each other when real(p1)=sqrt(3)/2. ; ; From each point z in the complex plane a test particle is launched at ; an angle of imag(p1) to the positive real axis. Thus, for imag(p1)=0, ; the test particle will travel to the right. ; ; Each time the particle encounters a circle, it is reflected in the ; traditional manner and a count is kept of the number of such ; reflections. This count is used to colour the original point if and ; when the particle escapes towards infinity - that is to say, when the ; three circles no longer obstruct its course. ; ; First, we need to establish the centres of the three circles. centre1=1 centre2=exp(flip(2*pi/3)) centre3=centre2*centre2 ; Reckon this is faster than another exp()? rho=real(p1) theta=imag(p1) direction=cos(theta)+i*sin(theta) ; We'll use a vector representaion ; of the direction z = pixel trapped=(|z-centre1|<rho*rho || |z-centre2|<rho*rho || |z-centre3|<rho*rho) ; For efficiency, we see if z is _inside_ a circle. If it is, we can ; predict how long it will take to escape :-) ; Note also that since Fractint's || operator is nonstandard, we use ; rho*rho instead of rho. : ; End of initialisation section. Now beginning the loop. if(trapped) escaped=0 ; We'll continue to iterate, though - so that the insides of ; the circles really are classified as "inside" else ; Let's get dangerous ; Right, we have a ray that passes through the point z in the direction ; theta. Finding the intersections (if any) of this ray with a circle ; involves finding the solutions of a certain quadratic with real ; coefficients. If the quadratic has two real roots, then the ray cuts the ; circle. If it has one real root (necessarily of multiplicity two) then ; the ray is tangent to the circle. And if both roots are complex, then ; the ray misses the circle completely. escaped=1 ; As far as we know at the moment. hit=9999 ; Meaningless when escaped==1 ;Examining circle 1 coefA = |direction| coefB = real(z-centre1)*real(direction)+imag(z-centre1)*imag(direction) coefC = |z-centre1|-rho*rho discriminant=coefB*coefB-coefA*coefC ; If discriminant==0, then the ray is tangent to circle 1 - we won't ; count this as a "reflection" ; If discriminant<0, then the ray misses circle 1 completely. if(discriminant>0) ; Two solutions t1=(-coefB-sqrt(discriminant))/coefA t2=(-coefB+sqrt(discriminant))/coefA if(t1>0) ; If t1<0 then this hit is actually behind us escaped=0 ; Sorry, not this time. hit=t1 target=1 ; The first circle endif if(t2>0 && t2<t1) ; Hits t2 before hitting t1 escaped=0 hit=t2 target=1 endif endif ; Circle 2 ; coefA = |direction| is already known coefB = real(z-centre2)*real(direction)+imag(z-centre2)*imag(direction) coefC = |z-centre2|-rho*rho discriminant=coefB*coefB-coefA*coefC if(discriminant>0) t1=(-coefB-sqrt(discriminant))/coefA t2=(-coefB+sqrt(discriminant))/coefA if(t1>0 && t1<hit) escaped=0 hit=t1 target=2 endif if(t2>0 && t2<t1 && t2<hit) escaped=0 hit=t2 target=2 endif endif ; Circle 3 coefB = real(z-centre3)*real(direction)+imag(z-centre3)*imag(direction) coefC = |z-centre3|-rho*rho discriminant=coefB*coefB-coefA*coefC if(discriminant>0) t1=(-coefB-sqrt(discriminant))/coefA t2=(-coefB+sqrt(discriminant))/coefA if(t1>0 && t1<hit) escaped=0 hit=t1 target=3 endif if(t2>0 && t2<t1 && t2<hit) escaped=0 hit=t2 target=3 endif endif ; We now know when we hit a circle (hit) and which circle it is (target) ; The hit point is z+direction*hit, the normal at this point is ; z-centre?, which we normalise to a unit vector (un). ; ; We set z to the hit point, and the reflected vector is ; direction-2(direction.un)un if(target==1) un=(z-centre1)/sqrt(|z-centre1|) elseif(target==2) un=(z-centre2)/sqrt(|z-centre2|) else un=(z-centre3)/sqrt(|z-centre3|) endif r=direction-2*(real(direction)*real(un)+imag(direction)*imag(un))*un z=z+direction*hit direction=r endif ;bailout continue until we escape escaped==0 } threecircles2 { ; three circles located at the cube roots of 1 ; real(p1) specifies their common radius - note that they're tangent to ; each other when real(p1)=sqrt(3)/2. ; ; p2 specifies a point (the "radiant") from which test particles are ; launched. More precisely, every point in the complex plane emits a ; test particle, which travels directly away from p2 ; ; First, we need to establish the centres of the three circles. centre1=1 centre2=exp(flip(2*pi/3)) centre3=centre2*centre2 ; Reckon this is faster than another exp()? rho=real(p1) direction=pixel-p2 z = pixel trapped=(|z-centre1|<rho*rho || |z-centre2|<rho*rho || |z-centre3|<rho*rho) ; For efficiency, we see if z is _inside_ a circle. If it is, we can ; predict how long it will take to escape :-) ; Note also that since Fractint's || operator is nonstandard, we use ; rho*rho instead of rho. : ; End of initialisation section. Now beginning the loop. if(trapped) escaped=0 ; We'll continue to iterate, though - so that the insides of ; the circles really are classified as "inside" else ; Let's get dangerous ; Right, we have a ray that passes through the point z in the direction ; theta. Finding the intersections (if any) of this ray with a circle ; involves finding the solutions of a certain quadratic with real ; coefficients. If the quadratic has two real roots, then the ray cuts the ; circle. If it has one real root (necessarily of multiplicity two) then ; the ray is tangent to the circle. And if both roots are complex, then ; the ray misses the circle completely. escaped=1 ; As far as we know at the moment. hit=9999 ; Meaningless when escaped==1 ;Examining circle 1 coefA = |direction| coefB = real(z-centre1)*real(direction)+imag(z-centre1)*imag(direction) coefC = |z-centre1|-rho*rho discriminant=coefB*coefB-coefA*coefC ; If discriminant==0, then the ray is tangent to circle 1 - we won't ; count this as a "reflection" ; If discriminant<0, then the ray misses circle 1 completely. if(discriminant>0) ; Two solutions t1=(-coefB-sqrt(discriminant))/coefA t2=(-coefB+sqrt(discriminant))/coefA if(t1>0) ; If t1<0 then this hit is actually behind us escaped=0 ; Sorry, not this time. hit=t1 target=1 ; The first circle endif if(t2>0 && t2<t1) ; Hits t2 before hitting t1 escaped=0 hit=t2 target=1 endif endif ; Circle 2 ; coefA = |direction| is already known coefB = real(z-centre2)*real(direction)+imag(z-centre2)*imag(direction) coefC = |z-centre2|-rho*rho discriminant=coefB*coefB-coefA*coefC if(discriminant>0) t1=(-coefB-sqrt(discriminant))/coefA t2=(-coefB+sqrt(discriminant))/coefA if(t1>0 && t1<hit) escaped=0 hit=t1 target=2 endif if(t2>0 && t2<t1 && t2<hit) escaped=0 hit=t2 target=2 endif endif ; Circle 3 coefB = real(z-centre3)*real(direction)+imag(z-centre3)*imag(direction) coefC = |z-centre3|-rho*rho discriminant=coefB*coefB-coefA*coefC if(discriminant>0) t1=(-coefB-sqrt(discriminant))/coefA t2=(-coefB+sqrt(discriminant))/coefA if(t1>0 && t1<hit) escaped=0 hit=t1 target=3 endif if(t2>0 && t2<t1 && t2<hit) escaped=0 hit=t2 target=3 endif endif ; We now know when we hit a circle (hit) and which circle it is (target) ; The hit point is z+direction*hit, the normal at this point is ; z-centre?, which we normalise to a unit vector (un). ; ; We set z to the hit point, and the reflected vector is ; direction-2(direction.un)un if(target==1) un=(z-centre1)/sqrt(|z-centre1|) elseif(target==2) un=(z-centre2)/sqrt(|z-centre2|) else un=(z-centre3)/sqrt(|z-centre3|) endif r=direction-2*(real(direction)*real(un)+imag(direction)*imag(un))*un z=z+direction*hit direction=r endif ;bailout continue until we escape escaped==0 } ...and while we're on the subject of Fractint formulae, can someone explain why it is that it's still possible after all this time for BoF to still contain things that haven't been reproduced in Fractint yet? You'd have thought that the two-dimensional Newton systems described therein would've been: twodnewton{ h = real(p1) m = imag(p1) z=pixel: oz=z x=real(z),y=imag(z) f=2*x-y-m*(x-x*x) g=2*y-x-m*(y-y*y) fx=2-m*(1-2*x) gy=2-m*(1-2*y) delta =(-g-f*gy)/(fx*gy-1) epsilon=(-f-g*fx)/(fx*gy-1) nx=x+h*delta ny=y+h*epsilon z=nx+flip(ny) |oz-z|>.001 } (E.g. h=0.5, m=2) Morgan L. Owens "I'm gonna build a room that echoes."
From: "Morgan L. Owens" Sent: Monday, May 20, 2002 9:38 AM [Way too much interesting stuff (Circles formulas) snipped...]
...and while we're on the subject of Fractint formulae, can someone explain why it is that it's still possible after all this time for BoF to still contain things that haven't been reproduced in Fractint yet? You'd have thought that the two-dimensional Newton systems described therein would've been:
twodnewton{ h = real(p1) m = imag(p1) z=pixel: oz=z x=real(z),y=imag(z) f=2*x-y-m*(x-x*x) g=2*y-x-m*(y-y*y) fx=2-m*(1-2*x) gy=2-m*(1-2*y) delta =(-g-f*gy)/(fx*gy-1) epsilon=(-f-g*fx)/(fx*gy-1) nx=x+h*delta ny=y+h*epsilon z=nx+flip(ny) |oz-z|>.001 }
(E.g. h=0.5, m=2)
Arrgh! Another chance to worldwide fame missed! ;-) As it happens, this - and the Voltera-Lottka system - where among the first formulas I tried when I first met Fractint in the German language edition of "Fractal Creations" back in '92. ("What? There are really fractals they *haven't* implemented?") Well, publish or perish... 8-/ (BTW, a Newton formula of a system of 2 real equations - not this one - was once published by Sylvie Gallet.) Concerning your "Circles" formulas: Some time ago I stumbled over "Wada Basins in Chaotic Scattering" and the following websites: http://webs1152.im1.net/~dsweet/Spheres/ ...and on Paul Bourke's site: http://astronomy.swin.edu.au/~pbourke/fractals/wada/ Regards, Gerald P.S. So here ("Who needs POV-Ray?") are the respective Fractint- formulas: ------------------------- WADA.FRM ---------------------------- TetraSpheres {;Four mirrored spheres at the corners of a ;tetrahedron, each touching the other three. ;( Viewing direction is positive z ) ;colouring: number of iterations ;periodicity=no ;p1r: z-depth of viewing ray's start (try -1.5 or 0.5) ; ;Spheres' centers xy1 = (-1,-0.577350269189625) ;(-1, -1/sqrt(3)) xy2 = (1,-0.577350269189625) ;( 1, -1/sqrt(3)) xy3 = (0,1.15470053837925) ;( 0, 2/sqrt(3)) ;xy4 = (0,0) z123 = -0.408248290463863 ;(-1/sqrt(6), 0) z4 = 1.22474487139159 ;( sqrt(3/2), 0) pxy = pixel, pz = real(p1) vxy = 0, vz = 1: isect = 0, dist = 999999 dz = z123 - pz, vzdz = vz*dz, dzmod = |dz| dxy = xy1 - pxy tmp1 = real(vxy)*real(dxy) + imag(vxy)*imag(dxy) + vzdz IF (tmp1 > 0) tmp2 = |dxy| + dzmod - |tmp1| IF (tmp2 < 1) dist = tmp1 - sqrt(1-tmp2) xy0 = xy1, z0 = z123 isect = 1 ENDIF ENDIF dxy = xy2 - pxy tmp1 = real(vxy)*real(dxy) + imag(vxy)*imag(dxy) + vzdz IF (tmp1 > 0) tmp2 = |dxy| + dzmod - |tmp1| IF (tmp2 < 1) tmp1 = tmp1 - sqrt(1-tmp2) IF (tmp1 < dist) dist = tmp1 xy0 = xy2, z0 = z123 isect = 1 ENDIF ENDIF ENDIF dxy = xy3 - pxy tmp1 = real(vxy)*real(dxy) + imag(vxy)*imag(dxy) + vzdz IF (tmp1 > 0) tmp2 = |dxy| + dzmod - |tmp1| IF (tmp2 < 1) tmp1 = tmp1 - sqrt(1-tmp2) IF (tmp1 < dist) dist = tmp1 xy0 = xy3, z0 = z123 isect = 1 ENDIF ENDIF ENDIF dxy = -pxy, dz = z4 - pz tmp1 = real(vxy)*real(dxy) + imag(vxy)*imag(dxy) + vz*dz IF (tmp1 > 0) tmp2 = |dxy| + |dz| - |tmp1| IF (tmp2 < 1) tmp1 = tmp1 - sqrt(1-tmp2) IF (tmp1 < dist) dist = tmp1 xy0 = 0, z0 = z4 isect = 1 ENDIF ENDIF ENDIF IF (isect) pxy = pxy + dist*vxy, pz = pz + dist*vz nxy = pxy - xy0, nz = pz - z0 tmp1 = sqrt(|nxy|+|nz|), nxy = nxy/tmp1, nz = nz/tmp1 tmp1 = (real(vxy)*real(nxy)+imag(vxy)*imag(nxy)+vz*nz)*2 vxy = vxy - tmp1*nxy, vz = vz - tmp1*nz ;tmp1 = sqrt(|vxy|+|vz|), vxy = vxy/tmp1, vz = vz/tmp1 ENDIF isect == 1 } TetraSpheresBas {;Four mirrored spheres at the corners of a ;tetrahedron, each touching the other three. ;( Viewing direction is positive z ) ;colouring: on which side of the tetrahedron the ray escapes ;outside=summ, periodicity=no ;p1r: z-depth of viewing ray's start (try -1.5 or 0.5) ; ;Spheres' centers xy1 = (-1,-0.577350269189625) ;(-1, -1/sqrt(3)) xy2 = (1,-0.577350269189625) ;( 1, -1/sqrt(3)) xy3 = (0,1.15470053837925) ;( 0, 2/sqrt(3)) ;xy4 = (0,0) z123 = -0.408248290463863 ;(-1/sqrt(6), 0) z4 = 1.22474487139159 ;( sqrt(3/2), 0) ;Unit vectors towards tetrahedron's sides e1xy = (0.816496580927725,0.816496580927725) ;(sqrt(2/3),sqrt(2/3)) e2xy = (-0.816496580927725,0.816496580927725);(-sqrt(2/3), sqrt(2/3)) e3xy = (0,-0.942809041582067) ;(0,-2*sqrt(2)/3) ;e4xy = (0,0) ;e123z = (1/3, 0) ;e4z = (-1, 0) pxy = pixel, pz = real(p1) vxy = 0, vz = j = 1: isect = 0, dist = 999999 dz = z123 - pz, vzdz = vz*dz, dzmod = |dz| dxy = xy1 - pxy tmp1 = real(vxy)*real(dxy) + imag(vxy)*imag(dxy) + vzdz IF (tmp1 > 0) tmp2 = |dxy| + dzmod - |tmp1| IF (tmp2 < 1) dist = tmp1 - sqrt(1-tmp2) xy0 = xy1, z0 = z123 isect = 1 ENDIF ENDIF dxy = xy2 - pxy tmp1 = real(vxy)*real(dxy) + imag(vxy)*imag(dxy) + vzdz IF (tmp1 > 0) tmp2 = |dxy| + dzmod - |tmp1| IF (tmp2 < 1) tmp1 = tmp1 - sqrt(1-tmp2) IF (tmp1 < dist) dist = tmp1 xy0 = xy2, z0 = z123 isect = 1 ENDIF ENDIF ENDIF dxy = xy3 - pxy tmp1 = real(vxy)*real(dxy) + imag(vxy)*imag(dxy) + vzdz IF (tmp1 > 0) tmp2 = |dxy| + dzmod - |tmp1| IF (tmp2 < 1) tmp1 = tmp1 - sqrt(1-tmp2) IF (tmp1 < dist) dist = tmp1 xy0 = xy3, z0 = z123 isect = 1 ENDIF ENDIF ENDIF dxy = -pxy, dz = z4 - pz tmp1 = real(vxy)*real(dxy) + imag(vxy)*imag(dxy) + vz*dz IF (tmp1 > 0) tmp2 = |dxy| + |dz| - |tmp1| IF (tmp2 < 1) tmp1 = tmp1 - sqrt(1-tmp2) IF (tmp1 < dist) dist = tmp1 xy0 = 0, z0 = z4 isect = 1 ENDIF ENDIF ENDIF IF (isect) pxy = pxy + dist*vxy, pz = pz + dist*vz nxy = pxy - xy0, nz = pz - z0 tmp1 = sqrt(|nxy|+|nz|), nxy = nxy/tmp1, nz = nz/tmp1 tmp1 = (real(vxy)*real(nxy)+imag(vxy)*imag(nxy)+vz*nz)*2 vxy = vxy - tmp1*nxy, vz = vz - tmp1*nz ;tmp1 = sqrt(|vxy|+|vz|), vxy = vxy/tmp1, vz = vz/tmp1 ELSE col = 5 dist = 999999 pz3 = pz/3, vz3 = vz/3 ;pz * e123z, vz * e123z tmp1 = real(vxy)*real(e1xy) + imag(vxy)*imag(e1xy) + vz3 IF (tmp1 > 0) tmp2 = real(pxy)*real(e1xy) + imag(pxy)*imag(e1xy) + pz3 dist = (1.5-tmp2)/tmp1 col = 1 ENDIF tmp1 = real(vxy)*real(e2xy) + imag(vxy)*imag(e2xy) + vz3 IF (tmp1 > 0) tmp2 = real(pxy)*real(e2xy) + imag(pxy)*imag(e2xy) + pz3 tmp1 = (1.5-tmp2)/tmp1 IF (tmp1 < dist) dist = tmp1 col = 2 ENDIF ENDIF tmp1 = real(vxy)*real(e3xy) + imag(vxy)*imag(e3xy) + vz3 IF (tmp1 > 0) tmp2 = real(pxy)*real(e3xy) + imag(pxy)*imag(e3xy) + pz3 tmp1 = (1.5-tmp2)/tmp1 IF (tmp1 < dist) dist = tmp1 col = 3 ENDIF ENDIF IF (vz < 0) IF ((-1.5-pz)/vz < dist) col = 4 ENDIF ENDIF z = col - j ENDIF j = j + 1 isect == 1 } ---------------------------------------------------------------
At 11:55 22/05/2002, Gerald K. Dobiasovsky wrote:
P.S. So here ("Who needs POV-Ray?") are the respective Fractint- formulas:
I think I'm outclassed. I mean, here's me still tinkering in two dimensions... Next thing to do would be to parameterise things a bit... I've touched up mine a bit, and added a few more. This time I've even chucked in a coupla pars. Morgan L. Owens "I need some thoughts that are new." trilattice { ; Something I'm not likely to see this winter. ; Version 2001 Patchlevel 8 reset=2001 type=formula formulafile=klein.frm formulaname=Klein_tri_lattice passes=1 center-mag=0/0/0.6666667 float=y maxiter=1023 inside=255 outside=tdis periodicity=0 colors=000ccc<3>nnnqqqtttwwwzzz<4>IIz99z00z<9>bbOffKjjG<3>zz0<9>zO0zK0zG\ 0<3>z00<9>O0bK0fG0j<3>00z<9>0bO0fK0jG<3>0z0<9>bObfKfjGj<3>z0z<9>`0`Y0YV0\ V<2>N0NK0KJ1L<8>8Ia7Kc5Me<2>2Sk0Um0Vm<8>0em0fm0hm<2>0km0mm0mm<8>0gu0gu0f\ v<3>0cz<9>bqzfrzjtz<3>zzz<25>zhCzgAzf8<2>zd2zc0zd0<8>zq0zr0zt0<3>zz0<9>z\ O0zK0zG0<3>z00<14>ZZZ } trilattice2 { ; Version 2001 Patchlevel 8 reset=2001 type=formula formulafile=klein.frm formulaname=Klein_tri_lattice passes=d center-mag=0/0/0.6666667 float=y maxiter=1023 inside=255 outside=atan periodicity=0 colors=@altern.map } trilattice3 { ; Superdoily ; Version 2001 Patchlevel 8 reset=2001 type=formula formulafile=klein.frm formulaname=Klein_tri_lattice center-mag=0/0/0.6666667 float=y maxiter=5 inside=zmag outside=0 periodicity=0 colors=@altern.map } trilattice4 { ; Uniqueness ; Version 2001 Patchlevel 8 reset=2001 type=formula formulafile=klein.frm formulaname=Klein_tri_lattice passes=t center-mag=-15.9676/10.6848/0.07415467 float=y maxiter=1023 inside=255 invert=0.5/0/0 periodicity=0 colors=@default.map } frm:3Klein_Group(XAXIS){ ang=2*pi/3 c1=exp((0,0)*ang) c2=exp((0,1)*ang) c3=exp((0,2)*ang) r=sqrt(3)/2 rr=r*r z=pixel: inside=0 if(|z-c1|<rr) z=r*conj(r/(z-c1))+c1 inside=1 elseif(|z-c2|<rr) z=r*conj(r/(z-c2))+c2 inside=1 elseif(|z-c3|<rr) z=r*conj(r/(z-c3))+c3 inside=1 endif inside} frm:6Klein_Group(XYAXIS){ ang=pi/3 c1=2*exp((0,0)*ang) c2=2*exp((0,1)*ang) c3=2*exp((0,2)*ang) c4=2*exp((0,3)*ang) c5=2*exp((0,4)*ang) c6=2*exp((0,5)*ang) z=pixel: inside=0 IF(|z-c1|<1) z=conj(1/(z-c1))+c1 inside=1 ELSEIF(|z-c2|<1) z=conj(1/(z-c2))+c2 inside=1 ELSEIF(|z-c3|<1) z=conj(1/(z-c3))+c3 inside=1 ELSEIF(|z-c4|<1) z=conj(1/(z-c4))+c4 inside=1 ELSEIF(|z-c5|<1) z=conj(1/(z-c5))+c5 inside=1 ELSEIF(|z-c6|<1) z=conj(1/(z-c6))+c6 inside=1 ENDIF inside} frm:7Klein_Group(XYAXIS){ ang=pi/3 c1=0 c2=1 c3=exp((0,1)*ang) c4=exp((0,2)*ang) c5=exp((0,3)*ang) c6=exp((0,4)*ang) c7=exp((0,5)*ang) r=1/2 rr=r*r z=pixel: inside=0 if(|z-c1|<rr) z=r*conj(r/(z-c1))+c1 inside=1 elseif(|z-c2|<rr) z=r*conj(r/(z-c2))+c2 inside=1 elseif(|z-c3|<rr) z=r*conj(r/(z-c3))+c3 inside=1 elseif(|z-c4|<rr) z=r*conj(r/(z-c4))+c4 inside=1 elseif(|z-c5|<rr) z=r*conj(r/(z-c5))+c5 inside=1 elseif(|z-c6|<rr) z=r*conj(r/(z-c6))+c6 inside=1 elseif(|z-c7|<rr) z=r*conj(r/(z-c7))+c7 inside=1 endif inside} frm:Klein_squ_lattice(XYAXIS){ r=1/2 rr=r*r z=pixel: inside=0 c=round(z) if(|z-c|<rr) z=r*conj(r/(z-c))+c inside=1 endif inside} frm:Klein_tri_lattice(XYAXIS){ ang=pi/3 r=1/2 rr=r*r z=pixel t1=sin(ang) t2=tan(ang) t3=exp(flip(ang)) : inside=0 m = round(imag(z)/t1) n = round(real(z)-imag(z)/t2) c0=n+m*t3 c1=n+(m-1)*t3 c2=n+(m+1)*t3 c3=(n-1)+m*t3 c4=(n+1)+m*t3 if(|z-c0|<rr) z=r*conj(r/(z-c0))+c0 inside=1 elseif(|z-c1|<rr) z=r*conj(r/(z-c1))+c1 inside=1 elseif(|z-c2|<rr) z=r*conj(r/(z-c2))+c2 inside=1 elseif(|z-c3|<rr) z=r*conj(r/(z-c3))+c3 inside=1 elseif(|z-c4|<rr) z=r*conj(r/(z-c4))+c4 inside=1 endif inside}
At 01:28 23/05/02 +1200, you wrote:
At 11:55 22/05/2002, Gerald K. Dobiasovsky wrote:
P.S. So here ("Who needs POV-Ray?") are the respective Fractint- formulas:
I think I'm outclassed. I mean, here's me still tinkering in two dimensions... Next thing to do would be to parameterise things a bit...
.... the good old times are back.. (1995-1997)
Don't mean to be rude, but . . . . . . could we "get at" something else, please ??? What about comments from readers re what might be included on Jim's CD, now that he has all the files, and has obtained (I assume) from PNL all the lists of duplicate names, similkar names, etc. One thing that I would find extremely useful (as I can recall a particular image frequently better than the name Jim gave it) would be several different cross-referenced Indexes to the "1700+" images: 1) by Name (including Date, Par type, generating equation type, subject matter), and from there to 2) by Subject (eg., "Flower"-like, "anthropomorphic", Snowmen/women, the 10-12 images which have double/twinned dwarves;etc.), 3) by "PAR type" by which I mean what Fractint PAR family was used as Jim's starting point: foe example, it would really be nice to have a list of all the images resulting from the 12 equations which together form a "PAR Family" Jim has taught us to call "Ikenaga Functions"; other examples abound of seemingly obsure/trivial PAR's which have turned out to be incredibly-rich generators of visually-pleasing and mathematically-interesting FOTD's); 4) by "generating function" (e.g., classify images according to what exact equation was used as Jim's starting point: ie, what exact [simple] function - like Mandelbrot's - Jim used, with increasing in complexity in # of terms, # of exponents, type of exponents, etc -- then we have a "roadmap" (or cookbook) of sorts telling us how to produce the kind of image we want to, and since Jim always comments on the PAR he used, and the specific equation, such an Index would specify each image's connection to the underlying mathematics - which IMHO, is the real beauty of Jim's work; 5) most important of all, by "Type"(ie., "Juli-Brot", mandeloid, Julia slices, etc), Freed ----- Original Message ----- From: "Guy Marson" <guy.marson@mnhn.lu> To: <fractint@mailman.xmission.com> Sent: Wednesday, May 22, 2002 2:53 PM Subject: Re: [Fractint] At it again...
At 01:28 23/05/02 +1200, you wrote:
At 11:55 22/05/2002, Gerald K. Dobiasovsky wrote:
P.S. So here ("Who needs POV-Ray?") are the respective Fractint- formulas:
I think I'm outclassed. I mean, here's me still tinkering in two dimensions... Next thing to do would be to parameterise things a bit...
....
the good old times are back.. (1995-1997)
_______________________________________________ Fractint mailing list Fractint@mailman.xmission.com http://mailman.xmission.com/cgi-bin/mailman/listinfo/fractint
----- Original Message ----- From: "bmc1" <bmc1@airmail.net> Sent: Wednesday, May 22, 2002 2:54 PM Subject: Re: [Fractint] At it again... Don't mean to be rude, but . . . . . . could we "get at" something else, please ??? What about comments from readers re what might be included on Jim's CD, now that he has all the files, and has obtained (I assume) from PNL all the lists of duplicate names, similkar names, etc. How tastes vary! Personally I'm not interested in "getting at" this sort of trivia. I trust Jim's taste, and I'm sure he doesn't need advice from me regarding what is, after all, his own personal statement.. At least he hasn't asked me, so far. Besides, I expect that he will be asking for cold cash for his efforts, so why would I do any of the work for him? :-) John W.
Simplistic ad hominem comments, ebven in the passive voice, are boring. ----- Original Message ----- From: "John W." <juanw@shaw.ca> To: <fractint@mailman.xmission.com> Sent: Wednesday, May 22, 2002 5:15 PM Subject: Re: [Fractint] At it again...
----- Original Message ----- From: "bmc1" <bmc1@airmail.net> Sent: Wednesday, May 22, 2002 2:54 PM Subject: Re: [Fractint] At it again...
Don't mean to be rude, but . . . . . . could we "get at" something else, please ???
What about comments from readers re what might be included on Jim's CD, now that he has all the files, and has obtained (I assume) from PNL all the lists of duplicate names, similkar names, etc.
How tastes vary! Personally I'm not interested in "getting at" this sort of trivia. I trust Jim's taste, and I'm sure he doesn't need advice from me regarding what is, after all, his own personal statement.. At least he hasn't asked me, so far. Besides, I expect that he will be asking for cold cash for his efforts, so why would I do any of the work for him? :-)
John W.
_______________________________________________ Fractint mailing list Fractint@mailman.xmission.com http://mailman.xmission.com/cgi-bin/mailman/listinfo/fractint
On Wed, 22 May 2002 16:54:22 -0500, bmc1 wrote:
Don't mean to be rude, but . . . . . . could we "get at" something else, please ???
What about comments from readers re what might be included on Jim's CD, now that he has all the files, and has obtained (I assume) from PNL all the lists of duplicate names, similar names, etc.
A copy of Fractint and instructions on how to generate the fractals from the PAR files? John -- John Lewis, jlewis@clara.net on 05/22/2002
Dear John- There you go. What better (and more essential thing) to include than the latest version of Fractint itself, and a few 100 KB's of the User's Guide to make it a "self-starting" (and more financially-attractive) CD for all?? Good suggestion, IMHO. I'll bet Jim could get the powers that be in Vancouver BC to let him include it . . . . . . . . . Freed ----- Original Message ----- From: "John Lewis" <jlewis@clara.net> To: <fractint@mailman.xmission.com> Sent: Wednesday, May 22, 2002 5:32 PM Subject: Re: [Fractint] At it again... On Wed, 22 May 2002 16:54:22 -0500, bmc1 wrote:
Don't mean to be rude, but . . . . . . could we "get at" something else, please ???
What about comments from readers re what might be included on Jim's CD, now that he has all the files, and has obtained (I assume) from PNL all the lists of duplicate names, similar names, etc.
A copy of Fractint and instructions on how to generate the fractals from the PAR files? John -- John Lewis, jlewis@clara.net on 05/22/2002 _______________________________________________ Fractint mailing list Fractint@mailman.xmission.com http://mailman.xmission.com/cgi-bin/mailman/listinfo/fractint
From: "Morgan L. Owens" Sent: Wednesday, May 22, 2002 3:28 PM
I think I'm outclassed. I mean, here's me still tinkering in two dimensions... Next thing to do would be to parameterise things a bit...
As much as I like ego strokes (who doesn't?) cudos should go to the POV-Ray team: A few years ago I nosed around in POV's source - the sphere and plane intersection code in my formulas is more or less gleaned from there (all I did was bolting the different pieces together...). As of more paramters, I've cobbled together a patch for both formulas to move the "camera" around a bit: ;---------------------- Parameter usage ----------------------- ;p1r: camera shift x ;p1i: camera shift y ;p2r: camera shift z ;p2i: rotation around x-axis (will be applied before p3r) :p3r: rotation around y-axis ;-------------------------------------------------------------- The patch proper has to replace everything below the coordinate constants (sphere centers and unit vector directions) up to the ;------------- TetraSpheres and TetraSpheresBas --------------- tmp2 = pi/180 tmp1 = exp(flip(imag(p2)*tmp2)), tmp2 = exp(flip(real(p3)*tmp2)) dxy = flip(conj(tmp2)) ; pxy = tmp2*real(pixel) - dxy*imag(tmp1)*imag(pixel) pz = imag(pxy) + real(p2) pxy = real(pxy) + flip(real(tmp1)*imag(pixel)) + p1 ; vxy = dxy*real(tmp1) vz = imag(vxy) vxy = real(vxy) + flip(imag(tmp1)) : ;-------------------------------------------------------------- In TetraSpheresBas also replace ":" with "j = 1:" That's all, Gerald And now on to the new "only 2d"<grin> stuff you have brewed up...
At 09:32 23/05/2002, Gerald K. Dobiasovsky wrote:
And now on to the new "only 2d"<grin> stuff you have brewed up...
And I should get back to writing a Universal Turing Machine simulator in Fractint... Morgan L. Owens "The good days are back, Good morning Mr. Rock and Roll"
Whoops. In my last post I was actually talking about #2 lattice.
At 09:32 23/05/2002, Gerald K. Dobiasovsky wrote:
From: "Morgan L. Owens" Sent: Wednesday, May 22, 2002 3:28 PM
I think I'm outclassed. I mean, here's me still tinkering in two dimensions... Next thing to do would be to parameterise things a bit...
Having tinkered some, I've now got a parameterised version. p1-p4 are the centres of four circles. The inversion group is then illustrated. What made this tricky is my insistence that the radii of the circles be as "natural" as possible; for any (finite) distribution of points (at least two) in the plane there are (uncountably) many ways of assigning radii to circles centred on those points such that none can be enlarged without it overlapping some other. This is the case even with a mere two points: one can be huge and the other tiny, or one can be tiny and the other huge, but the most "natural" choice would be that they're equal-sized. Ditto for n points equally spaced around a circle; if I were to have three points forming the vertices of an equilateral triangle the natural solution would be three mutually tangent circles of equal size, not one huge circle with two tiny nubs. The solution is fairly robust, based on my half-baked test procedures - the result is independent of which order points are specified, and there don't seem to be any nasty discontinuities where a circle suddenly jumps in size when its position is tweaked slightly. This should make it ripe for animation. So, after a quick rendition of the happy Job's Done Shuffle: 4movable{ ; For any set of four points in the plane, there are an infinite number ; of solutions to the problem of mutually tangent circles centred on those ; points. For the sake of definiteness, some more or less arbitrary methods ; have to be applied. First, we find the distances between each pair of ; points. d21=d12=cabs(p1-p2) d31=d13=cabs(p1-p3) d41=d14=cabs(p1-p4) d32=d23=cabs(p2-p3) d42=d24=cabs(p2-p4) d43=d34=cabs(p3-p4) ; The radius of each circle is _at least_ half the distance between its centre ; and the centre of the nearest other circle. r1=d12 r2=d21 r3=d31 r4=d41 r1=(d13<r1)*d13+(d13>=r1)*r1 r2=(d23<r2)*d23+(d23>=r2)*r2 r3=(d32<r3)*d32+(d32>=r3)*r3 r4=(d42<r4)*d42+(d42>=r4)*r4 r1=(d14<r1)*d14+(d14>=r1)*r1 r2=(d24<r2)*d24+(d24>=r2)*r2 r3=(d34<r3)*d34+(d34>=r3)*r3 r4=(d43<r4)*d43+(d43>=r4)*r4 ;Yeah, I said "half", didn't I? r1=r1/2 r2=r2/2 r3=r3/2 r4=r4/2 ; We subtract these radii from our distances, leaving only some possible "excess" d21=d12=d12-r1-r2 d31=d13=d13-r1-r3 d41=d14=d14-r1-r4 d32=d23=d23-r2-r3 d42=d24=d24-r2-r4 d43=d34=d34-r3-r4 ; At this point the two nearest circles are already tangent to each other. The ; others, however, may still have some distance remaining between themselves ; and the others. This remaining distance is what I referred to above as the ; "excess". For two circles that are tangent, this excess is zero. ; ; If both of the remaining circles are free to grow (a circle is "free to ; grow" when it is not tangent to any other circle), we want both to be as ; large as possible - we don't want, for example, one to be so large that the ; other is unable to grow any further at all. The most sensible solution is ; for each to take half of the excess that lies between them; unless of course ; that would cause one to overlap either of the first two circles, in which ; case the growth is limited by the excess lying between it and the fixed ; circle. ; We note which circles can still grow (i.e. nonzero excess between it and all ; others) g1=(d12*d13*d14>0) g2=(d21*d23*d24>0) g3=(d31*d32*d34>0) g4=(d41*d42*d43>0) if(g1) ma=1,da1=0,da2=d12,da3=d13,da4=d14 elseif(g2) ma=2,da1=d21,da2=0,da3=d23,da4=d24 elseif(g3) ma=3,da1=d31,da2=d32,da3=0,da4=d34 elseif(g4) ma=4,da1=d41,da2=d42,da3=d43,da4=0 else ma=0 endif if(g1 && ma!=1) mb=1,db1=0,db2=d12,db3=db3,db4=d14 elseif(g2 && ma!=2) mb=2,db1=d21,db2=0,db3=d23,db4=d24 elseif(g3 && ma!=3) mb=3,db1=d31,db2=d32,db3=0,db4=d34 elseif(g4 && ma!=4) mb=4,db1=d41,db2=d42,db3=d43,db4=0 else mb=0 endif ; ma and mb are the only two (if any) circles that can still grow. if(ma!=0) ; At least one circle can still grow. if(mb==0) ; and it's the only one, so we grow it as big as it will go. if(ma==1) d=da2 d=(da3<d)*da3+(da3>=d)*d d=(da4<d)*da4+(da4>=d)*d r1=r1+d elseif(ma==2) d=da1 d=(da3<d)*da3+(da3>=d)*d d=(da4<d)*da4+(da4>=d)*d r2=r2+d elseif(ma==3) d=da1 d=(da2<d)*da2+(da2>=d)*d d=(da4<d)*da4+(da4>=d)*d r3=r3+d elseif(ma==4) d=da1 d=(da2<d)*da2+(da2>=d)*d d=(da3<d)*da3+(da3>=d)*d r4=r4+d endif else ; Both can grow, so we grow them both as much as they can go. if((ma==1 && mb==2)||(ma==2 && mb==1)) dab=d12 elseif((ma==1 && mb==3)||(ma==3 && mb==1)) dab=d13 elseif((ma==1 && mb==4)||(ma==4 && mb==1)) dab=d14 elseif((ma==2 && mb==3)||(ma==3 && mb==2)) dab=d23 elseif((ma==2 && mb==4)||(ma==4 && mb==2)) dab=d24 elseif((ma==3 && mb==4)||(ma==4 && mb==3)) dab=d34 endif da=dab/2 if(ma!=1) da=(da1<da)*da1+(da1>=da)*da endif if(ma!=2) da=(da2<da)*da2+(da2>=da)*da endif if(ma!=3) da=(da3<da)*da3+(da3>=da)*da endif if(ma!=4) da=(da4<da)*da4+(da4>=da)*da endif db=dab/2 if(mb!=1) db=(db1<db)*db1+(db1>=db)*db endif if(mb!=2) db=(db2<db)*db2+(db2>=db)*db endif if(mb!=3) db=(db3<db)*db3+(db3>=db)*db endif if(mb!=4) db=(db4<db)*db4+(db4>=db)*db endif if(ma==1) r1=r1+da elseif(ma==2) r2=r2+da elseif(ma==3) r3=r3+da elseif(ma==4) r4=r4+da endif if(mb==1) r1=r1+db elseif(mb==2) r2=r2+db elseif(mb==3) r3=r3+db elseif(mb==4) r4=r4+db endif endif endif rr1=sqr(r1) rr2=sqr(r2) rr3=sqr(r3) rr4=sqr(r4) z=pixel: inside=0 if(|z-p1|<rr1) z=r1*conj(r1/(z-p1))+p1 inside=1 elseif(|z-p2|<rr2) z=r2*conj(r2/(z-p2))+p2 inside=1 elseif(|z-p3|<rr3) z=r3*conj(r3/(z-p3))+p3 inside=1 elseif(|z-p4|<rr4) z=r4*conj(r4/(z-p4))+p4 inside=1 endif inside} Morgan L. Owens "Dance all around the World with me."
At 00:19 24/05/2002, Morgan L. Owens wrote:
4movable{
Oh, that's right; the current (developer) version has 5 user pars. 5movable{ d21=d12=cabs(p1-p2) d31=d13=cabs(p1-p3) d41=d14=cabs(p1-p4) d51=d15=cabs(p1-p5) d32=d23=cabs(p2-p3) d42=d24=cabs(p2-p4) d52=d25=cabs(p2-p5) d43=d34=cabs(p3-p4) d53=d35=cabs(p3-p5) d54=d45=cabs(p4-p5) r1=d12 r2=d21 r3=d31 r4=d41 r5=d51 r1=(d13<r1)*d13+(d13>=r1)*r1 r2=(d23<r2)*d23+(d23>=r2)*r2 r3=(d32<r3)*d32+(d32>=r3)*r3 r4=(d42<r4)*d42+(d42>=r4)*r4 r5=(d52<r5)*d52+(d52>=r5)*r5 r1=(d14<r1)*d14+(d14>=r1)*r1 r2=(d24<r2)*d24+(d24>=r2)*r2 r3=(d34<r3)*d34+(d34>=r3)*r3 r4=(d43<r4)*d43+(d43>=r4)*r4 r5=(d53<r5)*d53+(d53>=r5)*r5 r1=(d15<r1)*d15+(d15>=r1)*r1 r2=(d25<r2)*d25+(d25>=r2)*r2 r3=(d35<r3)*d35+(d35>=r3)*r3 r4=(d45<r4)*d45+(d45>=r4)*r4 r5=(d54<r5)*d54+(d54>=r5)*r5 r1=r1/2 r2=r2/2 r3=r3/2 r4=r4/2 r5=r5/2 d21=d12=d12-r1-r2 d31=d13=d13-r1-r3 d41=d14=d14-r1-r4 d51=d15=d15-r1-r5 d32=d23=d23-r2-r3 d42=d24=d24-r2-r4 d52=d25=d25-r2-r5 d43=d34=d34-r3-r4 d53=d35=d35-r3-r5 d54=d45=d45-r4-r5 g1=(d12*d13*d14*d15>0) g2=(d21*d23*d24*d25>0) g3=(d31*d32*d34*d35>0) g4=(d41*d42*d43*d45>0) g5=(d51*d52*d53*d54>0) if(g1) ma=1,da1=0,da2=d12,da3=d13,da4=d14,da5=d15 elseif(g2) ma=2,da1=d21,da2=0,da3=d23,da4=d24,da5=d25 elseif(g3) ma=3,da1=d31,da2=d32,da3=0,da4=d34,da5=d35 elseif(g4) ma=4,da1=d41,da2=d42,da3=d43,da4=0,da5=d45 elseif(g5) ma=5,da1=d51,da2=d52,da3=d53,da5=d54,da5=0 else ma=0 endif if(g1 && ma!=1) mb=1,db1=0,db2=d12,db3=db3,db4=d14,db5=d15 elseif(g2 && ma!=2) mb=2,db1=d21,db2=0,db3=d23,db4=d24,db5=d25 elseif(g3 && ma!=3) mb=3,db1=d31,db2=d32,db3=0,db4=d34,db5=d35 elseif(g4 && ma!=4) mb=4,db1=d41,db2=d42,db3=d43,db4=0,db5=d45 elseif(g5 && ma!=5) mb=5,db1=d51,db2=d52,db3=d53,db4=d54,db5=0 else mb=0 endif if(ma!=0) if(mb==0) if(ma==1) d=da2 d=(da3<d)*da3+(da3>=d)*d d=(da4<d)*da4+(da4>=d)*d d=(da5<d)*da5+(da5>=d)*d r1=r1+d elseif(ma==2) d=da1 d=(da3<d)*da3+(da3>=d)*d d=(da4<d)*da4+(da4>=d)*d d=(da5<d)*da4+(da5>=d)*d r2=r2+d elseif(ma==3) d=da1 d=(da2<d)*da2+(da2>=d)*d d=(da4<d)*da4+(da4>=d)*d d=(da5<d)*da5+(da5>=d)*d r3=r3+d elseif(ma==4) d=da1 d=(da2<d)*da2+(da2>=d)*d d=(da3<d)*da3+(da3>=d)*d d=(da5<d)*da5+(da5>=d)*d r4=r4+d elseif(ma==5) d=da1 d=(da2<d)*da2+(da2>=d)*d d=(da3<d)*da3+(da3>=d)*d d=(da4<d)*da4+(da4>=d)*d r5=r5+d endif else if((ma==1 && mb==2)||(ma==2 && mb==1)) dab=d12 elseif((ma==1 && mb==3)||(ma==3 && mb==1)) dab=d13 elseif((ma==1 && mb==4)||(ma==4 && mb==1)) dab=d14 elseif((ma==1 && mb==5)||(ma==5 && mb==1)) dab=d15 elseif((ma==2 && mb==3)||(ma==3 && mb==2)) dab=d23 elseif((ma==2 && mb==4)||(ma==4 && mb==2)) dab=d24 elseif((ma==2 && mb==5)||(ma==5 && mb==2)) dab=d25 elseif((ma==3 && mb==4)||(ma==4 && mb==3)) dab=d34 elseif((ma==3 && mb==5)||(ma==5 && mb==3)) dab=d35 elseif((ma==4 && mb==5)||(ma==5 && mb==4)) dab=d45 endif da=db=dab/2 if(ma!=1) da=(da1<da)*da1+(da1>=da)*da endif if(ma!=2) da=(da2<db)*da2+(da2>=da)*da endif if(ma!=3) da=(da3<da)*da3+(da3>=da)*da endif if(ma!=4) da=(da4<da)*da4+(da4>=da)*da endif if(ma!=5) da=(da5<da)*da5+(da5>=da)*da endif if(mb!=1) db=(db1<db)*db1+(db1>=db)*db endif if(mb!=2) db=(db2<db)*db2+(db2>=db)*db endif if(mb!=3) db=(db3<db)*db3+(db3>=db)*db endif if(mb!=4) db=(db4<db)*db4+(db4>=db)*db endif if(mb!=5) db=(db5<db)*db5+(db5>=db)*db endif if(ma==1) r1=r1+da elseif(ma==2) r2=r2+da elseif(ma==3) r3=r3+da elseif(ma==4) r4=r4+da elseif(ma==5) r5=r5+da endif if(mb==1) r1=r1+db elseif(mb==2) r2=r2+db elseif(mb==3) r3=r3+db elseif(mb==4) r4=r4+db elseif(mb==5) r5=r5+db endif endif endif rr1=sqr(r1) rr2=sqr(r2) rr3=sqr(r3) rr4=sqr(r4) rr5=sqr(r5) z=pixel: inside=0 if(|z-p1|<rr1) z=r1*conj(r1/(z-p1))+p1 inside=1 elseif(|z-p2|<rr2) z=r2*conj(r2/(z-p2))+p2 inside=1 elseif(|z-p3|<rr3) z=r3*conj(r3/(z-p3))+p3 inside=1 elseif(|z-p4|<rr4) z=r4*conj(r4/(z-p4))+p4 inside=1 elseif(|z-p5|<rr5) z=r5*conj(r5/(z-p5))+p5 inside=1 endif inside}
From: "Morgan L. Owens" Sent: Thursday, May 23, 2002 3:19 PM
At 00:19 24/05/2002, Morgan L. Owens wrote:
4movable{
Oh, that's right; the current (developer) version has 5 user pars.
[Big intricate formula snipped...] Not feeling capable to code something which will evoke headlines like "script for freeware fractal software beats Mathematica - Wolfram says he's stunned" I approached the problem from the other side: Provide the circles' radii and let the formula put them where they belong. The first two circles (with radii r1, r2) can be put on the x-axis at -r1 and r2, so they touch at the origin. Calculating where the center of circle 3 should be to touch both 1 and 2 is pretty straightforward. Using only the solution for positive y one then repeats the procedure for circle 4 with a solution for negative y. Then things get complicated, so one better stops... ;-) This way one has only access to small subset of cases your formula provides (and only 4 circles at that!), but with each circle having contact with at least 2 others hopefully interesting ones... ...and while playing around with these modifications I suddenly had the idea of adding an "inverted" circle, a circle where inside=1 when the point is outside - whith truly interesting results (pars and formulas at the bottom of this mail). Regards, Gerald P.S.: I know this is not exactly small for one's average email, but I promise to restrain myself in the future. :-) ;-------------------- Pars following -------------------------- Inv4Klein_Group_1 {; ; reset=2002 type=formula formulafile=fmlpost.frm formulaname=Inv4Klein_Group corners=-10.90761/10.90761/-8.180707/8.180707 params=0.86602540378444/1.86602540378444 float=y periodicity=0 colors=@chroma.map } Inv4Klein_Group_2 {; ; reset=2002 type=formula formulafile=fmlpost.frm formulaname=Inv4Klein_Group center-mag=-4.44089e-015/3.10862e-015/0.5722363 params=0.86602540378444/0.87 float=y periodicity=0 colors=@chroma.map } Inv4Klein_Group_3 {; ; reset=2002 type=formula formulafile=fmlpost.frm formulaname=Inv4Klein_Group center-mag=-5.32907e-015/7.10543e-015/0.08343137 params=1/2 float=y periodicity=0 colors=@chroma.map } Inv4Klein_Group_4 {; ; reset=2002 type=formula formulafile=fmlpost.frm formulaname=Inv4Klein_Group center-mag=-1.3047/-7.10543e-015/0.07093161 params=1/2.25 float=y maxiter=256 outside=atan periodicity=0 colors=@chroma.map } Inv4Klein_Group_5 {; ; reset=2002 type=formula formulafile=fmlpost.frm formulaname=Inv4Klein_Group center-mag=-1.3047/-3.64153e-014/0.1069102 params=0.9/1.8 float=y maxiter=256 periodicity=0 colors=@chroma.map } Inv4Klein_Group_6 {; ; reset=2002 type=formula formulafile=fmlpost.frm formulaname=Inv4Klein_Group center-mag=-1.3047/-1.42109e-014/0.03353532 params=0.99/1.98 float=y maxiter=256 periodicity=0 colors=@chroma.map } Inv4Klein_Group_7 {; ; reset=2002 type=formula formulafile=fmlpost.frm formulaname=Inv4Klein_Group center-mag=4.52648/0/0.1640166 params=0.86602540378444/2.3/-1/0.5 float=y periodicity=0 colors=@chroma.map } Mod4Klein_Group_1 {; ; reset=2002 type=formula formulafile=flmpost.frm formulaname=Mod4Klein_Group corners=-4.01749/4.01749/-2.048485/3.977749 params=1/1/2/1.5/0/0 float=y periodicity=0 colors=@chroma.map } Mod4Klein_Group_2 {; ; reset=2002 type=formula formulafile=fmlpost.frm formulaname=Mod4Klein_Group corners=-7.289188/1.594677/5.107935/-6.737217/1.594677/-6.737217 params=1/1/1/2/1/1 float=y periodicity=0 colors=@chroma.map } Mod5Klein_Group_1 {; ; reset=2002 type=formula formulafile=fmlpost.frm formulaname=Mod5Klein_Group corners=2.408138/-2.408138/-5.688688/0.7330124/-2.408138/0.7330124 params=1/0.5/0.25/0.75/0/1.5/2.5/0 float=y periodicity=0 colors=@chroma.map } Mod5Klein_Group_2 {; ; reset=2002 type=formula formulafile=fmlpost.frm formulaname=Mod5Klein_Group corners=-374.0298/251.9447/-234.7405/234.7405 params=1/1.25/1/1.75/-0.25/0/2.5/0 float=y periodicity=0 colors=@chroma.map } Mod5Klein_Group_3 {; ; reset=2002 type=formula formulafile=fmlpost.par formulaname=Mod5Klein_Group corners=2.6930253/-0.94438741/-2.8427454/2.4755537/-1.1692268/2.3069241 params=1/1.25/1.5/2.25/0.25/0.5/1/0 float=y periodicity=0 colors=@chroma.map } frm:Inv4Klein_Group {;Modification of "3Klein_Group" by Morgan L. Owens ;Circle 4 has "inverted" function. ;periodicity=no ;( Circles all touching: r123 = sqrt(3)/2 ; r4 = sqrt(3)/2 + 1 ; c4 = 0 ) ;------------------------------------ ;p1r: radii 1 to 3 ;p1i: radius 4 ;p2r: Center of circle 4 x-coordinate ;p2i: Center of circle 4 y-coordinate ;------------------------------------ ; ang = 2*pi/3 c1 = 1 c2 = exp((0,1)*ang) c3 = exp((0,2)*ang) r123 = real(p1) r4 = imag(p1) rr123 = sqr(r123) rr4 = sqr(r4) z = pixel: inside = 0 IF (|z-c1| < rr123) z = r123*conj(r123/(z-c1)) + c1 inside = 1 ELSEIF (|z-c2| < rr123) z = r123*conj(r123/(z-c2)) + c2 inside = 1 ELSEIF (|z-c3| < rr123) z = r123*conj(r123/(z-c3)) + c3 inside = 1 ELSEIF (|z-p2| > rr4) z = r4*conj(r4/(z-p2)) + p2 inside = 1 ENDIF inside } frm:Alt3Klein_Group {;Modification of "3Klein_Group" by Morgan L. Owens ;Each circle is always touching the other two. ;periodicity=no ;-------------- ;p1r: radius 1 ;p1i: radius 2 ;p2r: radius 3 ;------------------------------ r1 = real(p1) r2 = imag(p1) r3 = real(p2) ;c1 = -r1 ;c2 = r2 c3 = ((r1-r2)*r3+flip(sqrt((r1+r2+r3)*r1*r2*r3)*2))/(r1+r2) rr1 = sqr(r1) rr2 = sqr(r2) rr3 = sqr(r3) z = pixel: inside = 0 IF (|z+r1| < rr1) z = r1*conj(r1/(z+r1)) - r1 inside = 1 ELSEIF (|z-r2| < rr2) z = r2*conj(r2/(z-r2)) + r2 inside = 1 ELSEIF (|z-c3| < rr3) z = r3*conj(r3/(z-c3)) + c3 inside = 1 ENDIF inside } frm:Alt4Klein_Group {;Modification of "4Klein_Group" by Morgan L. Owens ;Circles 1 and 2 touch, 3 and 4 each touch 1 and 2. ;periodicity=no ;-------------- ;p1r: radius 1 ;p1i: radius 2 ;p2r: radius 3 ;p2i: radius 4 ;------------------------------ r1 = real(p1) r2 = imag(p1) r3 = real(p2) r4 = imag(p2) ;c1 = -r1 ;c2 = r2 c3 = ((r1-r2)*r3+flip(sqrt((r1+r2+r3)*r1*r2*r3)*2))/(r1+r2) c4 = ((r1-r2)*r4-flip(sqrt((r1+r2+r4)*r1*r2*r4)*2))/(r1+r2) rr1 = sqr(r1) rr2 = sqr(r2) rr3 = sqr(r3) rr4 = sqr(r4) z = pixel: inside = 0 IF (|z+r1| < rr1) z = r1*conj(r1/(z+r1)) - r1 inside = 1 ELSEIF (|z-r2| < rr2) z = r2*conj(r2/(z-r2)) + r2 inside = 1 ELSEIF (|z-c3| < rr3) z = r3*conj(r3/(z-c3)) + c3 inside = 1 ELSEIF (|z-c4| < rr4) z = r4*conj(r4/(z-c4)) + c4 inside = 1 ENDIF inside } frm:Mod4Klein_Group {;Modification of "3Klein_Group" by Morgan L. Owens ;Each of the circles 1 - 3 always touches the other two. ;Parameters of circle 4 are not restricted. Circle has "inverted" function. ;periodicity=no ;------------------------------------ ;p1r: radius 1 ;p1i: radius 2 ;p2r: radius 3 ;p2i: radius 4 ;p3r: Center of circle 4 x-coordinate ;p3i: Center of circle 4 y-coordinate ;------------------------------------ r1 = real(p1) r2 = imag(p1) r3 = real(p2) r4 = imag(p2) ;c1 = -r1 ;c2 = r2 c3 = ((r1-r2)*r3+flip(sqrt((r1+r2+r3)*r1*r2*r3)*2))/(r1+r2) rr1 = sqr(r1) rr2 = sqr(r2) rr3 = sqr(r3) rr4 = sqr(r4) z = pixel: inside = 0 IF (|z+r1| < rr1) z = r1*conj(r1/(z+r1)) - r1 inside = 1 ELSEIF (|z-r2| < rr2) z = r2*conj(r2/(z-r2)) + r2 inside = 1 ELSEIF (|z-c3| < rr3) z = r3*conj(r3/(z-c3)) + c3 inside = 1 ELSEIF (|z-p3| > rr4) z = r4*conj(r4/(z-p3)) + p3 inside = 1 ENDIF inside } frm:Mod5Klein_Group {;Modification of "4Klein_Group" by Morgan L. Owens ;Circle 1 and 2 touch, 3 and 4 each touch 1 and 2. ;Parameters of circle 5 are not restricted. Circle has "inverted" function. ;periodicity=no ;------------------------------------ ;p1r: radius 1 ;p1i: radius 2 ;p2r: radius 3 ;p2i: radius 4 ;p3r: Center of circle 5 x-coordinate ;p3i: Center of circle 5 y-coordinate ;p4r: radius 5 ;------------------------------------ r1 = real(p1) r2 = imag(p1) r3 = real(p2) r4 = imag(p2) r5 = real(p4) ;c1 = -r1 ;c2 = r2 c3 = ((r1-r2)*r3+flip(sqrt((r1+r2+r3)*r1*r2*r3)*2))/(r1+r2) c4 = ((r1-r2)*r4-flip(sqrt((r1+r2+r4)*r1*r2*r4)*2))/(r1+r2) rr1 = sqr(r1) rr2 = sqr(r2) rr3 = sqr(r3) rr4 = sqr(r4) rr5 = sqr(r5) z = pixel: inside = 0 IF (|z+r1| < rr1) z = r1*conj(r1/(z+r1)) - r1 inside = 1 ELSEIF (|z-r2| < rr2) z = r2*conj(r2/(z-r2)) + r2 inside = 1 ELSEIF (|z-c3| < rr3) z = r3*conj(r3/(z-c3)) + c3 inside = 1 ELSEIF (|z-c4| < rr4) z = r4*conj(r4/(z-c4)) + c4 inside = 1 ELSEIF (|z-p3| > rr5) z = r5*conj(r5/(z-p3)) + p3 inside = 1 ENDIF inside } ;-------------------------- End pars --------------------------
At 18:00 25/05/2002, Gerald K. Dobiasovsky wrote:
From: "Morgan L. Owens" Sent: Thursday, May 23, 2002 3:19 PM
At 00:19 24/05/2002, Morgan L. Owens wrote:
4movable{
Oh, that's right; the current (developer) version has 5 user pars.
[Big intricate formula snipped...]
To be honest, that larger one is actually known to be broken - the code only still only checks the tangency of four circles (notes for which are in the original version). Position circles at (-1,+/-0.1), (0,+/-0.2) and (2,0) to see what I mean - the one on the right should be much bigger. To confess further, I've found situations where the original four-circle code fails to ensure proper tangency. But it was painful enough getting it into the state it's in now: while I was writing it I perpetually found myself wishing I could use arrays and nested loops. And a debugger.
Not feeling capable to code something which will evoke headlines like "script for freeware fractal software beats Mathematica - Wolfram says he's stunned"
Some earlier attempts of mine broke Fractint. "Too many jumps" it said... And one more confession. I could have made them twice as fast, and my own personal copies do. The problem is that they achieve their speedup by means of a hack that relies on something which I consider to be a bug (or rather, enhancement opportunity) in the Fractint formula parser. The "bug" is that values computed for one pixel are still retained when the next pixel is calculated. Now, if you were behaving yourself in the first place, you would have set the values of any variables you used in the formula, so that in the second pixel they'd be recalculated all over again. But if you _use_ a variable _before_ giving it a value, then for the first pixel it will have a value of zero, while for subsequent pixels it will have whatever you set it to during calculation of the previous pixel. The problem is that the order in which pixels are calculated depends critically on the drawing method used. The following formula and par SHOULD NOT work: swatch { ; Version 2001 Patchlevel 8 reset=2001 type=formula formulafile=swatch.frm formulaname=swatch passes=1 center-mag=0/0/0.6666667/1.3333 float=y maxiter=256 inside=255 periodicity=0 viewwindows=1/1/yes/256/256 colors=000ccc<3>nnnqqqtttwwwzzz<4>IIz99z00z<9>bbOffKjjG<3>zz0<9>zO0zK0zG\ 0<3>z00<9>O0bK0fG0j<3>00z<9>0bO0fK0jG<3>0z0<9>bObfKfjGj<3>z0z<9>`0`Y0YV0\ V<2>N0NK0KJ1L<8>8Ia7Kc5Me<2>2Sk0Um0Vm<8>0em0fm0hm<2>0km0mm0mm<8>0gu0gu0f\ v<3>0cz<9>bqzfrzjtz<3>zzz<25>zhCzgAzf8<2>zd2zc0zd0<8>zq0zr0zt0<3>zz0<9>z\ O0zK0zG0<3>z00<14>ZZZ } frm:swatch{ z=ig ig=ig+1 if(ig==256) ig=0 endif : z=z-1 z } And it won't if you use any drawing method other than (1) or (b). So what? What has this conversational tangent got to tangential circles? In the 4movable and 5movable (and I really should have thought of better names than those) formulae, virtually _all_ the initialisation is identical for every single pixel - the only pixel-dependent initialisation is the line "z=pixel". If I could retain from one pixel to the next those radii that the code goes to such great lengths to compute I would get a huge speedup. And this is how I do it: Insert as the first line of the initialisation the line if(precalc==0) I've yet to say what value "precalc" actually has yet: for the first pixel computed it will be zero (and so the test will succeed); for subsequent pixels it will be whatever the previous pixel set it to, which is done by adding endif precalc=1 immediately before the "z=pixel" line. So when the first pixel is initialised, precalc==0, and so all the radius calculation is carried out. Afterwards, precalc==1, so all that work is skipped, the values of r1..r4 are never overwritten and so retain their values set when the first pixel was initialised. It's a good thing that none of that initialisation did use pixel-specific quantities or this would obviously never have worked. The Opportunity. The above is a dirty hack. One should instead have a per-image initialisation section in Fractint formulae just as there is now for per-pixel initialisation. A backwards-compatible syntax would be: formulaname{ per-image initialisation code :: per-pixel initialisation code : per-iteration code } After getting that off my chest I'm finally going to let myself have a look at these new pars! Morgan "She Speeds"
At 20:27 25/05/02 +1200, you wrote:
At 18:00 25/05/2002, Gerald K. Dobiasovsky wrote:
From: "Morgan L. Owens"
.....
The problem is that the order in which pixels are calculated depends critically on the drawing method used. The following formula and par SHOULD NOT work:
swatch { ; Version 2001 Patchlevel 8 reset=2001 type=formula formulafile=swatch.frm formulaname=swatch passes=1 center-mag=0/0/0.6666667/1.3333 float=y maxiter=256 inside=255 periodicity=0 viewwindows=1/1/yes/256/256 colors=000ccc<3>nnnqqqtttwwwzzz<4>IIz99z00z<9>bbOffKjjG<3>zz0<9>zO0zK0zG\ 0<3>z00<9>O0bK0fG0j<3>00z<9>0bO0fK0jG<3>0z0<9>bObfKfjGj<3>z0z<9>`0`Y0YV0\ V<2>N0NK0KJ1L<8>8Ia7Kc5Me<2>2Sk0Um0Vm<8>0em0fm0hm<2>0km0mm0mm<8>0gu0gu0f\ v<3>0cz<9>bqzfrzjtz<3>zzz<25>zhCzgAzf8<2>zd2zc0zd0<8>zq0zr0zt0<3>zz0<9>z\ O0zK0zG0<3>z00<14>ZZZ }
frm:swatch{ z=ig ig=ig+1 if(ig==256) ig=0 endif : z=z-1 z }
And it won't if you use any drawing method other than (1) or (b).
;-))) swatch2 { ; Version 2002 Patchlevel 3 ; Version 2002 Patchlevel 3 reset=2002 type=formula formulafile=swatch2.frm formulaname=swatch2 passes=b center-mag=9.775e-006/1.0105e-005/0.6666712 params=1/0 colors=000000<9>ab1ef1ij1<3>xz1<9>NO0JK0FG0<3>000<9>SVbVYfY`j<3>imz<9>HI\ OEFKBCG<3>000<8>aB8eC9iDA<3>zIE<9>O75K54G43<3>000<9>MbJOfLQjN<3>ZzV<9>DO\ BBK98G7<3>000<9>bJMfLOjNQ<3>zVZ<9>OBDK9BG89<3>000<9>CbADfBFjC<3>KzG<9>7O\ 66K55G4<3>000<8>aVTeZWiaZ<3>zok<9>OJIKGFGDC<3>000<9>03b03f03j<2>14v15z14\ v<14>000 } swatch3 { ; Version 2002 Patchlevel 3 ; Version 2002 Patchlevel 3 reset=2002 type=formula formulafile=swatch2.frm formulaname=swatch2 passes=t center-mag=9.775e-006/1.0105e-005/0.6666712 params=1/0 colors=000000<9>ab1ef1ij1<3>xz1<9>NO0JK0FG0<3>000<9>SVbVYfY`j<3>imz<9>HI\ OEFKBCG<3>000<8>aB8eC9iDA<3>zIE<9>O75K54G43<3>000<9>MbJOfLQjN<3>ZzV<9>DO\ BBK98G7<3>000<9>bJMfLOjNQ<3>zVZ<9>OBDK9BG89<3>000<9>CbADfBFjC<3>KzG<9>7O\ 66K55G4<3>000<8>aVTeZWiaZ<3>zok<9>OJIKGFGDC<3>000<9>03b03f03j<2>14v15z14\ v<14>000 } swatch4 { ; Version 2002 Patchlevel 3 ; Version 2002 Patchlevel 3 reset=2002 type=formula formulafile=swatch2.frm formulaname=swatch2 passes=t center-mag=9.775e-006/1.0105e-005/0.6666712 params=0.5/-0.5 colors=000000<9>ab1ef1ij1<3>xz1<9>NO0JK0FG0<3>000<9>SVbVYfY`j<3>imz<9>HI\ OEFKBCG<3>000<8>aB8eC9iDA<3>zIE<9>O75K54G43<3>000<9>MbJOfLQjN<3>ZzV<9>DO\ BBK98G7<3>000<9>bJMfLOjNQ<3>zVZ<9>OBDK9BG89<3>000<9>CbADfBFjC<3>KzG<9>7O\ 66K55G4<3>000<8>aVTeZWiaZ<3>zok<9>OJIKGFGDC<3>000<9>03b03f03j<2>14v15z14\ v<14>000 } swatch5 { ; Version 2002 Patchlevel 3 ; Version 2002 Patchlevel 3 reset=2002 type=formula formulafile=swatch2.frm formulaname=swatch2 passes=t center-mag=9.775e-006/1.0105e-005/0.6666712 params=0.5/0.5 colors=000000<9>ab1ef1ij1<3>xz1<9>NO0JK0FG0<3>000<9>SVbVYfY`j<3>imz<9>HI\ OEFKBCG<3>000<8>aB8eC9iDA<3>zIE<9>O75K54G43<3>000<9>MbJOfLQjN<3>ZzV<9>DO\ BBK98G7<3>000<9>bJMfLOjNQ<3>zVZ<9>OBDK9BG89<3>000<9>CbADfBFjC<3>KzG<9>7O\ 66K55G4<3>000<8>aVTeZWiaZ<3>zok<9>OJIKGFGDC<3>000<9>03b03f03j<2>14v15z14\ v<14>000 } swatch6 { ; Version 2002 Patchlevel 3 ; Version 2002 Patchlevel 3 reset=2002 type=formula formulafile=swatch2.frm formulaname=swatch2 passes=b center-mag=-3.695e-006/-8.405e-006/0.9999915 params=0.5/0 maxiter=256 inside=255 periodicity=0 colors=000000<9>ab1ef1ij1<3>xz1<9>NO0JK0FG0<3>000<9>SVbVYfY`j<3>imz<9>HI\ OEFKBCG<3>000<8>aB8eC9iDA<3>zIE<9>O75K54G43<3>000<9>MbJOfLQjN<3>ZzV<9>DO\ BBK98G7<3>000<9>bJMfLOjNQ<3>zVZ<9>OBDK9BG89<3>000<9>CbADfBFjC<3>KzG<9>7O\ 66K55G4<3>000<8>aVTeZWiaZ<3>zok<9>OJIKGFGDC<3>000<9>03b03f03j<2>14v15z14\ v<14>000 } swatch7 { ; Version 2002 Patchlevel 3 ; Version 2002 Patchlevel 3 reset=2002 type=formula formulafile=swatch2.frm formulaname=swatch2 passes=b center-mag=-3.695e-006/-8.405e-006/0.9999915 params=1/-0.5 maxiter=256 inside=255 periodicity=0 colors=000000<9>ab1ef1ij1<3>xz1<9>NO0JK0FG0<3>000<9>SVbVYfY`j<3>imz<9>HI\ OEFKBCG<3>000<8>aB8eC9iDA<3>zIE<9>O75K54G43<3>000<9>MbJOfLQjN<3>ZzV<9>DO\ BBK98G7<3>000<9>bJMfLOjNQ<3>zVZ<9>OBDK9BG89<3>000<9>CbADfBFjC<3>KzG<9>7O\ 66K55G4<3>000<8>aVTeZWiaZ<3>zok<9>OJIKGFGDC<3>000<9>03b03f03j<2>14v15z14\ v<14>000 } swatch8 { ; Version 2002 Patchlevel 3 ; Version 2002 Patchlevel 3 reset=2002 type=formula formulafile=swatch2.frm formulaname=swatch2 passes=b center-mag=-3.695e-006/-8.405e-006/0.9999915 params=0.5/2 maxiter=256 inside=255 periodicity=0 colors=000000<9>ab1ef1ij1<3>xz1<9>NO0JK0FG0<3>000<9>SVbVYfY`j<3>imz<9>HI\ OEFKBCG<3>000<8>aB8eC9iDA<3>zIE<9>O75K54G43<3>000<9>MbJOfLQjN<3>ZzV<9>DO\ BBK98G7<3>000<9>bJMfLOjNQ<3>zVZ<9>OBDK9BG89<3>000<9>CbADfBFjC<3>KzG<9>7O\ 66K55G4<3>000<8>aVTeZWiaZ<3>zok<9>OJIKGFGDC<3>000<9>03b03f03j<2>14v15z14\ v<14>000 } frm:swatch2{ z=ig ig=ig+(1+imag(p1)) if(ig==256) ig=0 endif : z=z-real(p1) z } cheers, Guy
From: "Guy Marson" Sent: Saturday, May 25, 2002 7:14 PM
;-)))
swatch2 { ; Version 2002 Patchlevel 3
[...]
swatch3 { ; Version 2002 Patchlevel 3 [...] swatch4 { ; Version 2002 Patchlevel 3 [...] swatch5 { ; Version 2002 Patchlevel 3 [...] swatch6 { ; Version 2002 Patchlevel 3 [...] swatch7 { ; Version 2002 Patchlevel 3 frm:swatch2{ z=ig ig=ig+(1+imag(p1)) if(ig==256) ig=0 endif : z=z-real(p1) z }
Gold medal winner in the Hardcore Fractint Users Olympics? "The canditate has to manipulate the program in such ways the output resembles that of the 'ant' fractal type without ever using that particular fractal type at all..." Regards, Gerald
From: "Morgan L. Owens" Sent: Saturday, May 25, 2002 10:27 AM
To be honest, that larger one is actually known to be broken [...] To confess further, I've found situations where the original four-circle code fails to ensure proper tangency.
I sincerely hope you didn't interprete my quip about your pars trying to beat Mathematica as some form of ironic critique. [...]
myself wishing I could use arrays and nested loops. And a debugger.
How often I've been sitting in front of the monitor testing a formula way simpler than these - totally frustrated. ("I don't get it! Look what it's doing *now*!")
Some earlier attempts of mine broke Fractint. "Too many jumps" it said...
To tell the truth, the last time I pushed the parser's limits was when it allowed no more than 250 instructions and got a "formula to big" regularly when the maximum was 80...
And one more confession. I could have made them twice as fast, and my own personal copies do. The problem is that they achieve their speedup by means of a hack that relies on something which I consider to be a bug (or rather, enhancement opportunity) in the Fractint formula parser.
The "bug" is that values computed for one pixel are still retained when the next pixel is calculated.
I feel a bit uneasy about using a program's undocumented features. In case things are changed in a future version...
The Opportunity. The above is a dirty hack. One should instead have a per-image initialisation section in Fractint formulae just as there is now for per-pixel initialisation.
Yes. That's definitely missing. On the other hand: Considering how Fractint evolved - changes and extensions by many different authors submitted over the years - it's no wonder the program has its idiosyncrasies. Still,the implementation of the formula parser was pivotal IMHO (I, at least, wouldn't have used it to such an extent without it). And I'm not sure you would see such *extensive* scripting capabilities in some modern fractal renderers without Fractint existing. Regards, Gerald
At 08:35 27/05/2002, Gerald K. Dobiasovsky wrote:
From: "Morgan L. Owens" Sent: Saturday, May 25, 2002 10:27 AM
To be honest, that larger one is actually known to be broken [...] To confess further, I've found situations where the original four-circle code fails to ensure proper tangency.
I sincerely hope you didn't interprete my quip about your pars trying to beat Mathematica as some form of ironic critique.
Not at all - since I don't actually have Mathematica yet, I have to make do with what I've got :-) Just to show there's no hard feelings; here's another Kleinian circle formula. This derives from a problem by Appollonius: Given three circles in the plane, find a fourth circle tangent to the given three. There are eight solutions in general, depending on whether the given circles are to be inside or outside the tangent circle; this one just picks the solution where all three are outside (I'll use imag(p5) to make this configurable later, and figure out which circles need to have negative radii). Every circle will be tangent to at least one other, and one of the circles will be tangent to the other three - further tangencies are the responsibility of the user. This was a situation where I wish I had Mathematica to do the algebra for me. I banged my head for several hours, got stuck, went to http://mathworld.wolfram.com/, found that I'd pretty much done that, went back, realised what I was missing (two lines), fixed a coupla typos and the rest fell into place. Exercise for the reader: Solve the Appollonian problem yourself, without peeking at the code or reference materials. Parameters: real(p1), imag(p1), real(p2); centre and radius of first circle imag(p2), real(p3), imag(p3); centre and radius of second circle real(p4), imag(p4), real(p5); centre and radius of third circle Like I said, imag(p5) will be getting a use soon. I might also do some extra checking to cope with collinear given circles (i.e., the tangent circle becomes a straight line). I take no responsibility if the first three circles overlap - though the tangent circle is still constructed, I can only invert in one circle at a time, and which one is used in regions of overlap is pretty arbitrary. 4ApolloKlein1{ ax=real(p1),ay=imag(p1),ar=real(p2) bx=imag(p2),by=real(p3),br=imag(p3) cx=real(p4),cy=imag(p4),cr=real(p5) h=sqr(ax)+sqr(ay)-sqr(ar) a=2*(ar-br),b=2*(ax-bx),c=2*(ay-by),d=h-(sqr(bx)+sqr(by)-sqr(br)) e=2*(ar-cr),f=2*(ax-cx),g=2*(ay-cy),h=h-(sqr(cx)+sqr(cy)-sqr(cr)) l=(b*g-c*f) i=(d*g-c*h)/l,j=(a*g-c*e)/l,k=(b*h-d*f)/l,l=(b*e-a*f)/l m=2*(1-sqr(l)-sqr(l)) n=2*(cr+(i-cx)*j+(k-cy)*l) o=2*(cr^2-sqr(i-cx)-sqr(k-cy)) r=sqrt(sqr(n)-m*o) r1=(-n-r)/m r2=(-n+r)/m if(imag(r1)==0 && real(r1)>0) r=r1 else r=r2 endif x=i-j*r y=k-l*r ap=real(ax)+flip(ay) bp=real(bx)+flip(by) cp=real(cx)+flip(cy) p=real(x)+flip(y) arr=sqr(ar) brr=sqr(br) crr=sqr(cr) rr=sqr(r) z=pixel: : inside=0 if(|z-ap|<arr) z=ar*conj(ar/(z-ap))+ap inside=1 elseif(|z-bp|<brr) z=br*conj(br/(z-bp))+bp inside=1 elseif(|z-cp|<crr) z=cr*conj(cr/(z-cp))+cp inside=1 elseif(|z-p|<rr) z=r*conj(r/(z-p))+p inside=1 endif inside}
Still,the implementation of the formula parser was pivotal IMHO (I, at least, wouldn't have used it to such an extent without it). And I'm not sure you would see such *extensive* scripting capabilities in some modern fractal renderers without Fractint existing.
Quite probably so; I hope no-one thought I was disparaging the formula parser - I was just pointing out one way it could be improved (and who would claim that it couldn't be?) The precalc test could also be added to the above formula. Morgan L. Owens "After a buildup like that it'll probably be pretty disappointing."
From: "Morgan L. Owens" Sent: Monday, May 27, 2002 10:04 AM (Formula cut and pasted into a .frm file...)
Quite probably so; I hope no-one thought I was disparaging the formula parser - I was just pointing out one way it could be improved (and who would claim that it couldn't be?) The precalc test could also be added to the above formula.
No, what I really was driving at is that at first the parser certainly was just there to provide basic customization: If one wanted a different iteration formula, a different pixel initialization routine, a different bailout test, it was there, no more. Extending it in (then) unexpected ways stood a good chance of producing shortcomings (I mean, the whole program has grown like that and the developers now have to wrestle with what has become of it)... Regards, Gerald
Gerald K. Dobiasovsky wrote:
Still,the implementation of the formula parser was pivotal IMHO (I, at least, wouldn't have used it to such an extent without it). And I'm not sure you would see such *extensive* scripting capabilities in some modern fractal renderers without Fractint existing.
It is amazing how many of the modern (and even older) fractal generators owe their beginnings, or even many of their functions and abilities, to FractInt. After all, look how many have the ability to open and use the PAR, FRM, and/or MAP files which comes from FractInt. This was one of the major promotional features of UltraFractal, since it was written to take advantage of all three of these FractInt files. And any program outside of FractInt which uses the FRM files must have that extensive scripting capability. Sincerely, P.N.L. -------------------------------------------------------------- http://www.fractalus.com/cgi-bin/theway?ring=fractals&id=43&go
From: "Morgan L. Owens" Sent: Wednesday, May 22, 2002 3:28 PM
I think I'm outclassed. I mean, here's me still tinkering in two dimensions... Next thing to do would be to parameterise things a bit...
As much as I like ego strokes (who doesn't?) cudos should go to the POV-Ray team: A few years ago I nosed around in POV's source - the sphere and plane intersection code in my formulas is more or less gleaned from there (all I did was bolting the different pieces together...). As of more paramters, I've cobbled together a patch for both formulas to move the "camera" around a bit: ;---------------------- Parameter usage ----------------------- ;p1r: camera shift x ;p1i: camera shift y ;p2r: camera shift z ;p2i: rotation around x-axis (will be applied before p3r) :p3r: rotation around y-axis ;-------------------------------------------------------------- The patch proper has to replace everything below the coordinate constants (sphere centers and unit vector directions) up to the colon. ;------------- TetraSpheres and TetraSpheresBas --------------- tmp2 = pi/180 tmp1 = exp(flip(imag(p2)*tmp2)), tmp2 = exp(flip(real(p3)*tmp2)) dxy = flip(conj(tmp2)) ; pxy = tmp2*real(pixel) - dxy*imag(tmp1)*imag(pixel) pz = imag(pxy) + real(p2) pxy = real(pxy) + flip(real(tmp1)*imag(pixel)) + p1 ; vxy = dxy*real(tmp1) vz = imag(vxy) vxy = real(vxy) + flip(imag(tmp1)) : ;-------------------------------------------------------------- In TetraSpheresBas also replace ":" with "j = 1:" That's all, Gerald And now on to the new so called "only 2d" stuff you have brewed up...
From: "Morgan L. Owens" Sent: Wednesday, May 22, 2002 3:28 PM
I've touched up mine a bit, and added a few more. This time I've even chucked in a coupla pars.
Great pars all, but especially the embossed look of #2 and the surprising "odd-man-out"-effect in the last one! Regards, Gerald
----- Original Message ----- From: "Morgan L. Owens" <packrat@nznet.gen.nz> Sent: Wednesday, May 22, 2002 6:28 AM Subject: Re: [Fractint] At it again...
I think I'm outclassed. I mean, here's me still tinkering in two dimensions... Next thing to do would be to parameterise things a bit...
I've touched up mine a bit, and added a few more. This time I've even chucked in a coupla pars.
Morgan L. Owens
Wow! that first trilattice is quite an eye-catcher, and, for me at least, has a strangely disturbing effect on the eyeballs! Can't seem to establish a centre of attention. Additionally, I found that treating the image as a 3-D pair gives a very nice impression of a crystal lattice floating in space. John W.
participants (8)
-
bmc1 -
Franktal Gallery -
Gerald K. Dobiasovsky -
Guy Marson -
John Lewis -
John W. -
Morgan L. Owens -
Paul N. Lee