POV-Ray : Newsgroups : povray.advanced-users : Boneheaded 3D trig question : Re: Boneheaded 3D trig question Server Time
29 Jul 2024 22:31:35 EDT (-0400)
  Re: Boneheaded 3D trig question  
From: Geoff Wedig
Date: 13 Sep 2000 08:30:58
Message: <39bf7382@news.povray.org>
Rick Gutleber <ric### [at] hiscom> 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.

> Thanks for the help!

I've found the following two macros to be of great help:

#macro vector_rotation(vect)
  #local AngleX = degrees(atan2(vect.z, vlength(<vect.x,vect.y,0>)));
  #if (vect.y>0.0001)
    #local AngleZ = degrees(atan2(-vect.x,vect.y));
  #end
  #if (vect.y<-.0001)
    #local AngleZ = degrees(atan2(-vect.x,vect.y));
  #end
  #if (vect.y<= 0.0001 & vect.y >=-.0001)
    #if (vect.x>0)
      #local AngleZ=-90;
    #else
      #local AngleZ=90;
    #end
  #end
  
  (<AngleX, 0, AngleZ>)

#end                   

#macro reverse_rotate(point, rot)

  vrotate(vrotate(vrotate(point,-rot * z), -rot * y), -rot * x)

#end

The first, given a vector, returns a rotation that will turn a <0,n,0>
vector into it.  Note that it is only one solution.  There are an infinite
number of solutions.  A rotate y previous to the rotate x can be used to
turn the vector about its axis if necessary (I've been meaning to change
this so it uses a <1,0,0> vector and returns a <0, x, y> rotation, so I can
rotate about the x freely, but I've just never found the time.

The second, given a point and a rotation does the *opposite* rotation on it. 
This is useful for when you've got a point you must have the object touch,
but you've constructed the object with a different rotation.  This returns
the point in the initial reference frame that the object must touch. (Note,
you can either use this once, print the result and modify the object
accordingly, or you can just let POV do the work.  The former is faster, but
more work for you)

Geoff


Post a reply to this message

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