POV-Ray : Newsgroups : povray.advanced-users : Rotation around an arbitrary axis : Rotation around an arbitrary axis Server Time
25 Apr 2024 22:22:03 EDT (-0400)
  Rotation around an arbitrary axis  
From: Tor Olav Kristensen
Date: 29 Nov 2001 19:23:16
Message: <3C06D0B8.9DE747A0@hotmail.com>
Here's some code I've made in order to try to
show the mathematical relations between two
different methods for rotation of a vector
about an axis.

vAxisRotate1() and vAxisRotate3() does it by
matrix transformations, while vAxisRotate2()
does it by vector math.

Tor Olav

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Copyright 2001 by Tor Olav Kristensen
// Email: tor### [at] hotmailcom
// http://www.crosswinds.net/~tok
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.5;

// An expression for a general rotation matrix for left a handed
// coordinate system is:
//
// R = I + (1 - Cos)*S*S - Sin*S
//
// I = identity matrix
// S = skew(v) matrix
// v = axis to rotate about
// Cos = cos(Angle)
// Sin = Sin(Angle)
// Angle = angle of rotation about v

// Note:
// When a 3d-vector is multiplied by the skew matrix S, one gets
// the same result as if one evaluates a cross product with that
// vector and the vector that the skew matrix is formed from.

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// First some general macros

#macro PrintVector(v0)

 #debug concat("<", vstr(3, v0, ", ", 0, -1), ">")

#end // macro PrintVector


#macro vTrans(vA, TT)

  #local Fn = function { transform { TT } }

  Fn(vA.x, vA.y, vA.z)

#end // macro vTr


#macro Ident()

  matrix <
    1, 0, 0,
    0, 1, 0,
    0, 0, 1,
    0, 0, 0
  >

#end // macro Ident


#macro Skew(vA)

  matrix <
       0, -vA.z,  vA.y,
    vA.z,     0, -vA.x,
   -vA.y,  vA.x,     0,
       0,     0,     0
  >

#end // macro Skew

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Some vAxisRotate macros
// (Non-optimal code for comparison purposes.) 

#macro vAxisRotate1(v0, vAxis, Angle)

  #local Phi = radians(Angle);
  #local Cos = cos(Phi);
  #local Sin = sin(Phi);
  #local vL = vnormalize(vAxis);
  #local I = transform { Ident() }
  #local S = transform { Skew(vL) }
  #local SS = transform { Skew(vL) Skew(vL) }

  (vTrans(v0, I) + (1 - Cos)*vTrans(v0, SS) - Sin*vTrans(v0, S))

#end // macro vAxisRotate


#macro vAxisRotate2(v0, vAxis, Angle)

  #local Phi = radians(Angle);
  #local Cos = cos(Phi);
  #local Sin = sin(Phi);
  #local vL = vnormalize(vAxis);
  
  (v0 + (1 - Cos)*vcross(vcross(v0, vL), vL) - Sin*vcross(v0, vL))

#end // macro vAxisRotate


#macro AxisRotate(vAxis, Angle)

  #local Phi = radians(Angle);
  #local Cos = cos(Phi);
  #local Sin = sin(Phi);
  #local omc = 1 - Cos;
  #local vL = vnormalize(vAxis);
  #local X = vL.x;
  #local Y = vL.y;
  #local Z = vL.z;

  transform {
    matrix < 
      X*X*omc + Cos,   Y*X*omc + Z*Sin, Z*X*omc - Y*Sin,
      X*Y*omc - Z*Sin, Y*Y*omc + Cos,   Z*Y*omc + X*Sin,
      X*Z*omc + Y*Sin, Y*Z*omc - X*Sin, Z*Z*omc + Cos,
      0,               0,               0
    >
  }
  
#end // macro AxisRotate


#macro vAxisRotate3(v0, vAxis, Angle)

  vTrans(v0, AxisRotate(vAxis, Angle))

#end // macro vAxisRotate3

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Compare the results from the macros

#declare vA = <2, 5, -4>;
#declare vB = <-1, 2, 3>;
#declare AnAngle = 20;

#debug "\n"
PrintVector(vaxis_rotate(vA, vB, AnAngle))
#debug "\n"
PrintVector(vAxisRotate1(vA, vB, AnAngle))
#debug "\n"
PrintVector(vAxisRotate2(vA, vB, AnAngle))
#debug "\n"
PrintVector(vAxisRotate3(vA, vB, AnAngle))
#debug "\n"

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

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