-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathQuaternion.java
More file actions
103 lines (91 loc) · 2.92 KB
/
Quaternion.java
File metadata and controls
103 lines (91 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
public class Quaternion
{
public static final Quaternion IDENTITY = new Quaternion(0, new Vector3(0, 0, 1));
/** scalar part of the quaternion */
public final double w;
public final double x;
public final double y;
public final double z;
/**
* creates a quaternion which represents a rotation around {@code axis}
* by {@code angle} degrees
* @param axis the axis of rotation
* @param angle angle in radians
*/
public Quaternion(double angle, Vector3 axis)
{
axis = (axis.getSqrMagnitude() != 1)? axis.getNormalized() : axis;
angle = Math.sin(angle/2);
w = Math.sqrt(1-angle*angle); //equal to doing Math.cos() of the origonal angle but faster
double sinAngle = angle;
x = axis.x*sinAngle;
y = axis.y*sinAngle;
z = axis.z*sinAngle;
}
/**
* creates a quaternion with specified components. warning: it doesn't normalize the values
* so be careful that only correct values are entered.
* @param wIn scalar real part of the quaternion
* @param iIn imaginary i
* @param jIn imaginary j
* @param kIn imaginary k
*/
public Quaternion(double wIn, double iIn, double jIn, double kIn)
{
w = wIn;
x = iIn;
y = jIn;
z = kIn;
}
/**
* @return the inverse of the quaternion
*/
public Quaternion getInverse()
{
return new Quaternion(w, -x, -y, -z);
}
/**
* formats to string
*/
public String toString()
{
return new String(String.format("[%.3f, %.3f, %.3f, %.3f]", w, x, y, z));
}
/**
* multiplies {@code q1} by {@code q2}
* @param q1
* @param q2
* @return the multiplied result
*/
public static Quaternion multiply(Quaternion q1, Quaternion q2)
{
return new Quaternion(
q1.w*q2.w-(q1.x*q2.x+q1.y*q2.y+q1.z*q2.z), //w
q2.w*q1.x + q1.w*q2.x + q1.y*q2.z-q1.z*q2.y, //x
q2.w*q1.y + q1.w*q2.y + q1.z*q2.x-q1.x*q2.z, //y
q2.w*q1.z + q1.w*q2.z + q1.x*q2.y-q1.y*q2.x); //z
}
/**
* converts an euler angle into quaternion
* @param pitch
* @param yaw
* @param roll
* @return the quaternion equivilant
*/
public static Quaternion toQuaternion(double pitch, double yaw, double roll)
{
double sy = Math.sin(roll * 0.5);
double cy = Math.sqrt(1-sy*sy);
double sp = Math.sin(yaw * 0.5);
double cp = Math.sqrt(1-sp*sp);
double sr = Math.sin(pitch * 0.5);
double cr = Math.sqrt(1-sr*sr);
return new Quaternion
(
cr * cp * cy + sr * sp * sy,
sr * cp * cy - cr * sp * sy,
cr * sp * cy + sr * cp * sy,
cr * cp * sy - sr * sp * cy
);
}
}