ms3

package
v0.0.0-...-370dd11 Latest Latest
Warning

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

Go to latest
Published: Jan 9, 2023 License: MIT Imports: 4 Imported by: 1

Documentation

Overview

package ms3 is a 32bit 3D math package based around the Vec type.

This is a different take compared to mgl32, a package that treats all data equally by giving them their own namespace with methods. This package is more similar to gonum's take on spatial operations where package-level functions like `Add` are reserved specifically for vector operations, which tend to be the most common. This aids in readability since long string of operations using methods can be remarkably hard to follow.

The name roughly stands for (m)ath for (s)hort floats in (3)D. "short" since there are no native 16 bit floats in Go.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Cos

func Cos(p, q Vec) float32

Cos returns the cosine of the opening angle between p and q.

func Divergence

func Divergence(p, step Vec, field func(Vec) Vec) float32

Divergence returns the divergence of the vector field at the point p, approximated using finite differences with the given step sizes.

func Dot

func Dot(p, q Vec) float32

Dot returns the dot product p·q.

func Norm

func Norm(p Vec) float32

Norm returns the Euclidean norm of p

|p| = sqrt(p_x^2 + p_y^2 + p_z^2).

func Norm2

func Norm2(p Vec) float32

Norm2 returns the Euclidean squared norm of p

|p|^2 = p_x^2 + p_y^2 + p_z^2.

func Sort

func Sort(a, b, c float32) (l1, l2, l3 float32)

Sort performs the sort-3 algorithm and returns l1, l2, l3 such that l1 ≤ l2 ≤ l3.

Types

type Box

type Box struct {
	Min, Max Vec
}

Box is a 3D bounding box. Well formed Boxes Min components are smaller than Max components.

func NewBox

func NewBox(x0, y0, z0, x1, y1, z1 float32) Box

NewBox is shorthand for Box{Min:Vec{x0,y0,z0}, Max:Vec{x1,y1,z1}}. The sides are swapped so that the resulting Box is well formed.

func (Box) Add

func (a Box) Add(v Vec) Box

Add adds v to the bounding box components. It is the equivalent of translating the Box by v.

func (Box) Canon

func (a Box) Canon() Box

Canon returns the canonical version of a. The returned Box has minimum and maximum coordinates swapped if necessary so that it is well-formed.

func (Box) Center

func (a Box) Center() Vec

Center returns the center of the Box.

func (Box) Contains

func (a Box) Contains(v Vec) bool

Contains returns true if v is contained within the bounds of the Box.

func (Box) Empty

func (a Box) Empty() bool

IsEmpty returns true if a Box's volume is zero or if a Min component is greater than its Max component.

func (Box) Scale

func (a Box) Scale(scale Vec) Box

Scale returns a new Box scaled by a size vector around its center. The scaling is done element wise which is to say the Box's X dimension is scaled by scale.X. Negative elements of scale are interpreted as zero.

func (Box) Size

func (a Box) Size() Vec

Size returns the size of the Box.

func (Box) Union

func (a Box) Union(b Box) Box

Union returns a box enclosing both the receiver and argument Boxes.

func (Box) Vertices

func (a Box) Vertices() []Vec

Vertices returns a slice of the 8 vertices corresponding to each of the Box's corners.

Ordering of vertices 0-3 is CCW in the XY plane starting at box minimum. Ordering of vertices 4-7 is CCW in the XY plane starting at box minimum for X and Y values and maximum Z value.

Edges for the box can be constructed with the following indices:

edges := [12][2]int{
 {0, 1}, {1, 2}, {2, 3}, {3, 0},
 {4, 5}, {5, 6}, {6, 7}, {7, 4},
 {0, 4}, {1, 5}, {2, 6}, {3, 7},
}

type Mat

type Mat [3 * 3]float32

func Identity

func Identity() *Mat

Identity returns the Identity 3x3 matrix

func NewMat

func NewMat(val []float32) *Mat

func (*Mat) Add

func (m *Mat) Add(A, B *Mat)

Add adds a and b element-wise, placing the result in the receiver. Add will panic if the two matrices do not have the same shape.

func (*Mat) At

func (m *Mat) At(i, j int) float32

func (*Mat) Dims

func (m *Mat) Dims() (r, c int)

func (*Mat) Mul

func (m *Mat) Mul(a, b *Mat)

Mul takes the matrix product of a and b, placing the result in the receiver. If the number of columns in a does not equal 3, Mul will panic.

func (*Mat) MulVec

func (m *Mat) MulVec(v Vec) (result Vec)

Performs matrix multiplication on v:

result = M * v

func (*Mat) MulVecTrans

func (m *Mat) MulVecTrans(v Vec) (result Vec)

Performs transposed matrix multiplication on v:

result = Mᵀ * v

func (*Mat) Prod

func (m *Mat) Prod(v1, v2t Vec)

Prod performs vector multiplication as if they were matrices

m = v1 * v2ᵀ

func (*Mat) RotationFromQuat

func (m *Mat) RotationFromQuat(q Quat)

RotationFromQuat stores the rotation matrix from a quaternion (must be normalized).

[R] = q.Real*q.Real * [E] - dot([q],[q])*[E] + 2*[q]*[q]ᵀ + 2*q.Real * skew([q])

where

[q] = {q.Imag, q.Jmag, q.Kmag}

and

[E]=Eye()

func (*Mat) Scale

func (m *Mat) Scale(f float32, a *Mat)

Scale multiplies the elements of a by f, placing the result in the receiver.

See the Scaler interface for more information.

func (*Mat) Set

func (m *Mat) Set(i, j int, v float32)

func (*Mat) Skew

func (m *Mat) Skew(v Vec)

Skew returns the skew symmetric matrix (right hand system) of v.

                [0  -z  y]
Skew({x,y,z}) = [z   0 -x]
                [-y  x  0]

func (Mat) String

func (m Mat) String() string

func (*Mat) Sub

func (m *Mat) Sub(a, b *Mat)

Subtracts b from a and stores result in receiver. Sub will panic if the two matrices do not have the same shape.

func (*Mat) VecCol

func (m *Mat) VecCol(j int) Vec

func (*Mat) VecRow

func (m *Mat) VecRow(i int) Vec

type Quat

type Quat struct {
	// V contains I, J and K imaginary parts.
	V Vec
	W float32
}

Quat represents a Quaternion, which is an extension of the imaginary numbers; there's all sorts of interesting theory behind it. In 3D graphics we mostly use it as a cheap way of representing rotation since quaternions are cheaper to multiply by, and easier to interpolate than matrices.

A Quaternion has two parts: W, the so-called scalar component, and "V", the vector component. The vector component is considered to be the part in 3D space, while W (loosely interpreted) is its 4D coordinate.

The imaginary V part is guaranteed to have an offset of zero in the Quat struct:

unsafe.Offsetof(q.V) // == 0

func AnglesToQuat

func AnglesToQuat(angle1, angle2, angle3 float32, order RotationOrder) Quat

AnglesToQuat performs a rotation in the specified order. If the order is not a valid RotationOrder, this function will panic

The rotation "order" is more of an axis descriptor. For instance XZX would tell the function to interpret angle1 as a rotation about the X axis, angle2 about the Z axis, and angle3 about the X axis again.

Based off the code for the Matlab function "angle2quat", though this implementation only supports 3 single angles as opposed to multiple angles.

func QuatBetweenVectors

func QuatBetweenVectors(start, dest Vec) Quat

QuatBetweenVectors calculates the rotation between two vectors

func QuatIdent

func QuatIdent() Quat

QuatIdent returns the quaternion identity: W=1; V=(0,0,0).

As with all identities, multiplying any quaternion by this will yield the same quaternion you started with.

func QuatLerp

func QuatLerp(q1, q2 Quat, amount float32) Quat

QuatLerp is a *L*inear Int*erp*olation between two Quaternions, cheap and simple.

Not excessively useful, but uses can be found.

func QuatLookAtV

func QuatLookAtV(eye, center, up Vec) Quat

QuatLookAtV creates a rotation from an eye vector to a center vector

It assumes the front of the rotated object at Z- and up at Y+

func QuatNlerp

func QuatNlerp(q1, q2 Quat, amount float32) Quat

QuatNlerp is a *Normalized* *L*inear Int*erp*olation between two Quaternions. Cheaper than Slerp and usually just as good. This is literally Lerp with Normalize() called on it.

Unlike Slerp, constant velocity isn't maintained, but it's much faster and Nlerp(q1,q2) and Nlerp(q2,q1) return the same path. You should probably use this more often unless you're suffering from choppiness due to the non-constant velocity problem.

func QuatRotate

func QuatRotate(angle float32, axis Vec) Quat

QuatRotate creates an angle from an axis and an angle relative to that axis.

This is cheaper than HomogRotate3D.

func QuatSlerp

func QuatSlerp(q1, q2 Quat, amount float32) Quat

QuatSlerp is *S*pherical *L*inear Int*erp*olation, a method of interpolating between two quaternions. This always takes the straightest path on the sphere between the two quaternions, and maintains constant velocity.

However, it's expensive and QuatSlerp(q1,q2) is not the same as QuatSlerp(q2,q1)

func (Quat) Add

func (q1 Quat) Add(q2 Quat) Quat

Add adds two quaternions. It's no more complicated than adding their W and V components.

func (Quat) Conjugate

func (q1 Quat) Conjugate() Quat

Conjugate returns the conjugate of a quaternion. Equivalent to Quat{q1.W, q1.V.Mul(-1)}.

func (Quat) Dot

func (q1 Quat) Dot(q2 Quat) float32

Dot product between two quaternions, equivalent to if this was a Vec4.

func (Quat) Inverse

func (q1 Quat) Inverse() Quat

Inverse of a quaternion. The inverse is equivalent to the conjugate divided by the square of the length.

This method computes the square norm by directly adding the sum of the squares of all terms instead of actually squaring q1.Len(), both for performance and precision.

func (Quat) Mul

func (q1 Quat) Mul(q2 Quat) Quat

Mul multiplies two quaternions. This can be seen as a rotation. Note that Multiplication is NOT commutative, meaning q1.Mul(q2) does not necessarily equal q2.Mul(q1).

func (Quat) Norm

func (q1 Quat) Norm() float32

Norm returns the euclidean length of the quaternion.

func (Quat) Rotate

func (q1 Quat) Rotate(v Vec) Vec

Rotate a vector by the rotation this quaternion represents. This will result in a 3D vector. Strictly speaking, this is equivalent to q1.v.q* where the "."" is quaternion multiplication and v is interpreted as a quaternion with W 0 and V v. In code: q1.Mul(Quat{0,v}).Mul(q1.Conjugate()), and then retrieving the imaginary (vector) part.

In practice, we hand-compute this in the general case and simplify to save a few operations.

func (Quat) Scale

func (q1 Quat) Scale(c float32) Quat

Scale every element of the quaternion by some constant factor.

func (Quat) Sub

func (q1 Quat) Sub(q2 Quat) Quat

Sub subtracts two quaternions. It's no more complicated than subtracting their W and V components.

func (Quat) Unit

func (q1 Quat) Unit() Quat

Normalize the quaternion, returning its versor (unit quaternion).

This is the same as normalizing it as a Vec4.

type RotationOrder

type RotationOrder int

RotationOrder is the order in which rotations will be transformed for the purposes of AnglesToQuat.

const (
	XYX RotationOrder = iota
	XYZ
	XZX
	XZY
	YXY
	YXZ
	YZY
	YZX
	ZYZ
	ZYX
	ZXZ
	ZXY
)

The RotationOrder constants represent a series of rotations along the given axes for the use of AnglesToQuat.

type Triangle

type Triangle [3]Vec

Triangle represents a triangle in 3D space and is composed by 3 vectors corresponding to the position of each of the vertices. Ordering of these vertices decides the "normal" direction. Inverting ordering of two vertices inverts the resulting direction.

func (Triangle) Area

func (t Triangle) Area() float32

Area returns the surface area of the triangle.

func (Triangle) Centroid

func (t Triangle) Centroid() Vec

Centroid returns the intersection of the three medians of the triangle as a point in space.

func (Triangle) IsDegenerate

func (t Triangle) IsDegenerate(tol float32) bool

IsDegenerate returns true if all of triangle's vertices are within tol distance of its longest side.

func (Triangle) Normal

func (t Triangle) Normal() Vec

Normal returns the vector with direction perpendicular to the Triangle's face and magnitude twice that of the Triangle's area. The ordering of the triangle vertices decides the normal's resulting direction. The returned vector is not normalized.

type Vec

type Vec struct {
	X, Y, Z float32
}

Vec is a 3D vector.

func AbsElem

func AbsElem(a Vec) Vec

AbsElem returns the vector with components set to their absolute value.

func Add

func Add(p, q Vec) Vec

Add returns the vector sum of p and q.

func Cross

func Cross(p, q Vec) Vec

Cross returns the cross product p×q.

func Gradient

func Gradient(p, step Vec, field func(Vec) float32) Vec

Gradient returns the gradient of the scalar field at the point p, approximated using finite differences with the given step sizes.

func MaxElem

func MaxElem(a, b Vec) Vec

MaxElem return a vector with the maximum components of two vectors.

func MinElem

func MinElem(a, b Vec) Vec

MinElem return a vector with the minimum components of two vectors.

func MulElem

func MulElem(a, b Vec) Vec

MulElem returns the Hadamard product between vectors a and b.

v = {a.X*b.X, a.Y*b.Y, a.Z*b.Z}

func Scale

func Scale(f float32, p Vec) Vec

Scale returns the vector p scaled by f.

func Sub

func Sub(p, q Vec) Vec

Sub returns the vector sum of p and -q.

func Unit

func Unit(p Vec) Vec

Unit returns the unit vector colinear to p. Unit returns {NaN,NaN,NaN} for the zero vector.

Jump to

Keyboard shortcuts

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