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