这是我的简单四元数类。它使用了本教程中的许多语义:
public class Quaternion {
public double w, x, y, z;
public Quaternion(double angleRadian, double x, double y, double z){
double dAngle=angleRadian/2; //might as well divide by 2 here
this.w=Math.cos(dAngle);
this.x=x * Math.sin(dAngle);
this.y=y * Math.sin(dAngle);
this.z=z * Math.sin(dAngle);
}
public Quaternion(){
x=y=z=0; w=1;
}
public void norm(){
double magnitude = Math.sqrt(w*w + x*x + y*y + z*z);
w = w / magnitude;
x = x / magnitude;
y = y / magnitude;
z = z / magnitude;
}
public Quaternion conj(){
Quaternion ans = new Quaternion();
ans.set(this);
ans.conjLocal();
return ans;
}
public void conjLocal(){
x=-x;
y=-y;
z=-z;
}
public void set(Quaternion q){
w=q.w;
x=q.x;
y=q.y;
z=q.z;
}
public void set(double w, double x, double y, double z){
this.w=w;
this.x=x;
this.y=y;
this.z=z;
}
public Quaternion mult(Quaternion q){
Quaternion ans = new Quaternion();
ans.w = (this.w*q.w - this.x*q.x - this.y*q.y - this.z*q.z);
ans.x = (this.w*q.x + this.x*q.w + this.y*q.z - this.z*q.y);
ans.y = (this.w*q.y - this.x*q.z + this.y*q.w + this.z*q.x);
ans.z = (this.w*q.z + this.x*q.y - this.y*q.x + this.z*q.w);
return ans;
}
public void multLocal(Quaternion q){
Quaternion temp=this.mult(q);
this.set(temp);
}
public String toString(){ return "<"+w+", "+x+", "+y+", "+z+">"; }
}
v
要通过四元数旋转向量q
以获得结果向量v'
,必须使用以下等式:
v' = q * v * q.conj()
这是一个围绕四元数旋转矢量(或位置坐标)的演示。
public class QuaternionExample {
public static void main(String[] args) {
/*
* Let's say we have a vector <1,0,0>, and we want to rotate it
* such that the result will be in the other unit axiis: <0,1,0>
* and <0,0,1>. Right hand rule applies for rotating about an axis!
* Convince yourself of the following through mental imagery:
* 1. For <0,1,0>, we want to rotate <1,0,0> by 90 degrees about the z axis
* 2. For <0,0,1>, we want to rotate <1,0,0> by 90 degrees about the -y axis (or -90 degrees also works)
*/
//the quaternion form of a 3d vector is simply <0,Vec3> or <0,x,y,z>
Quaternion x=new Quaternion();
x.set(0,1,0,0);
//1, we want <0,1,0>
Quaternion rot = new Quaternion(Math.PI/2,0,0,1);
System.out.println( rot.mult(x).mult(rot.conj()) );
//2, we want <0,0,1>
rot = new Quaternion(Math.PI/2,0,-1,0);
System.out.println( rot.mult(x).mult(rot.conj()) );
rot = new Quaternion(-Math.PI/2,0,1,0);
System.out.println( rot.mult(x).mult(rot.conj()) );
}
}
我想围绕原点旋转我的矢量(或位置坐标)。如果我想围绕不同的点旋转它(例如,对象的质心c
),我需要先减去对象的质心,然后将其添加到结果中:
v' = q * (v-c) * q.conj() + c