package java3d;
public class Quat4d implements Cloneable {
private static final double EPS = 1.0e-12;
public double x;
public double y;
public double z;
public double w;
public Quat4d clone() {
Quat4d q;
try {
q = (Quat4d) super.clone();
} catch (CloneNotSupportedException ce) {
throw new RuntimeException();
}
q.set(x, y, z, w);
return q;
}
// コンストラクタ
public Quat4d() {
x = 0.0;
y = 0.0;
z = 0.0;
w = 0.0;
}
// コンストラクタ
public Quat4d(double px, double py, double pz, double pw) {
double mag = 1.0/Math.sqrt(px*px+py*py+pz*pz+pw*pw);
x = px*mag;
y = py*mag;
z = pz*mag;
w = pw*mag;
}
public Quat4d(Quat4d q) {
x = q.x;
y = q.y;
z = q.z;
w = q.w;
}
public void set(AxisAngle4d a) {
double mag,amag;
amag = Math.sqrt( a.x*a.x + a.y*a.y + a.z*a.z);
if( amag < EPS ) {
w = 0.0;
x = 0.0;
y = 0.0;
z = 0.0;
} else {
amag = 1.0/amag;
mag = Math.sin(a.angle/2.0);
w = Math.cos(a.angle/2.0);
x = a.x*amag*mag;
y = a.y*amag*mag;
z = a.z*amag*mag;
}
}
private void set(double x2, double y2, double z2, double w2) {
x = x2;
y = y2;
z = z2;
w = w2;
}
public void mul(Quat4d q1) {
double x, y, w;
w = this.w * q1.w - this.x * q1.x - this.y * q1.y - this.z * q1.z;
x = this.w * q1.x + q1.w * this.x + this.y * q1.z - this.z * q1.y;
y = this.w * q1.y + q1.w * this.y - this.x * q1.z + this.z * q1.x;
this.z = this.w * q1.z + q1.w * this.z + this.x * q1.y - this.y * q1.x;
this.w = w;
this.x = x;
this.y = y;
}
public void interpolate(Quat4d q1, double alpha) {
double dot, s1, s2, om, sinom;
dot = x * q1.x + y * q1.y + z * q1.z + w * q1.w;
if (dot < 0) {
// negate quaternion
q1.x = -q1.x;
q1.y = -q1.y;
q1.z = -q1.z;
q1.w = -q1.w;
dot = -dot;
}
if ((1.0 - dot) > EPS) {
om = Math.acos(dot);
sinom = Math.sin(om);
s1 = Math.sin((1.0 - alpha) * om) / sinom;
s2 = Math.sin(alpha * om) / sinom;
} else {
s1 = 1.0 - alpha;
s2 = alpha;
}
w = s1 * w + s2 * q1.w;
x = s1 * x + s2 * q1.x;
y = s1 * y + s2 * q1.y;
z = s1 * z + s2 * q1.z;
}
public void normalize() {
double norm;
norm = (this.x * this.x + this.y * this.y + this.z * this.z + this.w
* this.w);
if (norm > 0.0) {
norm = 1.0 / Math.sqrt(norm);
this.x *= norm;
this.y *= norm;
this.z *= norm;
this.w *= norm;
} else {
this.x = 0.0;
this.y = 0.0;
this.z = 0.0;
this.w = 0.0;
}
}
}