/* This file is part of the source code for 3D-XplorMath-J, Version 1.0 (January 2008).
* Copyright (c) 2008 The 3D-XplorMath Consortium (http://3d-xplormath.org).
* This source code is released under a BSD License, which allows redistribution
* in source and binary form, with or without modification, provided copyright
* and license information are included, and with no warranty or guarantee of
* any kind. For details, see http://3d-xplormath.org/j/source/BSDLicense.txt
*/
package vmm3d.core;
import vmm3d.core3D.Vector3D;
/**
* Represents an element of the set of quaternions.
*/
public class Quaternion {
public final static Quaternion ZERO = new Quaternion();
public final static Quaternion q1 = new Quaternion(1,0,0,0);
public final static Quaternion qI = new Quaternion(0,1,0,0);
public final static Quaternion qJ = new Quaternion(0,0,1,0);
public final static Quaternion qK = new Quaternion(0,0,0,1);
public double a,b,c,d;
/**
* Create a quaternion with all coordinates intially equal to zero.
*/
public Quaternion() {
}
/**
* Create a quaternion from initial values for each coordinate.
*/
public Quaternion(double a, double b, double c, double d) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
/**
* Create a copy of an exiting non-null Quaternion object
* @param source the object to be copied. A NullPointerException is thrown if
* this is null.
*/
public Quaternion(Quaternion source) {
a = source.a;
b = source.b;
c = source.c;
d = source.d;
}
public boolean equals(Object obj) {
try {
Quaternion q = (Quaternion)obj;
return a == q.a && b == q.b && c == q.c && d == q.d;
}
catch (Exception e) {
return false; // handles the case where obj == null or is not an instance of Quaternion
}
}
public String toString() {
return "(" + a + "," + b + "," + c + "," + d + ")";
}
/**
* p.dot(q) returns the scalar product
*/
public double dot(Quaternion q) {
return (a*q.a + b*q.b + c*q.c +d*q.d);
}
/**
* Returns the norm of this quaternion.
*/
public double norm() {
return Math.sqrt(a*a + b*b + c*c + d*d);
}
/**
* p.conj() returns the conjugate to p
*/
public Quaternion conj() {
return new Quaternion(a,-b,-c,-d);
}
/**
* Compute the sum of this quaternaion and another quaternion
* @param q the non-null quaternion to be added to this one. If this is null, a NullPointerException is thrown.
*/
public Quaternion plus(Quaternion q) {
return new Quaternion(a + q.a, b + q.b, c + q.c, d + q.d);
}
/**
* Compute the difference of this quaternaion and another quaternion
* @param q the non-null quaternion to be subtracted from this one. If this is null, a NullPointerException is thrown.
*/
public Quaternion minus(Quaternion q) {
return new Quaternion(a - q.a, b - q.b, c - q.c, d - q.d);
}
/**
* Compute the product of this quaternaion and another quaternion
* @param q the non-null quaternion to be ultiplied by this one. If this is null, a NullPointerException is thrown.
*/
public Quaternion times(Quaternion q) {
return new Quaternion(
a*q.a - b*q.b - c*q.c - d*q.d,
a*q.b + b*q.a + c*q.d - d*q.c,
a*q.c - b*q.d + c*q.a + d*q.b,
a*q.d + b*q.c - c*q.b + d*q.a
);
}
/**
* Compute the product of this quaternaion and a real number
*/
public Quaternion times(double x) {
return new Quaternion(a*x, b*x, c*x, d*x);
}
/**
* Compute the multiplicative inverser of this quaternion. Note that the inverse of
* zero will not generate an error; instead, the inverse of zero is a quaternion object
* in which every coordinate is Double.NaN.
*/
public Quaternion inverse() {
double denom = a*a + b*b + c*c + d*d;
return new Quaternion(a/denom, -b/denom, -c/denom, -d/denom);
}
/**
* Compute the quotient of this quaternaion by another quaternion. Note that division by zero
* does not generate an error. Instead, the the result is a vector in which each coordinate
* is Double.NaN.
* @param q the non-null quaternion that this quaternion is to be multiplied by. If this is null, a NullPointerException is thrown.
*/
public Quaternion dividedBy(Quaternion q) {
return this.times(q.inverse());
}
/**
* Returns rotation by phi around standard Hopf fiber through (1,0,0,0)
*/
public Quaternion rotateAroundHopfFibre(double phi){
return new Quaternion(a,b,c*Math.cos(phi)-d*Math.sin(phi), c*Math.sin(phi)+d*Math.cos(phi));
}
/**
* Returns rotation by phi around standard Hopf fiber through q0
*/
public Quaternion rotateAroundHopfFibre(double phi, Quaternion q0){
Quaternion p = new Quaternion(this.times(q0.inverse()));
p = p.rotateAroundHopfFibre(phi);
return p.times(q0);
}
/**
* Returns stereographic projection from (-1,0,0,0)
*/
public Vector3D StereographicProjection() {
return new Vector3D(b/(1+a),c/(1+a),d/(1+a));
}
}
Ads help maintain this website.