quaternion

package module
v0.0.0-...-e66e49f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2026 License: MIT Imports: 2 Imported by: 5

README

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()

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Quaternion

type Quaternion struct {
	W float64 // Scalar component
	X float64 // i component
	Y float64 // j component
	Z float64 // k component
}

Quaternion represents a quaternion W+X*i+Y*j+Z*k

func FromAxisAngle

func FromAxisAngle(axis Vec3, angle float64) Quaternion

FromAxisAngle returns a Quaternion representing a rotation of angle radians about the given axis. The axis is normalized internally.

func FromEuler

func FromEuler(phi, theta, psi float64) Quaternion

FromEuler returns a Quaternion corresponding to Euler angles phi, theta, psi

func Identity

func Identity() Quaternion

Identity returns the multiplicative identity quaternion (1,0,0,0), which represents "no rotation".

func New

func New(w, x, y, z float64) Quaternion

New returns a new quaternion

func Nlerp

func Nlerp(q0, q1 Quaternion, t float64) Quaternion

Nlerp returns the normalized linear interpolation between unit quaternions q0 and q1 at parameter t in [0,1]. It is cheaper than Slerp but does not rotate at a constant angular velocity.

func Prod

func Prod(qin ...Quaternion) Quaternion

Prod returns the non-commutative product of any number of Quaternions

func Pure

func Pure(x, y, z float64) Quaternion

Pure returns a new pure quaternion (no scalar part)

func Scalar

func Scalar(w float64) Quaternion

Scalar returns a scalar-only Quaternion representation of a float (W,0,0,0)

func Slerp

func Slerp(q0, q1 Quaternion, t float64) Quaternion

Slerp returns the spherical linear interpolation between unit quaternions q0 and q1 at parameter t in [0,1], rotating along the shortest arc at a constant angular velocity. Near-parallel inputs fall back to Nlerp.

func Sum

func Sum(qin ...Quaternion) Quaternion

Sum returns the vector sum of any number of Quaternions

func (Quaternion) ApproxEqual

func (q Quaternion) ApproxEqual(r Quaternion, tol float64) bool

ApproxEqual reports whether every component of q and r differs by no more than tol

func (Quaternion) AxisAngle

func (qin Quaternion) AxisAngle() (axis Vec3, angle float64)

AxisAngle returns the unit axis and angle (in radians) of the rotation represented by the Quaternion. For a rotation of ~0 the axis is undefined and (1,0,0) is returned.

func (Quaternion) Conj

func (qin Quaternion) Conj() Quaternion

Conj returns the conjugate of a Quaternion (W,X,Y,Z) -> (W,-X,-Y,-Z)

func (Quaternion) Dot

func (q Quaternion) Dot(r Quaternion) float64

Dot returns the dot product of two Quaternions treated as 4-vectors

func (Quaternion) Euler

func (q Quaternion) Euler() (float64, float64, float64)

Euler returns the Euler angles phi, theta, psi corresponding to a Quaternion

func (Quaternion) Inv

func (qin Quaternion) Inv() Quaternion

Inv returns the Quaternion conjugate rescaled so that Q Q* = 1. The zero quaternion has no inverse and is returned unchanged.

func (Quaternion) Mul

func (q Quaternion) Mul(r Quaternion) Quaternion

Mul returns the non-commutative Hamilton product q*r of two Quaternions

func (Quaternion) Neg

func (qin Quaternion) Neg() Quaternion

Neg returns the negative

func (Quaternion) Norm

func (qin Quaternion) Norm() float64

Norm returns the Euclidean (L2) norm of a Quaternion (W,X,Y,Z) -> Sqrt(W*W+X*X+Y*Y+Z*Z)

func (Quaternion) Norm2

func (qin Quaternion) Norm2() float64

Norm2 returns the squared Euclidean norm of a Quaternion (W,X,Y,Z) -> W*W+X*X+Y*Y+Z*Z

func (Quaternion) RotMat

func (qin Quaternion) RotMat() [3][3]float64

RotMat returns the rotation matrix (as float array) corresponding to a Quaternion

func (Quaternion) RotMatUnit

func (q Quaternion) RotMatUnit() [3][3]float64

RotMatUnit is like RotMat but assumes the quaternion is already unit-length and skips normalization. The result is meaningful only for a unit quaternion. (The body mirrors RotMat without the Unit() call; TestRotMatUnit guards that the two stay in agreement.)

func (Quaternion) RotateVec3

func (qin Quaternion) RotateVec3(vec Vec3) Vec3

RotateVec3 returns the vector rotated by the quaternion. The quaternion is normalized first, so the result is a pure rotation regardless of its norm.

func (Quaternion) RotateVec3Unit

func (qin Quaternion) RotateVec3Unit(vec Vec3) Vec3

RotateVec3Unit is like RotateVec3 but assumes the quaternion is already unit-length and skips normalization. The result is meaningful only for a unit quaternion; for any other the vector is scaled by the squared norm.

func (Quaternion) Scale

func (qin Quaternion) Scale(k float64) Quaternion

Scale returns the Quaternion with every component multiplied by k

func (Quaternion) String

func (q Quaternion) String() string

String implements fmt.Stringer, e.g. "0.5 + 0.5i - 0.707j - 0.707k"

func (Quaternion) Sub

func (q Quaternion) Sub(r Quaternion) Quaternion

Sub returns the component-wise difference q-r of two Quaternions

func (Quaternion) Unit

func (qin Quaternion) Unit() Quaternion

Unit returns the Quaternion rescaled to unit norm. The zero quaternion has no unit form and is returned unchanged.

type Vec3

type Vec3 struct {
	X float64
	Y float64
	Z float64
}

Vec3 represents a vector in 3d space

func (Vec3) Add

func (v Vec3) Add(w Vec3) Vec3

Add returns the vector sum v+w

func (Vec3) Cross

func (v Vec3) Cross(w Vec3) Vec3

Cross returns the cross product v×w

func (Vec3) Dot

func (v Vec3) Dot(w Vec3) float64

Dot returns the dot product v·w

func (Vec3) Norm

func (v Vec3) Norm() float64

Norm returns the Euclidean length of the vector

func (Vec3) Normalize

func (v Vec3) Normalize() Vec3

Normalize returns the vector rescaled to unit length. The zero vector is returned unchanged.

func (Vec3) Rotate

func (vin Vec3) Rotate(q Quaternion) Vec3

Rotate returns the vector rotated by the quaternion.

func (Vec3) RotateUnit

func (vin Vec3) RotateUnit(q Quaternion) Vec3

RotateUnit is like Rotate but assumes the quaternion is already unit-length and skips normalization. See RotateVec3Unit.

func (Vec3) Scale

func (v Vec3) Scale(k float64) Vec3

Scale returns the vector with every component multiplied by k

func (Vec3) Sub

func (v Vec3) Sub(w Vec3) Vec3

Sub returns the vector difference v-w

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL