POV-Ray : Newsgroups : povray.advanced-users : Using only POV-Ray keywords to make an equation solver Server Time
5 Dec 2025 23:07:39 EST (-0500)
  Using only POV-Ray keywords to make an equation solver (Message 1 to 1 of 1)  
From: Bald Eagle
Subject: Using only POV-Ray keywords to make an equation solver
Date: 5 Dec 2025 22:05:00
Message: <web.69339ccb36705cf71f9dae3025979125@news.povray.org>
Round and round we go.
IIRC, I wrote a solution for generating a parabola passing through 3 points for
jr at one point.
Recently I went through the solver code for the sor {} Catmull-Rom splines
And again I touched on the parabola solution while discussing math with my son.

I was looking a few things over to review the math and methods, and I said to
myself, "Hey - this all looks awfully familiar."

Why should I write code to solve a set of linear equations when the code already
exists in source and is exposed to the user through matrix transforms?

I'll likely follow this up with some other examples and explanatory text, but
for right now behold:  Solving a system of linear equation with 3 unknowns using
only keywords.  No "math" to speak of.

POV-Ray black magic.   :)

Go ahead: change P0, P1, or P2.

Enjoy,

- BE


#version version;
global_settings {assumed_gamma 1.0}


camera {
 location  <0, 0, -40>
 right  x*image_width/image_height
 up   y
 look_at  <0, 0, 0>
}

light_source {<0, 0, -50> rgb 1}

sky_sphere {pigment {rgb 0.2}}

plane {z, 0 pigment {checker rgb 0.15 rgb 0.2}}


#declare E = 0.000001;
#declare Line = 0.05;

cylinder {-x*100, x*100 Line pigment {rgb x}}
cylinder {-y*100, y*100 Line pigment {rgb y}}



#declare P0 = <0, 6>;
#declare P1 = <3, 3>;
#declare P2 = <-2, -3>;

#declare PointArray = array {P0, P1, P2}

#macro SolveParabola (P)
 // Just some setup stuff to keep later notation short
 #local X02 = P[0].x*P[0].x;
 #local X0  = P[0].x;
 #local Y0  = P[0].y;

 #local X12 = P[1].x*P[1].x;
 #local X1  = P[1].x;
 #local Y1  = P[1].y;

 #local X22 = P[2].x*P[2].x;
 #local X2  = P[2].x;
 #local Y2  = P[2].y;

 // Here's where we do the equation solving

 #local EquationMatrix =
 transform {
  matrix <
   X02, X12, X22,
   X0 , X1 , X2 ,
   1  , 1  , 1  ,
   0  , 0  , 0
  >
 }

 #local Inv = function {transform {EquationMatrix inverse}}

 #local Coeff = Inv (Y0, Y1, Y2);

 #local (a, b, c) = (Coeff.x, Coeff.y, Coeff.z);

 // And we're done.

 //#debug concat ("a = ", str(a, 0, 3),  " b = ", str(b, 0, 3), " c = ", str(c,
0, 3), "\n")


 #local ParabolaMatrix =
 transform {
  matrix <
   0, a, 0,
   1, b, 0
   0, c, 0
   0, 0, 0
  >
 }

 ParabolaMatrix

#end

// Now we can use a matrix transform again to make the function
#declare Parabola = function {transform {SolveParabola (PointArray)}}

#for (i, 0, 2)
 sphere {PointArray[i], Line*5 pigment {rgb y}}
#end

union {
 #for (i, 0, 20, 0.1)
  #local X = i-10;
  #local Xterms = <X*X, X, 1>;
  #local P = Parabola (Xterms.x, Xterms.y, Xterms.z)-z; // -z compensates for
POV-Ray's auto-fix of <0, 0, 0> scaling
  //#debug concat ("P = ", vstr(3, P, ", ", 0, 3), " \n")
  sphere {P, Line}
  #if (i>0)
   cylinder {LastP, P, Line}
  #end
  #local LastP = P;
 #end
 pigment {rgb 1}
}


Post a reply to this message

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