|
|
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
|
|