|
|
Someone in comp.graphics.rendering.raytracing recently asked how to
place a possibly scaled sphere so that it is tangent to two given
points. I answered in email with the following include file that I
threw together based on math from the Matrix Page of John vanSickle.
Variations on this question seem to be pretty frequent and I myself use
various modifications of this math constantly, so I am publishing the
include file here. (I did not publish it in cgrr because I get a spam
blizzard every time I post there.) Cut it out, name it "tanball.inc"
and save it in your include directory. Usage instructions are in the
include file.
// Begin POV code
/* tanball.inc - connects two points with a (possibly ellipsoidal)
"ball" tangent to each point. The vector math is taken from a code
snippet on the Matrix Page of John vanSickle
(http://www.erols.com/vansickl/matrix.htm), which should be required
reading for any POV user. Use this by declaring:
Tanball_Start_Point
Tanball_EndPoint
The points to be connected. Default to <0, 0, 0> and <1, 1, 1>. If the
points are equal, tanball will create a very slight difference to avoid
math trouble.
Tanball_Y_Size
Tanball_Z_Size
The tanball is created as a unit sphere then stretched as needed in the
X direction and rotated. Tanball_Y_Size and Tanball_Z_Size are the size
you want the directions transverse to the tanball axis to be. If you
use 1 for both, the cross section at the widest point will be a unit
circle. If you use the special value 0 (zero) for either or both of
these parameters, the relevant parameter will be set to be identical to
the tanball axis, so if you use 0 for both, the tanball will be a
sphere. Default to 1 and 1. Note: If you get a warning about scaling by
0 in a matrix from tanball.inc, ignore it.
Tanball_Texture
The texture you want the tanball to have. Default to
texture { pigment { color rgbt <1, 1, 0, .8> } }.
After you set up these parameters, say:
include "tanball.inc"
at any place where you want a tanball. You can use it several times in
the same file and simply redeclare any variables that change before each
use. */
// Set defaults and trap trouble.
#ifndef (Tanball_Start_Point)
#declare Tanball_Start_Point = <0, 0, 0>
#end
#ifndef (Tanball_End_Point)
#declare Tanball_End_Point = <1, 1, 1>
#end
#ifndef (Tanball_Y_Size)
#declare Tanball_Y_Size = 1
#end
#ifndef (Tanball_Z_Size)
#declare Tanball_Z_Size = 1
#end
#ifndef (Tanball_Texture)
#declare Tanball_Texture = texture { pigment { color rgbt <1, 1, 0, .8>
} }
#end
#declare Tanball_Dir_Vec = Tanball_End_Point - Tanball_Start_Point
#declare Tanball_X_Size = vlength(Tanball_Dir_Vec)
#if (Tanball_X_Size = 0)
#declare Tanball_End_Point = Tanball_End_Point + .00001
#declare Tanball_Dir_Vec = Tanball_End_Point - Tanball_Start_Point
#declare Tanball_X_Size = vlength(Tanball_Dir_Vec)
#end
#if (Tanball_Y_Size = 0)
#declare Tanball_Y_Size = Tanball_X_Size / 2
#end
#if (Tanball_Z_Size = 0)
#declare Tanball_Z_Size = Tanball_X_Size / 2
#end
// Get under way
#declare VX1=vnormalize(<Tanball_X_Size, 0, 0>)
#declare VX2=vnormalize(Tanball_Dir_Vec)
#declare VY=vcross(VX2,VX1)
#declare VZ1=vcross(VY,VX1)
#declare VZ2=vcross(VY,VX2)
sphere { 0, .5
scale <Tanball_X_Size, 2 * Tanball_Y_Size, 2 * Tanball_Z_Size>
translate <.5 * Tanball_X_Size, 0, 0>
matrix < VX1.x, VY.x, VZ1.x,
VX1.y, VY.y, VZ1.y,
VX1.z, VY.z, VZ1.z,
0 0 0 >
matrix < VX2.x, VX2.y, VX2.z,
VY.x, VY.y, VY.z,
VZ2.x, VZ2.y, VZ2.z,
0, 0, 0 >
translate Tanball_Start_Point
texture { Tanball_Texture }
}
// End POV code
Jerry Anning
cle### [at] dholcom
Post a reply to this message
|
|