|
|
Rick Gutleber wrote:
> I've got a simple question that's bugged me for years. The answer's got to
> be simple, but I just can't figure it out.
>
> I'm writing a C++ program to programmatically generate a Christmas tree and
> I'm trying to put needles on the branches. I have the start and end point
> of the branch so I figured I would create the needles as if the branch
> started at the origin and pointed straight up and then just translate and
> rotate the union of the resulting needles so they actually appear on the
> branch in the scene. This translatation/rotation can occur in my C++ code
> or the generated POV script, whichever is easier.
>
> I've got an arbitary unit vector that reflects the orientation of the branch
> (from VNormalize( ) in POV, or the good old Pythagorean distance function in
> my C++ code), how do I turn that into an equivalent rotate < x, y, z >
> statement so the needles end up on the branch? I'm sure it's just the right
> combination of atan( ) calls, but the details elude my addled brain.
If I have understood your problem correctly, then
you only need rotations around two axes to do this.
See POV-code below for some of my suggestions.
Tor Olav
--
mailto:tor### [at] hotmailcom
http://www.crosswinds.net/~tok/tokrays.html
P.S:
In POV-script YOU don't need to Pythagoras' formula
to calculate the distance between two points.
You can find it this way:
#declare Distance = vlength(PointB - PointA);
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#declare AnyThing = cylinder { 0*y, 6*y, 1 }
#declare vOrientation = <1, -2, -1>;
#declare vPosition = <2, 1, -1>;
// You can find the angles like this:
#declare AngleX = acos(vOrientation.x/vlength(vOrientation*<1, 0, 1>));
#declare AngleY = acos(vOrientation.y/vlength(vOrientation));
/*
// Or like this:
#declare AngleX = acos(vnormalize((x + z)*vOrientation).x);
#declare AngleY = acos(vnormalize(vOrientation).y);
*/
// If the vector vOrientation points "downwards" then make the
// rotation go the other way around the Y-axis
#if (vOrientation.z < 0)
#declare AngleX = -AngleX;
#end // if
// Now "tilt" the object
#declare TiltedThing =
object {
AnyThing
rotate degrees(AngleX)*y
rotate -degrees(AngleY)*z
rotate -degrees(AngleX)*y
}
// Then put it in place and give it a pigment
object {
TiltedThing
translate vPosition
pigment { color <1, 0, 0> }
}
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
/*
// Or you can make a macro for it like I did:
#macro Tilt(Thing, Vector)
#local xAngle = (Vector.z < 0 ? -1 : 1)*
degrees(acos(vnormalize((x + z)*Vector).x));
#local yAngle = degrees(acos(vnormalize(Vector).y));
object {
Thing
rotate xAngle*y
rotate -yAngle*z
rotate -xAngle*y
}
#end // macro Tilt
object {
Tilt(AnyThing, vOrientation)
pigment { color <0, 1, 0> }
translate vPosition
}
*/
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Or you can calculate a matrix for the complete transformation
// and then apply that matrix to the object once.
// John VanSickle's Reorient macro does that (and more) for
// the rotational part of such a transformation.
// See: http://users.erols.com/vansickl/macs.htm
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
Post a reply to this message
|
|