POV-Ray : Newsgroups : povray.advanced-users : Spline length/constant speed along spline. : Re: Spline length/constant speed along spline. Server Time
30 Jul 2024 08:23:54 EDT (-0400)
  Re: Spline length/constant speed along spline.  
From: Josh English
Date: 26 May 2000 19:46:56
Message: <392F0CEB.21BDCC76@spiritone.com>
Get ready for another long-winded pendantic post ; )

My bezier.inc file can be found here:
 http://www.spiritone.com/~english/cyclopedia/include/bezier.inc

but it is not well documented yet.

Here's a brief rundown.  I don't have a link handy (I'm sure Ken does) for the graphic
portion of the
process, but it's easy to describe.

Declare four points in space, and label them A,B,C, and D. A is the starting point of
the spline, and D is
the end point. B and C are your control points.
Graphically:
find the midpoint between A and B and call it E,
find the midpoint between B and C and call it F,
find the midpoint between C and D and call it G.
find the midpoint between E and F and call it H,
find the midpoint betweenF and G, call it I.
The last point is J, which is directly inbetween H and I.

Out of all these points, only A,J, and D are on the line, but if you have drawn this
all out you will see
that you can apply the process recursively, using A,E,H, and J as one set, and J,I,G
and D as the other. This
process repeats until the full curve is drawn.

Mathematically, the formua for a bezier curve is a parameatric equation. We'll use t,
and it will go from 0
to 1. At t=0 we are at A, and at t=1 we are at D.
Find where you are along the curve with
position = A*(1-t)^3 + 3*B*t*(1-t)^2 + 3*C*t^2*(1-t) + D*t^3

After a whole lot of algebra we find an easier equation.
Find three constants based on A,B,C, and D:
E = -A + 3B -3C +D
F = 3A - 6B + 3C
G = -3A + 3B
position = E*t^3 + F*t^2 + G*t + A

This is a faster calculation and easier to differentiate:

Velocity = 3*E*t^2 + 2*F*t + G

Now, this means you have to specify the control points of each segment of the spline.
You only know that the
curve will pass through the starting point A and the end point D.

The problem your documents solves is to find a curve that passes through a series of
points.
Given an array of position vectors, find a smooth curve between them.

Lets work with a series of points A,B,C,D, and E. We want our curve to touch them in
that order.

It is easier to start with the second point B. B is the endpoint of the first bezier
spline and the start
point of the second bezier spline. The two conrol points associated with this point
need to lie on the same
vector (so their second derivatives are the same, or at least scalar multipliers of
eachother) and to make
things easer, assume that this vector is parallel to the vector AC. Then it is a
simple matter of finding the
lengths of these vectors to the control points.

This is a slightly different way of talking about control points than before. The two
control points
associated with B are for two different splines, since B is part of two different
splines. When you look at
the calculations for point C, it's control points being parallel to BD, you will have
the four points
necessary to draw a bezier curve between B and C

Back to the lengths of these control vectors. They need to be on the same line to
avoid a sharp corner, but
if they are of equal length the entire curve will look strange and go needlessly too
far. If A and B are far
apart, but B and C are close together, having control vectors ofthe same lenght makes
an undesirable curve.
So, to counter act this, I find the length of the vector between A and B, multiply it
by a constant value
(usally around 0.1) and use that to alter the length of vector CA, which I add to B,
to get the position of
the control vector. I then repeat the process using the length of B to C multiplied by
the same constant to
change the length of  vector AC(notice the reverse direction) and add it to B to get
the second control
points position.

It's a bit glib, and I keep kicking myself for not having a nice version of this
available yet.
Do the same thing for B,C, and D and you will have all of the necessary control points
except for two. The
control point next to point A, andthe control point for point E.

The easy solution is to declare the control point for A is A, and the control point
for E is E. I use this
and find it has the nicest results. You can label the control point for A to be B,
meaning the curve will
mover directly towards point B, move away from it and come at it "from the side".
The third method I've found is to find the vector from C to B and make the control
vector for point A
parallel to that. This looks nice as well, but it can make the curve move away from
the other points in the
sequence which might look strange animating it.

You can look at the poorly documented files I made that do most of this at:

 http://www.spiritone.com/~english/cyclopedia/include/SplineList.inc
 http://www.spiritone.com/~english/cyclopedia/include/list.pov
(list.pov is the main file. It includes SplineList.inc, which includes bezier.inc)

Please ask clarifying questions. I will answer them all.

Josh

Serge LAROCQUE wrote:

> > I couldn't follow everything you had, and the system of equations was a bit beyond
what I'm capable of.
>
> Ah I see. Well, basically, if you have a set of linear equations such as
>
> x + 2y + 3z = 4
> 2x + 3y - z = 3
> -x - 4y + 2z = 5
>
> where the number of equations must be equal to the number of unknows.
> You can form here a 3x3 matrix with just the coefficients of the unknows, in this
case:
>       | 1  2  3 |
> [A] = | 2  3  -1|
>       |-1  -4  2|
> View the equation in matrix form:
> [A]{x} = {c}
> where {x} is {x y z} and {c} is the constants on the RHS {4 3 5}
> you can solve this by calculating the inverse of [A] and multiplying both sides of
the equation (
> [A]^(-1) represents the inverse of [A])(Excel can calculate this for you, or you can
implement an
> algorithm from an algebra textbook)
> [A]^(-1)*[A]*{x}=[A]^(-1)*{c}
>
> obviously, this reduces to {x}=[A]^(-1)*{c}
> this approach is what I have used in that Excel spreadsheet.
>
> There is another method, Cramer's rule. This one involves calculating determinants
> So we have matrix [A]. calculate its determinant: |A|
> then, replace the first column by the constants column, and calculate the
determinant of this matrix,
> call it |Ax|, do the same thing with the second and third columns, call them |Ay|
and |Az|.
>
> then solve: x = |Ax|/|A|
>             y = |Ay|/|A|
>             z = |Az|/|A|  (I haven't done this in years so I'm not 100% sure it's
|Ax|/|A| or the other
> way around ;) )
>
> Of course, this is easy to do when the matrix [A] isn't too big (say 2x2 or 3x3), so
it's usually easier
> to just go with the inverse matrix approach.
>
> BTW, I am interested in these Bezier splines... do you have some URLs where I could
go and take a peak? I
> was wondering how the relationship between control points and curve points worked, I
am working on
> something which might use these. I figured it would be easy to form a curve when the
control points are
> known, but not the other way? I'd like to find more about this.
>
> Whew long post :)

--
Josh English
eng### [at] spiritonecom
"May your hopes, dreams, and plans not be destroyed by a few zeros."


Post a reply to this message

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