





 
 




 
 


On 12/06/2024 17:52, Bald Eagle wrote:
> That's a beauty.
Thanks
> I'll bet that would amazing done in glass with caustics.
Hum.. hum... lot of work.
I have to think about it
> Or as stone spheres in a field of grass.
Easier and faster. First test attached.
Does it match your idea ?
Note :
 Random textures from "stones.inc" without optimization
 Makegrass macro from Gilles Tran

Kurtz le pirate
Compagnie de la Banquise
Post a reply to this message
Attachments:
Download 'papus_grass.jpg' (1510 KB)
Preview of image 'papus_grass.jpg'


 
 




 
 


hi,
kurtz le pirate <kur### [at] gmailcom> wrote:
> ...
> wip here : {...}
the "l'image en noir et blanc" does it for me, v nice.
regards, jr.
Post a reply to this message


 
 




 
 


kurtz le pirate <kur### [at] gmailcom> wrote:
> I'm working on it too.
>
> wip here : <http://louisbel.free.fr/scenes/scene038.shtml>
> (in french for the moment)
Very nice. Excellent work as always!
I see you've been going over the same references as I have.
I just started watching Daniel Schiffman's video this morning  I was hoping to
start writing some code based on it after work.
I'm still amazed that "Beyond the Descartes Circle Theorem" was only published
in 2001! :O
I recall in one of the sites that I stumbled across, there was a method for
calculating how many circles there were for any given level of recursion.
That might be a nice addition to the debug stream, as well as warning/sanity
check before a render is attempted to be started with too high a level of
recursion for the system it's being run on.
It would also be nice to have a few ways to generate the output, so that the
gasket could be further used in a more complex scene.
1. Someone might want the tori to overlap such that the centers of their minor
radii are coincident/tangent, OR they might want the outside surfaces of the
tori to be tangent.
2. The coloration of each level of recursion ought to be able to be specified by
something like an array. That way different textures and normals, etc can be
applied. Also, it could then be rendered and subsequently used as a
heightfield.
3. There might be a desire to texture the circles based on their radius, or from
the distance from the center of the outer circle.
I've also found PDF and djvu copies of "Indra's Pearls" on the web, and they
have some very interesting algorithms to render a wide variety of variations on
this theme.
The authors even mention that some madman might be able to do this in Excel 
which is what I'm currently working on, since it's the only tool I have
available during the day. :D
 BW
Post a reply to this message


 
 




 
 


On 13/06/2024 17:17, kurtz le pirate wrote:
> I'm working on it too.
> wip here : <http://louisbel.free.fr/scenes/scene038.shtml>
Really nice !
Especially metallike construction on black.
Also math surfaces in Scenes menu attracted my attention  I love them
also.

YB
Post a reply to this message


 
 




 
 


On 6/13/24 10:17, kurtz le pirate wrote:
> wip here :<http://louisbel.free.fr/scenes/scene038.shtml>
Cool!
Bill P.
Post a reply to this message


 
 




 
 


"Bald Eagle" <cre### [at] netscapenet> wrote:
> I just started watching Daniel Schiffman's video this morning  I was hoping to
> start writing some code based on it after work.
Well, I got partway there.
I'm botching _something_ up (as usual).
I need to stop blindly hacking and do some more thinking and learning.
#version 3.8;
global_settings {assumed_gamma 1.0 }
#declare S3 = sqrt(3);
#declare M = 3;
#declare C1 = < 1, 0, 1>+M*(x+y);
#declare C2 = <1, 0, 1>+M*(x+y);
#declare C3 = < 0, S3, 1>+M*(x+y);
camera {
location M*<1, S3/2, 2.25>
right x*image_width/image_height
up y
look_at M*<1, S3/2, 0>
//rotate y*15
}
sky_sphere {pigment {rgb 1}}
light_source {< 0, 0, 150> rgb 1}
#declare Line = 0.005;
cylinder {x*100, x*100, Line pigment {rgb x}}
cylinder {y*100, y*100, Line pigment {rgb y}}
#declare k4curvature1 = function (k1, k2, k3) {k1 + k2 + k3 + 2 * sqrt (k1*k2 +
k2*k3 + k3*k1)}
#declare k4curvature2 = function (k1, k2, k3) {k1 + k2 + k3  2 * sqrt (k1*k2 +
k2*k3 + k3*k1)}
// Make every circle a vector: <Real, Imaginary, Radius>
// Start out with <R, I, 0> to do math, and then tack on radius in last step
// That way add, subtract, and scalar multiplication are all just operations on
a vector
#macro Re(Z) Z.x #end
#macro Im(Z) Z.y #end
#macro Mult(z1, z2) <Re(z1)*Re(z2)  Im(z1)*Im(z2), Re(z1)*Im(z2) +
Im(z1)*Re(z2)> #end
#macro Sqrt (Z)
#local m = sqrt ( Re(Z)*Re(Z) + Im(Z)*Im(Z) );
#local Angle = atan2 (Im(Z), Re(Z)) / 2;
#local NewZ = sqrt(m)*<cos(Angle), sin(Angle)>;
NewZ
#end
#macro ComplexDescartes (C1, C2, C3, k4)
// z41 = (z1*k1 + z2*k2 + z3*k3 + 2 * sqrt (z1*k1*z2*k2 + z2*k2*z3*k3 +
z3*k3*z1*k1)) / k4
// z42 = (z1*k1 + z2*k2 + z3*k3  2 * sqrt (z1*k1*z2*k2 + z2*k2*z3*k3 +
z3*k3*z1*k1)) / k4
#local k1 = 1/C1.z;
#local k2 = 1/C2.z;
#local k3 = 1/C3.z;
#local z1 = <C1.x, C1.y>;
#local z2 = <C2.x, C2.y>;
#local z3 = <C3.x, C3.y>;
#local zk1 = z1*k1;
#local zk2 = z2*k2;
#local zk3 = z3*k3;
#local Sum = zk1 + zk2 + zk3;
#local Square = Mult (zk1, zk2) + Mult (zk2, zk3) + Mult (zk3, zk1);
#local Root = Sqrt (Square);
#local z41 = (Sum + 2*Root) / k4;
#local z42 = (Sum  2*Root) / k4;
#local Z41 = z41 + <0, 0, 1/k4>;
#local Z42 = z42 + <0, 0, 1/k4>;
#local Result = array [2] {Z41, Z42};
Result
#end
#macro Circle (C)
torus {abs(C.z), Line pigment {rgb 0} rotate x*90 translate <C.x, C.y, 0>}
#end
#declare k41 = k4curvature1 (1/C1.z, 1/C2.z, 1/C3.z);
#declare k42 = k4curvature2 (1/C1.z, 1/C2.z, 1/C3.z);
#declare C41 = ComplexDescartes (C1, C2, C3, k41);
#declare C42 = ComplexDescartes (C1, C2, C3, k42);
#if (0)
Circle (C1)
Circle (C2)
Circle (C3)
Circle (C41[0])
Circle (C42[1])
#end
#macro DrawCircles (Array)
#local Circles = dimension_size (Array, 1)1;
#for (C, 0, Circles)
Circle (Array [C])
#end
#end
#declare AllCircles = array;
#declare AllCircles [0] = C1;
#declare AllCircles [1] = C2;
#declare AllCircles [2] = C3;
#declare Queue = array;
#declare Queue [0] = array [3] {C1, C2, C3};
//#declare Queue [0] = C1;
//#declare Queue [1] = C2;
//#declare Queue [2] = C3;
#declare Levels = 3;
#macro Gasket (RecursionLevels)
#for (L, 0, RecursionLevels)
#local Triplets = dimension_size (Queue, 1)1;
#for (T, 0, Triplets)
DrawCircles (Queue [T])
#end
#declare NextQueue = array;
#local QIndex = 0;
#for (T, 0, Triplets)
#local triplet = Queue [T];
#local c1 = triplet [0];
#local c2 = triplet [1];
#local c3 = triplet [2];
#local k41 = k4curvature1 (1/c1.z, 1/c2.z, 1/c3.z);
#local k42 = k4curvature2 (1/c1.z, 1/c2.z, 1/c3.z);
#declare new1 = ComplexDescartes (c1, c2, c3, k41);
#declare new2 = ComplexDescartes (c1, c2, c3, k42);
#local T1 = array [3] {c1, c2, new1[0]};
#local T2 = array [3] {c2, c3, new1[1]};
#local T3 = array [3] {c3, c1, new1[1]};
#local T4 = array [3] {c1, c2, new2[1]};
#local T5 = array [3] {c2, c3, new2[1]};
#local T6 = array [3] {c3, c1, new2[1]};
//#local T6 = array [3] {c2, c3, new1[1]};
#declare NextQueue [QIndex] = T1;
#local QIndex = QIndex + 1;
#declare NextQueue [QIndex] = T2;
#local QIndex = QIndex + 1;
#declare NextQueue [QIndex] = T3;
#local QIndex = QIndex + 1;
#declare NextQueue [QIndex] = T4;
#local QIndex = QIndex + 1;
#declare NextQueue [QIndex] = T5;
#local QIndex = QIndex + 1;
#declare NextQueue [QIndex] = T6;
#end // end for T
#declare Queue = NextQueue;
#end // end for L
#end
Gasket (Levels)
Post a reply to this message
Attachments:
Download 'appolonian_gasket.png' (62 KB)
Preview of image 'appolonian_gasket.png'


 
 




 
 


"Bald Eagle" <cre### [at] netscapenet> wrote:
> Well, I got partway there.
> I'm botching _something_ up (as usual).
I almost got it.
Removing one of the circle solutions cleaned up a bunch of unnecessary circles,
but the circles for the top right area are in the wrong place.
I'm wondering if there's some sign or floating point thing going on.
This is 5 levels of recursion.
Minor changes to recursion macro:
(mostly just 2 changes to an array index, restoring them to my initial values)
#macro Gasket (RecursionLevels)
#for (L, 0, RecursionLevels)
#local Triplets = dimension_size (Queue, 1)1;
#for (T, 0, Triplets)
DrawCircles (Queue [T])
#end
#declare NextQueue = array;
#local QIndex = 0;
#for (T, 0, Triplets)
#local triplet = Queue [T];
#local c1 = triplet [0];
#local c2 = triplet [1];
#local c3 = triplet [2];
#local k41 = k4curvature1 (1/c1.z, 1/c2.z, 1/c3.z);
#local k42 = k4curvature2 (1/c1.z, 1/c2.z, 1/c3.z);
#declare new1 = ComplexDescartes (c1, c2, c3, k41);
#declare new2 = ComplexDescartes (c1, c2, c3, k42);
#local T1 = array [3] {c1, c2, new1[0]};
#local T2 = array [3] {c2, c3, new1[0]};//
#local T3 = array [3] {c3, c1, new1[0]};//
#local T4 = array [3] {c1, c2, new2[1]};
#local T5 = array [3] {c2, c3, new2[1]};
#local T6 = array [3] {c3, c1, new2[1]};
//#local T6 = array [3] {c2, c3, new1[1]};
#declare NextQueue [QIndex] = T1;
#local QIndex = QIndex + 1;
#declare NextQueue [QIndex] = T2;
#local QIndex = QIndex + 1;
#declare NextQueue [QIndex] = T3;
#local QIndex = QIndex + 1;
#declare NextQueue [QIndex] = T4;
//#local QIndex = QIndex + 1;
//#declare NextQueue [QIndex] = T5;
#local QIndex = QIndex + 1;
#declare NextQueue [QIndex] = T6;
#end // end for T
#declare Queue = NextQueue;
#end // end for L
#end
Post a reply to this message
Attachments:
Download 'appolonian_gasket.png' (58 KB)
Preview of image 'appolonian_gasket.png'


 
 




 
 


"Bald Eagle" <cre### [at] netscapenet> wrote:
> I recall in one of the sites that I stumbled across, there was a method for
> calculating how many circles there were for any given level of recursion.
> That might be a nice addition to the debug stream, as well as warning/sanity
> check before a render is attempted to be started with too high a level of
> recursion for the system it's being run on.
https://en.wikibooks.org/wiki/Fractals/Apollonian_fractals
Post a reply to this message


 
 




 
 


A few quick explanations for those interested.
(I'd probably do a page on my site... but I'm so far behind ;) )
I haven't used Bald Eagle's inversion method, which looks very
interesting and promising.
The reference being the WIKIPEDIA page
<https://en.wikipedia.org/wiki/Pappus_chain>
 The two basic radii :
#declare BigRadius = SIZE; // AB/2
#declare SmallRadius = SIZE*3/4; // AC/2
 For the first circle (CB):
#declare cx = SmallRadius*2 + BigRadius  SmallRadius;
#declare r = BigRadius  SmallRadius;
DrawCircle(cx, 0, r)
 Next, a simple loop :
#declare r = SmallRadius/BigRadius;
#declare NthRadius = r;
#declare n = 1;
#while ( NthRadius > MIN_RADIUS )
#declare divisor = n*n*(1r)*(1r)+r;
#declare xx = 2*BigRadius*r*(1+r)/(2*divisor);
#declare yy = 2*BigRadius*n*r*(1r)/divisor;
#declare NthRadius = 2*BigRadius*r*(1r)/(2*divisor);
DrawCircle(xx, +yy, NthRadius)
DrawCircle(xx, yy, NthRadius) // symmetrically
#declare n = n + 1;
#end
The first tests were in 2D. So I made a macro that drew circles :
#macro DrawCircle(X,Y,R,C)
torus { R, rLine pigment { color C } rotate 90*x translate <X,Y,0> }
#end
Transformed for 3d :
#macro DrawCircle(X,Y,R,C)
sphere { <X,R,Y>, R pigment { color C } }
#end
A yes, I forgot! The end of the loop is controlled by the constancy
MIN_RADIUS. If the radius is "too" small, we stop.
#declare MIN_RADIUS = 0.50; for the stone spheres

Kurtz le pirate
Compagnie de la Banquise
Post a reply to this message


 
 




 
 


On 14/06/2024 16:30, Bald Eagle wrote:
> "Bald Eagle" <cre### [at] netscapenet> wrote:
> https://en.wikibooks.org/wiki/Fractals/Apollonian_fractals
This guy is working on similar things and making interactive toys:
https://observablehq.com/@esperanc/3dapollonianspherepackings

YB
Post a reply to this message


 
 




 

