POV-Ray : Newsgroups : povray.animations : Dominoes Server Time
6 May 2026 11:22:05 EDT (-0400)
  Dominoes (Message 11 to 16 of 16)  
<<< Previous 10 Messages Goto Initial 10 Messages
From: Bald Eagle
Subject: Re: Dominoes
Date: 1 May 2026 12:20:00
Message: <web.69f4d1e7cea3e23eda82d88b25979125@news.povray.org>
"koppi" <jak### [at] gmailcom> wrote:

> I just have fixed the domino orientation along the spiral as you have suggested,

Perfect.
Now set up all the dominoes like so:

https://news.povray.org/povray.advanced-users/attachment/%3Cweb.659879b9cca34dee1f9dae3025979125%40news.povray.org%3E/m
athpatterns1.png

:D


Post a reply to this message

From: koppi
Subject: Re: Dominoes
Date: 1 May 2026 13:10:00
Message: <web.69f4dc6fcea3e23e993716b9199194f2@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:
> Now set up all the dominoes like so:
>
>
https://news.povray.org/povray.advanced-users/attachment/%3Cweb.659879b9cca34dee1f9dae3025979125%40news.povray.org%3E
/m
> athpatterns1.png

Bill, do you mean I should arrange some self similar, some sort of fractal
domino arrangement to the playground? - That's an interesting challenge!


Post a reply to this message

From: Bald Eagle
Subject: Re: Dominoes
Date: 1 May 2026 13:20:00
Message: <web.69f4e05acea3e23eda82d88b25979125@news.povray.org>
"koppi" <jak### [at] gmailcom> wrote:

> Bill, do you mean I should arrange some self similar, some sort of fractal
> domino arrangement to the playground? - That's an interesting challenge!

I was only half-joking, but if you can make it happen, then YES!

That pattern is from a shader on ShaderToy by Fabrice Neyret.  It was only like
6 lines of code.

Might help, might make it more confusing.

You might also have to consider adjusting the size of the dominoes as the
spirals get longer and the spacing is limited.

- BW


Post a reply to this message

From: koppi
Subject: Re: Dominoes
Date: 1 May 2026 13:30:00
Message: <web.69f4e262cea3e23e993716b9199194f2@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:
> That pattern is from a shader on ShaderToy by Fabrice Neyret.  It was only like
> 6 lines of code.
>
> Might help, might make it more confusing.

Foud it: https://www.shadertoy.com/view/XtSBDK
Will see, what can be done with it inside BPP ;-)


Post a reply to this message

From: Leroy
Subject: Re: Dominoes
Date: 1 May 2026 16:55:00
Message: <web.69f5120ccea3e23e2e883926f712fc00@news.povray.org>
"koppi" <jak### [at] gmailcom> wrote:
> "Leroy" <whe### [at] gmailcom> wrote:
> >  I was wondering how you place the dominoes. I use a spline for placement. I
> > have my dominoes placed 2 pov units apart. That because I don't use true physics
> > to move the dominoes.
>
> Archimedean spiral calculation is used to create the control points [1]:
>
>   [... line 47]:
>   local angle = (i - 1) * 0.09
>   local radius = 5 + angle * 0.95
>   cp = {
>     x = math.cos(angle) * radius,
>     y = y_pos,
>     z = math.sin(angle) * radius,
>   }
>   [...]
>

I basically did the same but written in POV3.7.


> The control points are then fed to the Catmull-Rom spline function [2] with the
> tension parameter set to 0.5.
>
> >  Noticed that your dominoes have different spacing, they got tighter toward the
> > center.
>
> I would like to have equal spacing between the dominoes, but I do not know how
> to calculate that, do you have an idea?
>

I'm a little late on this one, as you already have a better way than I have. I
wrote the spline starting from the outside in like normal. Then translated all
the control points so the outer point was <0,0,0>. That because these spirals
where made to be part of a bigger Field of dominoes and also be able to use a
spiral over & over & .....
 I use this spline to hunt down each domino point that was 2 pov units from the
last domino placed. I started at 0 +some very small number (.0001 I think) then
keep adding that small value until I got vlength(Oldpoint,Newpoint) =2. The only
problem was at the very end when the search point goes out of range. So I put a
Stop Gap if the search counter got to big.(.1 is to big) not very efficient.

> > Your physics engine did a good job of dropping them. I also like the
> > wiggle the engine gave to the already down dominoes.
>
> I have been experimenting with different parameters for the friction,
> restitution, linear and angular damping of the dominoes, currently using:
>
>   friction = 0.01
>   restitution = 0.01
>   damp_lin = 0.5
>   damp_ang = 0.01
>
> Kind regards,
> koppi
>
> --
> [1]
>
https://github.com/bullet-physics-playground/bpp/blob/b558bdf8e8ab23a1438d0162d40c7f0029eb3efd/demo/basic/11-domino.l
ua
>
> [2]
>
https://github.com/bullet-physics-playground/bpp/blob/b558bdf8e8ab23a1438d0162d40c7f0029eb3efd/demo/module/spline.lua
#L
> 134

Have Fun!


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Dominoes
Date: 5 May 2026 18:00:00
Message: <web.69fa66a1cea3e23ebe9d2d3f89db30a9@news.povray.org>
"koppi" <jak### [at] gmailcom> wrote:
> "Leroy" <whe### [at] gmailcom> wrote:
> >  I was wondering how you place the dominoes. I use a spline for placement. I
> > have my dominoes placed 2 pov units apart. That because I don't use true physics
> > to move the dominoes.
>
> Archimedean spiral calculation is used to create the control points [1]:
>
>   [... line 47]:
>   local angle = (i - 1) * 0.09
>   local radius = 5 + angle * 0.95
>   cp = {
>     x = math.cos(angle) * radius,
>     y = y_pos,
>     z = math.sin(angle) * radius,
>   }
>   [...]
>
> The control points are then fed to the Catmull-Rom spline function [2] with the
> tension parameter set to 0.5.
>
> >  Noticed that your dominoes have different spacing, they got tighter toward the
> > center.
>
> I would like to have equal spacing between the dominoes, but I do not know how
> to calculate that, do you have an idea?
> ...

Below is an example in POV-Ray SDL that places dominoes at a fixed
distance from each other along an Archimedean spiral (without using
splines).

A Newton-Raphson solver macro is used to find the placement points
analytically for high precision.

The dominoes are also oriented by a Frenet-Serret frame so that they
always face the same side forward along the spiral.

--
Tor Olav
http://subcube.com
https://github.com/t-o-k


// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.7;

global_settings {
    assumed_gamma 1
    ambient_light color rgb 0.2*<1, 1, 1>
}

#include "colors.inc"

#declare tau = 2*pi;

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

// Newton-Raphson macro to find the root of a function.
// Used in this example to find the angle (Theta) that
// corresponds to a given arc length.

#macro NewtonRaphson(Fn, DerFn, EstimatedRoot, Tolerance, MaxIter)

    #local Nil = 1e-12;
    #local EstRoot = EstimatedRoot;
    #if (Tolerance <= 0)
        #local Tolerance = 1e-6;
    #end // if
    #local I = 0;
    #local Continue = true;
    #while (Continue)
        #local DerVal = DerFn(EstRoot);
        #local UseableTangent = (Nil < abs(DerVal));
        #if (UseableTangent)
            #local CloserRoot = EstRoot - Fn(EstRoot)/DerVal;
            #local Delta = abs(CloserRoot - EstRoot);
            #local EstRoot = CloserRoot;
            #local I = I + 1;
            #local Continue = ((Tolerance < Delta) & (I < MaxIter));
        #else
            #local Continue = false;
        #end // if
    #end // while

    EstRoot

#end // macro NewtonRaphson

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

// Archimedes spiral (radius = g * th)

// _g: Growth rate (how fast the spiral spreads outward).
//     The radius increases by _g*tau mm per full revolution.
// _th: Rotation angle in radians.

// Position functions (calculates x and z from polar coordinates)
// <x, 0, z> are the cartesian coordinates for a point on the
// spiral at angle _th.
#declare FnX = function(_g, _th) { _g*_th*cos(_th) };
#declare FnZ = function(_g, _th) { _g*_th*sin(_th) };

// First derivatives of the functions (velocity),
// used to determine the tangent vector/direction of the curve.
#declare DerFnX = function(_g, _th) { _g*(cos(_th) - _th*sin(_th)) };
#declare DerFnZ = function(_g, _th) { _g*(sin(_th) + _th*cos(_th)) };


/*
Arc length function: Calculates the distance traveled along the spiral.
_g: Growth rate (how fast the spiral spreads outward).
_th: Final angle in radians (the angle the spiral has passed through).
*/

/*
#declare ArcLengthFn =
    function(_g, _th) {
        _g/2*(
            _th*sqrt(1 + pow(_th, 2)) +
            ln(_th + sqrt(1 + pow(_th, 2)))
        )
    }
;
#declare Asinh(_th) =
    function(_th) {
        ln(_th + sqrt(1 + pow(_th, 2)))
    }
;
*/

// Calculates the total distance traveled along the spiral curve,
// from the center to point the final angle.
#declare ArcLengthFn =
    function(_g, _th) {
        _g/2*(_th*sqrt(1 + pow(_th, 2)) + asinh(_th))
    }
;

// The first derivative of the arc length function:
#declare DerArcLengthFn =
    function(_g, _th) {
        _g*sqrt(1 + pow(_th, 2))
    }
;

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

// Domino piece geometry (L x W x T: 48mm x 24mm x 10mm)
// Oriented so it stands on the xz plane, growing in y.
#declare DominoPiece =
    union {
        // Centered at origin
        box {
            -<12, 24, 5>, +<12, 24, 5>
            pigment { color White }
        }
        // Direction markers for debugging the matrix orientation:
        cylinder {
            +12*x, +16*x, 2  // Local +x (Normal)
            pigment { color Red }
        }
        cylinder {
            +24*y, +28*y, 2  // Local +y (Binormal)
            pigment { color Green }
        }
        cylinder {
            +5*z,  +9*z, 2  // Local +z (Tangent)
            pigment { color Blue }
        }
        // Move bottom of piece to y = 0
        translate +24*y
    }


#declare NoOfPoints = 300;  // Also the number of dominoes.

#declare GrowthRate = 60/tau;  // mm/radian
// The radial distance between centerlines of successive
// windings (the pitch) will be 60mm.

// Distance between centers of dominoes along the spiral path.
#declare StepLength = 25;  // mm


// Calculate angles (Thetas) for each domino using numerical inversion.

#debug "\n"
#declare Thetas = array[NoOfPoints];
#declare Thetas[0] = 0;
#for (I, 1, NoOfPoints - 1)
    #declare TargetLength = I*StepLength;
    #declare Thetas[I] =
        NewtonRaphson(
            function(_th) {
                ArcLengthFn(GrowthRate, _th) - TargetLength
            },
            function(_th) {
                DerArcLengthFn(GrowthRate, _th)
            },
            Thetas[I-1],  // Use previous angle as start estimate
            1e-6,
            10
        )
    ;
    #declare AchievedLength = ArcLengthFn(GrowthRate, Thetas[I]);
    #debug str(AchievedLength - TargetLength, 0, 14)
    #debug "\n"
#end // for
#debug "\n"


// Define specific instances of the functions
// for the chosen growth rate

#declare X_Fn = function(_th) { FnX(GrowthRate, _th) };
#declare Z_Fn = function(_th) { FnZ(GrowthRate, _th) };

#declare DerX_Fn = function(_th) { DerFnX(GrowthRate, _th) };
#declare DerZ_Fn = function(_th) { DerFnZ(GrowthRate, _th) };

/*
pP: Position on spiral
vT: Tangent vector (Forward direction)
vB: Binormal vector (Up direction)
vN: Normal vector (Side direction, perpendicular to curve)
*/

// Render the dominoes
union {
    #declare vB = vnormalize(<0, 1, 0>);  // = <0, 1, 0>
    // Start at 1 to skip the domino piece in the center
    #for (I, 1, NoOfPoints - 1)
        #declare Th = Thetas[I];
        #declare pP = <X_Fn(Th), 0, Z_Fn(Th)>;
        #declare vT = vnormalize(<DerX_Fn(Th), 0, DerZ_Fn(Th)>);
        #declare vN = vcross(vB, vT);
        object {
            DominoPiece
            matrix <
                vN.x, vN.y, vN.z, // Maps local x to Side
                vB.x, vB.y, vB.z, // Maps local y to Up
                vT.x, vT.y, vT.z, // Maps local z to Forward
                pP.x, pP.y, pP.z  // Translates to spiral position
            >
        }
    #end // for
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

sky_sphere { pigment { color Gray } }

// A checkered floor plane to provide visual context and shadows
plane {
    y, 0  // The ground plane at y = 0
    pigment {
        checker
        color 0.05*White  // Dark squares
        color 0.60*White  // Light squares
        scale 60 // Each square matches the pitch of the spiral (60mm)
    }
}

light_source {
    100*<6, 14, 3>
    color White
}

#declare AspectRatio = image_width/image_height;

camera {
 orthographic
    location +1000*y
 right +900*AspectRatio*x
 up +900*z
    direction -y
}

/*
camera {
    location 120*<+1, +3, -5>
    look_at 100*< 0, -1,  0>
}
*/

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

<<< Previous 10 Messages Goto Initial 10 Messages

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.