POV-Ray : Newsgroups : povray.advanced-users : Boneheaded 3D trig question : Re: Boneheaded 3D trig question Server Time
29 Jul 2024 22:33:25 EDT (-0400)
  Re: Boneheaded 3D trig question  
From: Tor Olav Kristensen
Date: 12 Sep 2000 16:35:17
Message: <39BE923A.4ED69247@online.no>
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

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.