|
![](/i/fill.gif) |
In article <3c7919a9@news.povray.org>,
"Rune" <run### [at] mobilixnet dk> wrote:
> I've done that before and it's not that slow. However, a solution I'd like
> to try is to return a new spline which has many more control points than the
> original and where those control points are arranged to give constant speed.
I've done that before, but never finished because of bugs in the spline
feature. Here are the (partially complete) macros:
// Persistence of Vision Ray Tracer version 3.5 Include File
// File: splines.inc
// Last updated: 2001.8.8
// Description: Spline-handling and interpolation macros
#ifndef(SPLINES_INC_TEMP)
#declare SPLINES_INC_TEMP = version;
#version 3.5;
#declare LINEAR_SPLINE = 0;
#declare QUADRATIC_SPLINE = 1;
#declare CUBIC_SPLINE = 2;
#macro SPLINE_TYPE(Type)
#switch(Type)
#case(LINEAR_SPLINE)
linear_spline
#break
#case(QUADRATIC_SPLINE)
quadratic_spline
#break
#case(CUBIC_SPLINE)
cubic_spline
#break
#end
#end
//Assumes spline T is in range [0, 1]
#macro Spline_Length(Spline, Intervals)
#local Len = 0;
#local PtA = 0+Spline(0);
#local J = 0;
#while(J < Intervals)
#local PtB = 0+Spline((J + 1)/Intervals);
#local Len = Len + vlength(PtB - PtA);
#local PtA = PtB;
#local J = J + 1;
#end
(Len)
#end
#macro Spline_Interval_Length(Spline, StartT, EndT, Intervals)
#local Len = 0;
#local PtA = (Spline(StartT));
#local J = 0;
#while(J < Intervals)
#local PtB = 0+Spline((EndT - StartT)*(J + 1)/Intervals +
StartT);
#local Len = Len + vlength(PtB - PtA);
#local PtA = PtB;
#local J = J + 1;
#end
(Len)
#end
#macro Constant_Speed_Spline(Spline, Type, Intervals, Samples)
#local SplineLen = Spline_Length(Spline, Intervals*Samples);
spline {SPLINE_TYPE(Type)
0, < 0, 0, 0>+Spline(0)
#local DistPassed = 0;
#local J = 0;
#while(J < Intervals)
#local IntLen = Spline_Interval_Length(Spline, J/Intervals,
(J + 1)/Intervals, Samples);
#local DistPassed = DistPassed + IntLen;
DistPassed/SplineLen, < 0, 0, 0>+Spline((J + 1)/Intervals)
#local J = J + 1;
#end
}
#end
#macro SPLINE_FindNextT(StIdx, Array)
#local PointNum = dimension_size(Array, 1);
#local K = StIdx;
#local Res = StIdx;
#while(K < PointNum)
#if(!VEq(Array[K][0], x))
#local Res = K;
#break
#else
#local K = K + 1;
#end
#end
(Res)
#end
#macro Spline_From_Array(Type, ConstantSpeedSamples, Array)
#local PointNum = dimension_size(Array, 1);
#if(ConstantSpeedSamples > 0)
#local Method = 3;
#else
#local Method = dimensions(Array);
#end
spline {SPLINE_TYPE(Type)
#switch(Method)
#case(1)
//No T values specified, autocompute all with even time
gaps
#debug "Spline_From_Array() method 1"
#local J = 0;
#while(J < PointNum - 1)
J/(PointNum - 1), Array[J],
#local J = J + 1;
#end
1, Array[PointNum - 1]
#break
#case(2)
//T values specified, autocompute only for gaps
#debug "Spline_From_Array() method 2"
#local J = 0;
#local NextTIdx = SPLINE_FindNextT(1, Array);
#while(J < PointNum - 1)
#if(VEq(Array[J][0], x))
#if(J > NextIdx)
#local NextTIdx = SPLINE_FindNextT(StIdx,
Array);
#end
#local LastT = Array[LastTIdx][0].y;
#local NextT = Array[NextTIdx][0].y;
#local Offset = (J - LastTIdx)/(NextTIdx -
LastTIdx);
#local TVal = (NextT - LastT)*Offset + LastT;
#else
#local LastTIdx = J;
#local TVal = Array[J][0].y;
#end
TVal, Array[J][1],
#local J = J + 1;
#end
1, Array[PointNum - 1][1]
#break
#case(3)
#debug "Spline_From_Array() method 3"
#warning "This method is not yet implemented"
//Ignore any T values specified, autocompute all for
constant speed
#local Reference = Spline_From_Array(Type, no, Array)
#local SplLen = Spline_Length(Reference,
PointNum*ConstantSpeedSamples);
#local DistPassed = 0;
#local J = 0;
#if(dimensions(Array) = 1)
0, Array[0],
#while(J < PointNum - 1)
#local IntLen =
Spline_Interval_Length(Reference, Array[J][0].y, Array[J + 1][0].y,
ConstantSpeedSamples);
#local DistPassed = DistPassed + IntLen;
DistPassed/SplLen, Array[J + 1],
#local J = J + 1;
#end
#else
0, Array[0][1],
#while(J < PointNum - 1)
#local IntLen =
Spline_Interval_Length(Reference, Array[J][0].y, Array[J + 1][0].y,
ConstantSpeedSamples);
#local DistPassed = DistPassed + IntLen;
DistPassed/SplLen, Array[J + 1][1],
#local J = J + 1;
#end
#end
#break
#end
}
#end
#version SPLINES_INC_TEMP;
#end//splines.inc
--
Christopher James Huff - chr### [at] mac com,
http://homepage.mac.com/chrishuff/
TAG: chr### [at] tag povray org, http://tag.povray.org/
<><
--
Christopher James Huff <chr### [at] mac com>
POV-Ray TAG e-mail: chr### [at] tag povray org
TAG web site: http://tag.povray.org/
Post a reply to this message
|
![](/i/fill.gif) |