Skip to content

Navigation Menu

Sign in
Sign up

Repository files navigation

quaternion

Quaternion math in golang

Note: There are other packages to support quaternions in Go. See, for example, https://github.com/thisisneal/Quaternion. I couldn't find any under an unrestrictive license, so this is an implementation under the MIT license.

Quaternions

Quaternions are defined by i * i = j * j = k * k = i * j * k = -1. See https://en.wikipedia.org/wiki/Quaternion

Usage

Instantiate a quaternion q = a_w + a_x * i + a_y * j + a_z * k:

q1 := Quaternion{a_w, a_x, a_y, a_z}
q2 := Quaternion{W: 0.5, X: 0.5, Y: -0.707, Z: -0.707}
q3 := New(0.5,0.5,-0.707,-0.707)

A number (scalar) can be created with Quaternion or with the Scalar function:

qk1 := Quaternion{W: -0.5}
qk2 := Scalar(0.5)

A pure quaternion with no scalar component:

q := Pure(0.5, -0.707, -0.707)

The identity ("no rotation") quaternion:

q := Identity()

Calculate the conjugate q* = a_w - a_x * i - a_y * j - a_z * k:

q5 := qr.Conj()

Calculate the sum as a new quaternion:

q3 := Sum(q1, q2)

Sum takes any number of quaternions as arguments:

q4 := Sum(q3, q1, q2, q4)

Prod works the same way as Sum:

q5 := Prod(q4, q3, q1, q2)

For the common two-quaternion case, Mul is a faster binary product. Scale multiplies by a scalar and Sub takes a difference:

q6 := q1.Mul(q2)
q7 := q1.Scale(0.5)
q8 := q1.Sub(q2)
d := q1.Dot(q2)

Calculate the norm ("length") and the squared norm:

k := q5.Norm()
k2 := q5.Norm2()

Convert to/from Euler angle representations:

q1 := FromEuler(math.Pi/4, math.Pi/3, 5*math.Pi/3)
phi, theta, psi := q1.Euler()

Convert to/from axis-angle representations:

q := FromAxisAngle(Vec3{0, 0, 1}, math.Pi/2)
axis, angle := q.AxisAngle()

Interpolate between two rotations. Slerp follows the shortest arc at constant angular velocity; Nlerp is a cheaper approximation:

q := Slerp(q1, q2, 0.5)
q := Nlerp(q1, q2, 0.5)

Rotate a vector by a quaternion, and get the Rotation Matrix:

v := q1.RotateVec3(Vec3{0, 0, 1})
m := q1.RotMat()

RotateVec3 and RotMat normalize the quaternion first. If you already hold a unit quaternion, the Unit variants skip that step and run roughly twice as fast:

v := q1.RotateVec3Unit(Vec3{0, 0, 1})
m := q1.RotMatUnit()

About

Quaternion math in golang

Resources

Stars

34 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /