|
|
On 2010-12-11 15:45, John VanSickle wrote:
> About a decade ago I looked into something like this. Measuring the
> length of a section of spline involves the integral of the length of the
> differential of the... Uh, it's complicated. Even for a quadratic spline
> the integral is hairy enough, and I suppose for a cubic spline it's
> downright ugly. The iterative solution is much neater and simpler to
> understand.
>
> Regards,
> John
I've been using splines to control the path of a piece of chain, which
requires that the specified length segments follow the arc. I recognized
that you can do this 3 ways:
1) Define the start point, path, end point, and let it add as many
segments as is needed to follow.
2) Define the start point, path, and number of segments, and guess where
it ends up.
3) Define the start point, end point, and number of segments, and use
some sort of approximation to make the path.
Of these, #3 is computationally expensive and doesn't really give what
you're looking for anyway, and #1 and #2 requires the computations that
this thread is about, which are hard. So I came up with:
4) Define start point, derivative of the path, and number of segments.
This approach is computationally trivial and with some tweaking will
give you almost exactly what you're looking for. I made the macro
calculate the distance between each segment of the chain (variable
length per unit for the heck of it), then it takes the derivative path
function as a parameter. Each step it finds the direction to move by
normalizing the spline entry at that index, increments the "current
position" variable, rotates the segment to fit the direction and then
translates to the new position. Yes, it's a numerical integrator, but if
you're placing things along the path you're doing most of that
computation already, so it's almost no more work. It has an added bonus
of working with any spline type you want.
So for example, you give a spline of:
#declare pathfunction = spline{
linear spline
0, <1,0,0>
20, <0,1,0>
}
you'll get a chain that starts going in +x and bends to be going +y by
the end of the 20 unit chain, i.e. a quarter circle (a real circle needs
natural_spline, but you get the idea). You have to fiddle with it to get
the right look and figure out where it ends, but that's not too hard.
The follower code:
#local dx = /*distance between centers of chain links*/
#local i = 0;
#local currentposition=<0,0,0>;
union{
#while (i < Length)
#local currentdirection=vnormalize(PathFunction(i+0.5));
#local currentposition=currentposition+dx*currentdirection;
object{ /* chain segment */
Reorient_Trans(x,currentdirection)
translate currentposition}
#local i = i + 1;
#end
}
Example render:
http://fc07.deviantart.net/fs22/i/2009/249/4/c/Full_Persian_Fun__CGI__by_cshake.png
Post a reply to this message
|
|