The POV-Ray Cyclopedia

The four vector functions native to POV-Ray look simple, but they can be deceptive. This document explains the vaxis_rotate command which is not the most instinctive function.

Remember that vaxis_rotate, vcross,vnormalize, and vrotate return vectors in the 3d coordinate system.

Part One
Using an image in the page

Most people are adept at rotating object around the three axes of x,y, and z, but to rotate a point around a non-axis vector is sometimes called for, and vaxis_rotate fits the bill. Take a look at the following code for image 1:

#declare p1 = <1,2,0>;

cylinder { <0,0,0> p1 0.05 
           pigment { rgb <1,0,0> } 
           finish { phong 1 } }

#declare q = <2,1,0>;

sphere { q 0.09 
         pigment { rgb <0,1,0> }
         finish { phong 1 } }

#declare cnt = 0;
#while ( cnt < 360 )
  #declare tmp1 = vaxis_rotate(q,p1,cnt);
  sphere { tmp1 0.05 
           pigment { rgb <1,1,0< }
           finish { phong 1 } }
 
  #declare cnt = cnt + 360/90;
#end

Now here we have a red cylinder representing the vector from the origin to popint p1, the green sphere is at point q, and the yellow spheres are results of the vaxis_rotate applied to the green sphere around the red cylinder. Notice that the "circle" described by the yellow spheres is perpindicular to red cylinder. In fact, it doesn't matter how long that red cylinder is, or even if it points in the exact opposite direction. The positions you get from the vaxis_rotate command will be the same.

Circular clump
1. Vaxis_rotate and one vector.
Part Two
Rotating around a different

Now if you want to rotate a point around a vector that doesn't intersect the origin, you need to add a few things.

What we have are three points that we're dealing with. p1 and p2 are part of a known object in your scene and you want to rotate an object at point q around the vector defined by p1 and p2.

#declare p1 = <1,2,0>;
#declare p2 = <0.75,3,0.125>;

cylinder { <0,0,0> p1 0.05 
           pigment { rgb <1,0,0> } 
           finish { phong 1 } }

cylinder { p1 p2 0.05 
           pigment { rgb <1,0.5,0> } 
           finish { phong 1 } }
           
#declare q = <2,1,0>;

sphere { q 0.09 
         pigment { rgb <0,1,0> }
         finish { phong 1 } }

cylinder { 0, (p1-p2) 0.00625
           pigment { rgb <0.0,0.75,0.75> }
           finish { phong 1 }
           scale 4
           translate p1 }
           

The orange cylinder connects two known points and the cyan cylinder is merely an extention of the orange one to see the center of circle that we get.

#declare p3 = (p1 - p2);
#declare q2 = q - p1;

#declare cnt = 0;
#while ( cnt < 360 )
  #declare tmp1 = vaxis_rotate(q2,p3,cnt);
  sphere { tmp1 0.05 
           pigment { rgb <1,1,0> }
           finish { phong 1 } 
           translate p1 }
  #declare cnt = cnt + 360/90;
#end

  In order to do this we need to find a vector that is the same length and distance as the one we know, but one that originates from the origin. This is why we have p3 = (p1 - p2). The vector from the origin to p3 plays the same role as the red cylinder in image 1 above. But the green sphere at point q is to far away from this new vector, so q2 = q - p1 corrects for it. The orange cylnder and the green dot are in a set relationship in space. If I drew another orange cylinder from the origin to p3 and a green dot at q2, they would have the same kind of relationships in space.

 Then we make our vaxis_rotate points, and translate them by p1 to reverse the correction we made with q2.

 In image three, we see the new circle. An interesting point is that when we declare q2, we are subrtacting point p1 and we add p1 to the vaxis_rotated position later. We can substitute p2 and get the exact same results.

Circular clump
2. Setting up for a different rotation
Circular clump
3. Rotating around a vector

Send feedback, or head back to the Cyclopedia.

Thanks for watching.