Re: [Algorithms] Rotation about arbitrary axis
Brought to you by:
vexxed72
From: Thatcher U. <tu...@tu...> - 2000-08-21 19:20:23
|
From: Pierre Terdiman <p.t...@wa...> > > Since I needed a piece of code to do that I searched the web and found: > http://www.iuk.tu-harburg.de/hypgraph/modeling/mod_tran/3drota.htm > > I used the final matrix at the bottom of the page, but it seems to fail when > the arbitrary axis actually is the Z axis. The third column gets erased > where it should at least contain a 1. This is obvious when looking at the > provided matrix, since the third column of the third row depends on the > rotation angle - and of course if the input axis already is the Z axis, it > shouldn't. > > Now, it sounds normal regarding the underlying method (mapping the rotation > axis to Z, etc). But I wonder whether there's an easy way to perform a real > arbitrary rotation about any arbitrary axis without using different code > paths according to the input axis. > > I think it can probably be done by introducing quaternions or better, > angle-axis, in the story. But err.... maybe there's something simpler. Here's what I use. I'm sure it could be streamlined by expanded out the quaternion stuff and simplifying. class quaternion { public: quaternion(const quaternion& q) : S(q.S), V(q.V) {} quaternion(float s, const vec3& v) : S(s), V(v) {} // [...] quaternion operator*(const quaternion& q) const; // [...] void ApplyRotation(vec3* result, const vec3& v); private: float S; vec3 V; }; vec3 Rotate(float Angle, const vec3& Axis, const vec3& Point) // Rotates the given point through the given angle (in radians) about the given // axis. { quaternion q(cos(Angle/2), Axis * sin(Angle/2)); vec3 result; q.ApplyRotation(&result, Point); return result; } quaternion quaternion::operator*(const quaternion& q) const // Multiplication of two quaternions. Returns a new quaternion // result. { return quaternion(S * q.S - V * q.V, q.V * S + V * q.S + V.cross(q.V)); } void quaternion::ApplyRotation(vec3* result, const vec3& v) // Rotates the given vec3 v by the rotation represented by this quaternion. // Stores the result in the given result vec3. { quaternion q(*this * quaternion(0, v) * quaternion(S, -V)); // There's definitely a shortcut here. Deal with later. *result = q.V; } -- Thatcher Ulrich http://tulrich.com |