POV-Ray : Newsgroups : povray.binaries.images : Is there a spline solution out there? Server Time
1 Oct 2024 20:23:10 EDT (-0400)
  Is there a spline solution out there? (Message 11 to 17 of 17)  
<<< Previous 10 Messages Goto Initial 10 Messages
From: Greg M  Johnson
Subject: Re: Is there a spline solution out there?
Date: 11 Aug 2000 14:33:10
Message: <399445AE.EB50AD7F@my-dejanews.com>
Looks brilliant, but:
0) I assume I need a defined array of Points, right?
1) you didn't define Bias anywhere, and this gives me an error.
2) how would I call the points from it??

Jerry Anning wrote:

> On Fri, 11 Aug 2000 09:19:42 -0400, "Greg M. Johnson"
> <gre### [at] my-dejanewscom> wrote:
>
> >Thanks, but I want it to work WITHIN pov. It's the angle of rotation of a knee in a
> >walk cycle.  This is come kind of "C" code, no?
>
> Here are the key guts of a Tau spline implementation within pov.  The
> Tau spline is a Catmull-Rom spline with tension and bias parameters.
> This means that:
>  it will pass through the control points
> you can control how much it bends (and how smooth the curve is) with
> tension
> you can control which end of a segment the maximum bend is near with
> bias.
> Incidentally, the cubic interpolation (cerp) and Horner's method
> (horn) macros can create many other spline types with an appropriate
> control matrix.  You should be able to figure out the rest from here.
> If not email and I will send you a full demo as health permits.
> This expects your control points to be in the array Points and  Bias
> and Tens to be (0 to 1) variables already declared.  The other
> variables are either obvious or irrelevant material from the original
> project.
>
> // begin partial code snippet
> #macro Mxv(In, Mx)
>   <max(In.x, Mx.x), max(In.y, Mx.y), max(In.z, Mx.z)>
> #end
>
> #macro Mnv(In, Mn)
>   <min(In.x, Mn.x), min(In.y, Mn.y), min(In.z, Mn.z)>
> #end
>
> #declare Tau = array[4][4]
>   {
>     { (Bias - 1) * Tens, 2 - Bias * Tens, (1 - Bias) * Tens - 2, Bias
> * Tens },
>     { 2 * (1 - Bias) * Tens, (3 * Bias - 1) * Tens - 3, 3 - Tens,
> -Bias * Tens },
>     { (Bias - 1) * Tens, (1 - 2 * Bias) * Tens, Bias * Tens, 0 },
>     { 0, 1, 0, 0 }
>   }
>
> #macro Horn(Row, Pt)
>   (T * ( T * (T * Tau[0][Row] + Tau[1][Row]) + Tau[2][Row]) +
> Tau[3][Row]) * Pt
> #end
>
> #macro Cerp(Pf)
>   Horn(0, Points[Pf - 1]) + Horn(1, Points[Pf]) +
>   Horn(2, Points[Pf + 1]) + Horn(3, Points[Pf + 2])
> #end
>
> union
>   {
>     #declare Iter = 1;
>     #while(Iter < Dim + 2 * Close)
>       #declare Count = max(1, int(Fine * vlength(Points[Iter + 1] -
> Points[Iter])));
>       #declare Incr = 1 / Count;
>       #declare T = 0;
>       #while(T < 1)
>         #declare Start = Mxv(Mnv(Cerp(Iter), <24 * Aspect, 24, 24>),
>                          <-24 * Aspect, -24, 0>);
>         #declare T = T + Incr;
>         #declare End = Mxv(Mnv(Cerp(Iter), <24 * Aspect, 24, 24>),
>                        <-24 * Aspect, -24, 0>);
>         #declare End = ((End.x = Start.x) ? End + <.001, 0, 0> : End);
>         sphere { Start, Width }
>         cylinder { Start, End, Width }
>
>       #end
>     #end
>   }
> // end partial code snippet
> Jerry Anning
> clem "at" dhol "dot" org


Post a reply to this message

From: Chris Colefax
Subject: Re: Is there a spline solution out there?
Date: 12 Aug 2000 00:41:59
Message: <3994d597@news.povray.org>
Greg M. Johnson <gre### [at] my-dejanewscom> wrote:
> I want a smoothly varying function that goes between the following
> points:
[snipped point list]
> The function/ spline will serve as a keyframing notation for the joints
> in a body, ala < timei , thetai >. Such that if I call out 0.375 for the
> x, I should get something not too far from 117.
>
> My own "cosinespline" is inadequate (see 04/14/00 posting) :  not much
> better than straight lines.  Chris Colefax's macro has a ton of options
> which offer some promise, but it is woefully lacking an adequate
> explanation of what he dreamed up. I'm suspecting it cannot even handle
> an irregular list like above.

Apologies for the current lack of documentation for the Spline macro!
Although it can handle splines of 2D vectors, it's not designed for values
in the form you have (i.e. <time, value>).  The ability to specify times
with spline values was a feature I had coded into an earlier version, but I
removed it in the name of simplicity (the macro file is complicated enough
as it stands!).

As an alternative, I might suggest the Automatic Clock Modifier, used with
the S-Curve clock type, e.g.:

   #include "autoclck.mcr"
   rotate From (0, -15) Using ("S", 1, 1, "") To (0.25, -125) To
(0.45, -110) ...

Of course, you could use other clock types to suit your purposes (e.g. if
you wanted the rotation to accelerate from one point to another, or
deccelerate, etc.).  If this doesn't produce what you're after, and you
still want to try the Spline macro, feel free to ask any questions you think
I might be able to answer...!


Post a reply to this message

From: Anton Sherwood
Subject: Re: Cubic spline mentioned above 18kbbu
Date: 12 Aug 2000 20:44:14
Message: <3995F0FB.254EACFA@pobox.com>
"Greg M. Johnson" wrote:
> This is actually supposed to be the rotation of a knee across a walk cycle.

Does a knee really bend to 125 degrees in walking?

> In your solution, which is very similar to mine, the knee would be bending
> backwards (theta>>0) during part of the cycle.  If you look at my solution
> in the blue curve that I posted, it is devoid of the above error, but so flat
> it is not much  better than straight lines.

Wish you'd said in the first place that you want the spline to stay
below zero.
One way to do that is to square some function that crosses the axis in
the segment where you want tangency.  Thus, for the segment 0.50 < t <
0.75, we take y=square(4*(t-1/2)*(sqrt(25)-sqrt(10))-sqrt(10)).  Then
spline the remaining segments to match the slopes of this parabola.

Of course you could fit a periodic function to
	0.00	sqrt(15)
	0.25	sqrt(125)
	0.45	sqrt(110)
	0.50	sqrt(10)
	0.75	-sqrt(25)
	1.00	-sqrt(15)
	1.25	-sqrt(125)
	1.45	-sqrt(110)
	1.50	-sqrt(10)
	1.75	sqrt(25)
	2.00	sqrt(15)
(where the left column is multiples of pi), square that, and use it at
half frequency.

-- 
Anton Sherwood  --  br0### [at] p0b0xcom  --  http://ogre.nu/


Post a reply to this message

From: Jerry Anning
Subject: Re: Is there a spline solution out there?
Date: 13 Aug 2000 11:46:37
Message: <3996b314.586738@news.povray.org>
On Fri, 11 Aug 2000 14:27:58 -0400, "Greg M. Johnson"
<gre### [at] my-dejanewscom> wrote:

>Looks brilliant, but:
>0) I assume I need a defined array of Points, right?
>1) you didn't define Bias anywhere, and this gives me an error.
>2) how would I call the points from it??

>>
>> // begin partial code snippet
>> #macro Mxv(In, Mx)
>>   <max(In.x, Mx.x), max(In.y, Mx.y), max(In.z, Mx.z)>
>> #end
>>
>> #macro Mnv(In, Mn)
>>   <min(In.x, Mn.x), min(In.y, Mn.y), min(In.z, Mn.z)>
>> #end
>>
>> #declare Tau = array[4][4]
>>   {
>>     { (Bias - 1) * Tens, 2 - Bias * Tens, (1 - Bias) * Tens - 2, Bias
>> * Tens },
>>     { 2 * (1 - Bias) * Tens, (3 * Bias - 1) * Tens - 3, 3 - Tens,
>> -Bias * Tens },
>>     { (Bias - 1) * Tens, (1 - 2 * Bias) * Tens, Bias * Tens, 0 },
>>     { 0, 1, 0, 0 }
>>   }
>>
>> #macro Horn(Row, Pt)
>>   (T * ( T * (T * Tau[0][Row] + Tau[1][Row]) + Tau[2][Row]) +
>> Tau[3][Row]) * Pt
>> #end
>>
>> #macro Cerp(Pf)
>>   Horn(0, Points[Pf - 1]) + Horn(1, Points[Pf]) +
>>   Horn(2, Points[Pf + 1]) + Horn(3, Points[Pf + 2])
>> #end
>>
>> union
>>   {
>>     #declare Iter = 1;
>>     #while(Iter < Dim + 2 * Close)
>>       #declare Count = max(1, int(Fine * vlength(Points[Iter + 1] -
>> Points[Iter])));
>>       #declare Incr = 1 / Count;
>>       #declare T = 0;
>>       #while(T < 1)
>>         #declare Start = Mxv(Mnv(Cerp(Iter), <24 * Aspect, 24, 24>),
>>                          <-24 * Aspect, -24, 0>);
>>         #declare T = T + Incr;
>>         #declare End = Mxv(Mnv(Cerp(Iter), <24 * Aspect, 24, 24>),
>>                        <-24 * Aspect, -24, 0>);
>>         #declare End = ((End.x = Start.x) ? End + <.001, 0, 0> : End);
>>         sphere { Start, Width }
>>         cylinder { Start, End, Width }
>>
>>       #end
>>     #end
>>   }
>> // end partial code snippet

1) Yes, you declare and define Points - the array of control points
for the spline, not the points along it - before you call the macros.

2) Likewise, you declare and define Bias and Tens before you create
the Tau matrix.

3) Points, as I said, is the control point array, not an array of
output points.  Calling Cerp(Iter) gives the current output point.

I am a bit more coherent today, so here is a cleaned up  and expanded
version of the above code with some more explanation of the variables
and operation.  Note the additions.  The material I removed in this
version has to do with constraining the curve, adjusting the aspect
ratio of the output, dealing with closed curves and other things
irrelevant to the point.

Iter determines which pair of control points you are running the curve
between at the moment.

T determines how far along you are between those control points at the
moment.

The business with Fine and Count decide how many sphere and cylinder
pairs you will draw between each pair of control points.

If you just want to return points along the curve for later use, strip
off the union in the last section and remove the parts about End, and
the sphere and cylinder declarations.  Start will be a point along the
output curve.

 // begin partial code snippet

#declare Dim = 6;  // this means an array of 6 control points.

#declare Points = array[Dim]
 { <.1, .5, .9>, <.8, 2, 3> ...} // the control points.

#declare Bias = .5; // max curvature midway between control points

#declare Tens = .5; // curve halfway between loopy and linear
// these bias and tens settings look like a Catmull-Rom spline
// higher tens and bias close to 0 (or 1) makes the curve look like
// (almost) straight lines between the control points with rounded
// "corners" at the control points.  I think that fits your described
// requirements

#declare Fine = 10 // 10 is quick and dirty resolution, 50 or 100
// , say, would be much finer detail (but slower, of course)

#declare Type = "Tau" // type of spline you want.
// for comparison I am adding a matrix for a Beta spline
// (the C-code guys' suggested spline) - like Tau except
// it only approximates the control points instead of passing
// through them (like the difference between the Catmull-Rom
// and B-splines).  Use Type = "Beta" instead of Type = "Tau"

 #declare Tau = array[4][4]
   {
     { (Bias - 1) * Tens, 2 - Bias * Tens, (1 - Bias) * Tens - 2, Bias
 * Tens },
     { 2 * (1 - Bias) * Tens, (3 * Bias - 1) * Tens - 3, 3 - Tens,
-Bias * Tens },
     { (Bias - 1) * Tens, (1 - 2 * Bias) * Tens, Bias * Tens, 0 },
     { 0, 1, 0, 0 }
   }

 #declare Divi = Tens + 2 * (Bias * (Bias * (Bias + 2) + 2) + 1);

#declare Bet = array[4][4]
  {
    { -2 * Bias * Bias * Bias / Divi,
    		 2 * (Tens + (Bias * (Bias * (Bias + 1) + 1))) / Divi,
      -2 * (Tens + Bias * (Bias + 1) +1) / Divi, 2 / Divi },
    { 6 * Bias * Bias * Bias / Divi,
    		-3 * (Tens + 2 *(Bias * Bias * (Bias + 1))) / Divi,
      3 * (Tens + 2 * Bias * Bias) / Divi, 0 },
    { -6 * Bias * Bias * Bias / Divi,
    		6 * Bias * (Bias * Bias - 1) / Divi, 6 * Bias / Divi, 0 },
    { 2 * Bias * Bias * Bias / Divi, (Tens + 4 * Bias * (Bias + 1)) /
Divi,
    	  2 / Divi, 0 }
  }
  
#undef Divi
  
 #if(strcmp(Type, "Tau") = 0)
      #declare Use = Tau
 #else
      #if(strcmp(Type, "Beta") = 0)
         #declare Use = Bet
     #end
#end

#macro Horn(Row, Pt)
   (T * ( T * (T * Use[0][Row] + Use[1][Row]) + Use[2][Row]) +
 Use[3][Row]) * Pt
 #end

 #macro Cerp(Pf)
   Horn(0, Points[Pf - 1]) + Horn(1, Points[Pf]) +
   Horn(2, Points[Pf + 1]) + Horn(3, Points[Pf + 2])
 #end

 union // this union is the output curve
   {
     #declare Iter = 1;
     #while(Iter < Dim)
       #declare Count = max(1, int(Fine * vlength(Points[Iter + 1] -
 Points[Iter])));
       #declare Incr = 1 / Count;
       #declare T = 0;
       #while(T < 1)
         #declare Start = Cerp(Iter);
         #declare T = T + Incr;
         #declare End = Cerp(Iter);
         #declare End = ((End.x = Start.x) ? End + <.001, 0, 0> :
End); // this avoids a degenerate cylinder
         sphere { Start, Width }
         cylinder { Start, End, Width }

       #end
      #declare Iter = Iter + 1; // oops! I left this line out somehow
     #end
   }
 // end partial code snippet

Jerry Anning
clem "at" dhol "dot" org


Post a reply to this message

From: Greg M  Johnson
Subject: Re: Is there a spline solution out there?
Date: 14 Aug 2000 09:10:03
Message: <3997EE73.46EB54DA@my-dejanews.com>
I get an error message for subscript out of range when it hits the code:

 + Horn(3, Points[Pf + 2])


Jerry Anning wrote:

> I am a bit more coherent today, so here is a cleaned up  and expanded
> version of the above code with some more explanation of the variables
> and operation.


Post a reply to this message

From: Jerry Anning
Subject: Re: Is there a spline solution out there?
Date: 14 Aug 2000 13:19:45
Message: <399828d1.2275552@news.povray.org>
On Mon, 14 Aug 2000 09:04:51 -0400, "Greg M. Johnson"
<gre### [at] my-dejanewscom> wrote:

>I get an error message for subscript out of range when it hits the code:
>
> + Horn(3, Points[Pf + 2])

This shows the perils of cut-and-pasting parts of messy one-off code.
replace the part at the beginning where you set up the Points array
with this:

#declare Dim = 6;  // this means an array of 6 control points

#declare Ptemp = array[Dim]
 { <.1, .5, .9>, <.8, 2, 3> ...} // temp for the control points

#declare Points = array[Dim + 2] // will be actual working points

#declare Points[0] = Ptemp[Dim - 1]; // this and following line
// allow for first and last points properly

#declare Points[Dim + 1] = Ptemp[0];

Discussion:  in most spline types, including these, the first and last
control points are not part of the final curve.  This fixes things so
that *all* of the control points (corners) you provide are part of the
curve and you get the endpoints you expect.  I left this out earlier
because I stupidly confused it with part of the closure code that I
removed.

Jerry Anning
clem "at" dhol "dot" org


Post a reply to this message

From: Greg M  Johnson
Subject: Re: Is there a spline solution out there?
Date: 15 Aug 2000 08:59:15
Message: <39993D70.357645D3@my-dejanews.com>
Apologies, O Great One, but I still get error messages, even after I figured
that I needed to add code to define

        #declare Points[nnn]=Ptemp[nnn];

Could you just post the whole working kaboodle at p.b.s-f?

Jerry Anning wrote:

> On Mon, 14 Aug 2000 09:04:51 -0400, "Greg M. Johnson"
> <gre### [at] my-dejanewscom> wrote:
>
> >I get an error message for subscript out of range when it hits the code:
> >
> > + Horn(3, Points[Pf + 2])
>
> This shows the perils of cut-and-pasting parts of messy one-off code.
> replace the part at the beginning where you set up the Points array
> with this:
>
> #declare Dim = 6;  // this means an array of 6 control points
>
> #declare Ptemp = array[Dim]
>  { <.1, .5, .9>, <.8, 2, 3> ...} // temp for the control points
>
> #declare Points = array[Dim + 2] // will be actual working points
>
> #declare Points[0] = Ptemp[Dim - 1]; // this and following line
> // allow for first and last points properly
>
> #declare Points[Dim + 1] = Ptemp[0];
>
> Discussion:  in most spline types, including these, the first and last
> control points are not part of the final curve.  This fixes things so
> that *all* of the control points (corners) you provide are part of the
> curve and you get the endpoints you expect.  I left this out earlier
> because I stupidly confused it with part of the closure code that I
> removed.
>
> Jerry Anning
> clem "at" dhol "dot" org


Post a reply to this message

<<< Previous 10 Messages Goto Initial 10 Messages

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