|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.proteinshader.math.Quaternion
public class Quaternion
This class is used to create a quaternion, a four-dimensional
complex number that is typically used to represent a rotation in
three-dimensional space.
The reason for using Quaternions to represent rotations is that there
is a very useful algorithm for interpolating between a start and an
end quaternion. This algorithm is called SLERP (Spherical Linear
intERPolation), and the primary reference is a paper by Ken Shoemake,
"Animating Rotation with Quaternion Curves" SIGGRAPH 85, Proc.
Computer Graphics Vol 19 No. 3, (1985), pp. 245-254.
SLERP ALGORITHM:
The equation for interpolating between quaternions q1 and q2 to obtain
q3 is given as
q3 = slerp(q1, q2; t), 0 <= t <= 1
q3 = q1 * (sin((1-t)*theta)) / sin(theta))
+ q2 * (sin(t*theta) / sin(theta))
where cos(theta) = q1.dot(q2), so
theta = acos(q1.dot(q2))
theta = acos(q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w)
For SLERP to give the shortest path, the angle theta should be between
0 and 90 degrees (positive cosine theta). If theta is between 90 and
180 degrees (negative cosine theta), then quaternion q2 should be
converted to the quaternion q = (-q2.x, -q2.y, -q2.z, -q2.w). This
new quaternion represents the same rotation as q2, but the angle theta
is now between 0 and 90 degrees.
ROTATION MATRIX TO QUATERNION CONVERSION:
For converting a rotation matrix to a quaternion (and for other basic
quaternion operations), three references were consulted:
1. "Rotating Objects using Quaternions" by Nick Bobick on the
Gamasutra web site. Registration (which is free) and a password are
needed for this link:
http://www.gamasutra.com/features/19980703/quaternions_01.htm
(cited December 2006).
This tutorial gives a good introduction to why quaternions are
useful for computer graphics and animation. Example C code is given
for converting a rotation matrix to a quaternion, converting a
quaternion back to a rotation matrix, and for doing SLERP. When
interpreting the example code, it is important to realize that
the matrices appear to all be given in terms of column major notation
rather than the usual row major notation used in C/C++/Java code.
If this issue is not accounted for, the quaternion produced from
the rotation matrix to quaternion code would end up rotating in the
opposite direction as expected.
2. The derivation of the equations used for a rotation matrix to
quaternion conversion (along with additional example code) can be
found at the "EuclideanSpace - building a 3D world" web site by
Martin Baker. The site also has numerous pages dealing with other
aspects of quaternion math, and 3D math in general.
http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
(cited December 2006).
3. The "Sacred Software" web site by Alex Diener was also very useful
for a general introduction to quaternions, and includes very readable
example code for several common quaternion operations, including SLERP.
http://www.sacredsoftware.net/tutorials/Quaternions/Quaternions.xhtml
(cited December 2006).
MATRIX NOTATION:
For matrix->quaternion and quaternion->matrix conversions in this
class, three column vectors are used to represent the matrix M:
M = [N B T]
N = normal = [N.x, N.y, N.z]
B = binormal = [B.x, B.y, B.z]
T = tangent = [T.x, T.y, T.z]
If a matrix was given in row major format with a shorthand notation
of m00 for m[0][0], the positions of a matrix could be represented as
-------------
|m00 m01 m02|
|m10 m11 m12|
|m20 m21 m22|
-------------
which is equivalent to
-------------
|N.x B.x T.x|
|N.y B.y T.y|
|N.z B.z T.z|
-------------
in the notation used in class Quaternion, so
N = [m00, m10, m20] = [N.x, N.y, N.z]
B = [m01, m11, m21] = [B.x, B.y, B.z]
T = [m02, m12, m22] = [T.x, T.y, T.z]
Field Summary | |
---|---|
static String |
DECIMAL_FORMAT
As a convenience for debugging, the toString() method will return a representation of a quaternion in the general form "(x, y, z, w)", where the number of decimal places for each value will be determined this decimal format String, which is "0.000". |
static double |
MIN_THETA
If theta is too close to zero for a SLERP calculation, then a clone of the start Quaternion will be returned. |
static double |
ONE_DEGREE
1 degree given in radians is PI / 180. |
double |
w
The public w-component. |
double |
x
The public x-component. |
double |
y
The public y-component. |
double |
z
The public z-component. |
Constructor Summary | |
---|---|
Quaternion()
Constructs the multiplication identity quaternion (x, y, z, w) = (0, 0, 0, 1). |
|
Quaternion(double x,
double y,
double z,
double w)
Constructs a quaternion. |
|
Quaternion(Vec3d axis,
double angle)
Creates a quaternion that is equivalent to the rotation specified by the axis and angle (in radians) given as aguments. |
|
Quaternion(Vec3d N,
Vec3d B,
Vec3d T)
Creates a quaternion that is equivalent to the rotation contained in the 3 x 3 matrix [N B T]. |
Method Summary | |
---|---|
void |
adjustMyTangent(Vec3d tangent)
Modifies this quaternion by rotating it such that if it is converted into a rotation matrix [N B T], the T vector will match the tangent given as an argument. |
Quaternion |
adjustTangent(Vec3d tangent)
Returns a copy of this quaternion that has been rotated such that if it is converted into a rotation matrix [N B T], the T vector will match the tangent given as an argument. |
double |
angleBetweenNormals(Quaternion quat)
Returns the angle between the normals of the calling and argument quaternions, where the normal is the first column vector of the rotation matrix [N B T] that is the equivalent of a quaternion. |
Quaternion |
clone()
Creates a clone of this quaternion and returns it. |
Quaternion |
conjugate()
Creates a clone of the calling Quaternion and then converts it to the conjugate, q'. |
void |
conjugateMe()
Converts the calling Quaternion to its conjugate. |
double |
generateAxisAndAngle(Vec3d axis)
Converts the Quaternion to an axis of rotation and an angle. |
double[] |
generateMatrix()
Generates a 4 x 4 rotation matrix that is equivalent to this quaternion, but returns it as a linear array of 16 elements so that it can be used with Java Bindings for OpenGL. |
void |
generateMatrix(Vec3d N,
Vec3d B,
Vec3d T)
Generates a 3 x 3 rotation matrix (actually 3 column vectors) that is equivalent to this quaternion, assuming that the quaternion has already been normalized (such that x^2 + y^2 + z^2 + w^2 = 1). |
Vec3d |
getBinormal()
Converts the Quaternion into a 3 x 3 rotation matrix and the returns the second column vector (the Binormal). |
Vec3d |
getNormal()
Converts the Quaternion into a 3 x 3 rotation matrix and the returns the first column vector (the Normal). |
Vec3d |
getTangent()
Converts the Quaternion into a 3 x 3 rotation matrix and the returns the third column vector (the Tangent). |
Quaternion |
invert()
Creates a clone of the calling Quaternion and inverts it. |
void |
invertMe()
Inverts the calling Quaternion. |
double |
magnitude()
Returns the magnitude (length) of this quaternion. |
Point3d |
multiply(Point3d p)
Multiplies a point by this quaternion and returns the resulting point. |
Quaternion |
multiply(Quaternion quat)
Creates a clone of the calling Quaternion and multiplies it by the Quaternion given as an argument. |
Vec3d |
multiply(Vec3d v)
Multiplies a vector by this quaternion and returns the resulting vector. |
void |
multiplyMe(Quaternion quat)
Multiplies the calling Quaternion by the argument Quaternion and stores the result in the calling Quaternion. |
Quaternion |
normalize()
Creates and returns a new quaternion that is equivalent to the calling quaternion, but is guaranteed to be of unit length. |
void |
normalizeMe()
Normalizes the calling quaternion object by dividing each component of the quaternion by the magnitude of the quaternion. |
void |
setXYZW(double x,
double y,
double z,
double w)
Sets the xyzw-values of the quaternion. |
void |
setXYZW(Quaternion quat)
Sets the xyzw-values of the quaternion to the xyzw-values of the quaternion given as an argument. |
void |
setXYZW(Vec3d axis,
double angle)
Calculates and sets (x, y, z, w) of this quaternion based on the axis and angle (in radians) given as aguments. |
void |
setXYZW(Vec3d N,
Vec3d B,
Vec3d T)
Calculates and sets (x, y, z, w) of this quaternion based on the rotation contained in the 3 x 3 matrix [N B T]. |
Quaternion |
slerp(Quaternion end,
double t)
Uses SLERP (Spherical Linear intERPolation) to calculate a Quaternion (a rotation) at any point t between the calling Quaternion and the argument Quaternion. |
String |
toString()
As a convenience for debugging, the toString() method returns the xyzw-components of the quaternion in the form "(x, y, z, w)". |
Methods inherited from class java.lang.Object |
---|
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
public static final double MIN_THETA
public static final double ONE_DEGREE
public static final String DECIMAL_FORMAT
public double x
public double y
public double z
public double w
Constructor Detail |
---|
public Quaternion()
public Quaternion(double x, double y, double z, double w)
x
- the x-component.y
- the y-component.z
- the z-component.w
- the w-component.public Quaternion(Vec3d N, Vec3d B, Vec3d T)
N
- a normal vector with components N.x, N.y, and N.z.B
- a binormal vector with components B.x, B.y, and B.z.T
- a tangent vector with components T.x, T.y, and T.z.public Quaternion(Vec3d axis, double angle)
axis
- the axis to rotate about.angle
- the rotation angle in radians.Method Detail |
---|
public Quaternion slerp(Quaternion end, double t)
end
- the end Quaternion.t
- a parameter that can vary from 0.0 to 1.0.
public void adjustMyTangent(Vec3d tangent)
tangent
- the target tangent.public Quaternion adjustTangent(Vec3d tangent)
tangent
- the target tangent.public double angleBetweenNormals(Quaternion quat)
quat
- the quaterion to compare.
public Quaternion conjugate()
public void conjugateMe()
public Quaternion clone()
clone
in class Object
public double[] generateMatrix()
public void generateMatrix(Vec3d N, Vec3d B, Vec3d T)
N
- a normal vector (N.x, N.y, N.z) to fill with values.B
- a binormal vector (B.x, B.y, B.z) to fill with values.T
- a tangent vector (T.x, T.y, T.z) to fill with values.public double generateAxisAndAngle(Vec3d axis)
axis
- a vector to store the (x, y, z) axis in.
public Vec3d getNormal()
public Vec3d getBinormal()
public Vec3d getTangent()
public Quaternion invert()
public void invertMe()
public double magnitude()
public Point3d multiply(Point3d p)
p
- The point to rotate.
public Vec3d multiply(Vec3d v)
v
- The vector to rotate.
public Quaternion multiply(Quaternion quat)
quat
- the Quaternion to multiply by.
public void multiplyMe(Quaternion quat)
quat
- the Quaternion to multiply by.public Quaternion normalize()
public void normalizeMe()
public void setXYZW(double x, double y, double z, double w)
x
- the x-componenty
- the y-componentz
- the z-componentw
- the w-componentpublic void setXYZW(Quaternion quat)
quat
- the quaternion to copy xyzw-values from.public void setXYZW(Vec3d N, Vec3d B, Vec3d T)
N
- a normal vector with components N.x, N.y, and N.z.B
- a binormal vector with components B.x, B.y, and B.z.T
- a tangent vector with components T.x, T.y, and T.z.public void setXYZW(Vec3d axis, double angle)
axis
- the axis to rotate about.angle
- the rotation angle in radians.public String toString()
toString
in class Object
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |