|
|
/*
Hi Stephen!
Here is a macro for springs made of torus-segments: fast, smooth, easy to
use. Copy this whole post to POV-Ray and play with the parameters. I've
included Warp's cylinder-spring for comparison, set UseSpiralMacro to
false to see it.
Spiral with 50 SpringSegments is approximately as fast as 1200 of Warp's
cylinders, but *much* smoother: compare them at a camera angle of 3.5!
If you want to see the borders between the tori, change the 0 in one of the
plane objects to -0.02.
Ideally the spiral should touch a cylinder from inside that has a radius of
SpringMajorRadius+SpringMinorRadius. With the torus method there is a very
small (unavoidable) bulge. This can be seen by setting ShowBulgeError to
true. The value of this error is written to the debug stream.
Sputnik
*/
// Spiral
// +SP8 +EP8 -FN +A0.1 +AM2 +R3
camera { location -z*20 look_at 0 angle 35 }
light_source { -z*10, 1 }
#declare SpringHeight = 8;
#declare SpringMajorRadius = 1;
#declare SpringMinorRadius = .1;
#declare SpringRevolutions = 10;
#declare SpringSegments = 50; // 5*SpringRevolutions is
// enough for #macro Spiral
#declare UseSpiralMacro = true; //
#declare ShowBulgeError = false; // true: shows the Spiral's bulge
// SPIRAL ///////////////////////////////////////////////////////////////////
#macro Spiral ( Radius1, Radius0, Rise, Turns, Segments )
// Radius1 : major radius
// Radius1 : minor radius
// Rise : height of a single turn
// Turns : number of turns (may be non-integer)
// Segments: number of tori in spiral
// (>= 2*Turns; usually 5*Turns ... 10*Turns is enough)
// some calculations ...
#local Ang= Turns*360/Segments;
#local Ri = Rise/2 * Turns/Segments;
#local Sin= sin(radians(Ang/2));
#local A = Radius1*Sin;
#local B = sqrt(Radius1*Radius1-A*A);
#local C = A*A/B;
#local DD = Ri*Ri+A*A;
#local E = DD/C;
#local W = degrees(atan2(C,sqrt(DD)));
#local R = sqrt(E*(E+C));
// single torus-segment
#declare T =
intersection {
torus { R, Radius0 }
plane { -x, 0 rotate W*y }
plane { x, 0 rotate -W*y }
bounded_by { box {
1.001*<-(R+Radius0)*Sin, -Radius0, -(R+Radius0)>,
1.001*< (R+Radius0)*Sin, Radius0, -(R-Radius0)*(1-Sin*Sin)>
} }
rotate -degrees(atan2(Ri,A))*z
translate <0, Ri, E-B>
rotate Ang/2*y
}
// the torus-segments have a small bulge
#local Err = R-Radius1-E+B;
#debug concat (
"\nMaximum radius error in 'Spiral' = ", str(Err,0,5),
" = ", str(Err/Radius1*100,0,3), " %\n"
)
// stack the segments
union {
#local N = 0;
#while (N<Segments)
object { T rotate N*Ang*y translate N*2*Ri*y }
#local N = N+1;
#end//while
// no "}" to allow modifiers
#end//macro Spiral
/////////////////////////////////////////////////////////////////////////////
#if (UseSpiralMacro)
// spring consisting of torus-segments
#declare Spring =
Spiral (
SpringMajorRadius,
SpringMinorRadius,
SpringHeight/SpringRevolutions,
SpringRevolutions,
SpringSegments // 5*SpringRevolutions usually is enough
) /* { */ rotate -90*y /* same orientation as Warp's spring */ }
#if (ShowBulgeError)
difference {
object { Spring }
cylinder { 0, SpringHeight*y, SpringMajorRadius+SpringMinorRadius }
pigment { rgb 1 } finish { specular .5 }
translate -4*y
}
#else
object { Spring
translate -4*y
pigment { rgb 1 } finish { specular .5 }
}
#end//if ShowBulgeError
#else
// spring consisting of cylinders as suggested by Warp
union
{
#declare Ind = 0;
#while(Ind <= SpringSegments)
#declare Pos2 =
vrotate(<SpringMajorRadius, SpringHeight*Ind/SpringSegments, 0>,
y*360*SpringRevolutions*Ind/SpringSegments);
#if(Ind > 0)
cylinder { Pos1, Pos2, SpringMinorRadius }
sphere { Pos2, SpringMinorRadius }
#end
#declare Pos1 = Pos2;
#declare Ind = Ind+1;
#end
pigment { rgb 1 } finish { specular .5 }
translate -y*4
}
#end//if UseSpiralMacro
box { <-2,-4,-2><2,-4.1,2> pigment { rgb <.8,.4,.2> } }
// END //////////////////////////////////////////////////////////////////////
Post a reply to this message
|
|
|
|
On Wed, 24 Sep 2003 08:57:36 -0500, "Steve Shelby" <ssh### [at] rexnetnet> wrote:
>I'm a little late coming to this thread, but I thought you might like to
>check out a free program called "helixer", http://www.evolve.co.uk/helixir/
>. You can easily make any kind of helix, and import it into Moray or Povray.
Thanks Steve,
I have a copy of "helixer" and it has served me well in Moray. I want to
use a couple of springs in an animation so with "helixer" I would need to work
out the intermediary positions as well as the start and end ones. Sputnik's
macro will do the job very well placed in the InsertCode plugin.
Regards
Stephen
Post a reply to this message
|
|