ms3

package
v0.0.0-...-a2463fe Latest Latest
Warning

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

Go to latest
Published: Nov 24, 2024 License: MIT Imports: 3 Imported by: 11

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 EqualElem

func EqualElem(a, b Vec, tol float32) bool

EqualElem checks equality between vector elements to within a tolerance.

func EqualMat3

func EqualMat3(a, b Mat3, tolerance float32) bool

EqualMat3 tests the equality of 3x3 matrices.

func EqualMat4

func EqualMat4(a, b Mat4, tolerance float32) bool

EqualMat4 tests the equality of 4x4 matrices.

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. Max is the most positive/largest vertex, Min is the most negative/smallest vertex.

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 NewCenteredBox

func NewCenteredBox(center, size Vec) Box

NewCenteredBox returns a box centered around center with size dimensions.

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(point Vec) bool

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

func (Box) Diagonal

func (a Box) Diagonal() float32

Diagonal returns a's diagonal length: sqrt(L*L + W*W + H*H).

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

func (a Box) Equal(b Box, tol float32) bool

Equal returns true if a and b are within tol of eachother for each box limit component.

func (Box) IncludePoint

func (a Box) IncludePoint(point Vec) Box

IncludePoint returns a box containing both the receiver and the argument point.

func (Box) Intersect

func (a Box) Intersect(b Box) (intersect Box)

Intersect returns a box enclosing the box space shared by both boxes.

func (Box) Scale

func (a Box) Scale(scale Vec) Box

Scale scales the box dimensions and positions in 3 directions. Does not preserve box center. Negative elements of scale can be used to mirror box dimension.

func (Box) ScaleCentered

func (a Box) ScaleCentered(scale Vec) Box

ScaleCentered 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() [8]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},
}

func (Box) Volume

func (a Box) Volume() float32

Volume returns the volume contained within the box. Returns 0 for malformed boxes.

type Line

type Line [2]Vec

Line is an infinite 3D line defined by two points on the line.

func (Line) Distance

func (l Line) Distance(p Vec) float32

Distance returns the minimum euclidean Distance of point p to the infinite line.

func (Line) Interpolate

func (l Line) Interpolate(t float32) Vec

Interpolate takes a value between 0 and 1 to linearly interpolate a point on the line.

Interpolate(0) returns l[0]
Interpolate(1) returns l[1]

type Mat3

type Mat3 struct {
	// contains filtered or unexported fields
}

Mat3 is a 3x3 matrix.

func AddMat3

func AddMat3(a, b Mat3) Mat3

AddMat3 adds two 3x3 matrices together.

func IdentityMat3

func IdentityMat3() Mat3

IdentityMat3 returns the 3x3 identity matrix.

func MulMat3

func MulMat3(a, b Mat3) Mat3

MulMat3 multiplies two 3x3 matrices.

func NewMat3

func NewMat3(v []float32) (m Mat3)

NewMat3 instantiates a new matrix from the first 9 floats, row major order. If v is of insufficient length NewMat3 panics.

func Prod

func Prod(v1, v2t Vec) Mat3

Prod performs vector multiplication as if they were matrices

m = v1 * v2ᵀ

func RotatingMat3

func RotatingMat3(rotationUnit Quat) Mat3

RotatingMat3 returns a 3×3 rotation matrix corresponding to the receiver. It may be used to perform rotations on a 3-vector or to apply the rotation to a 3×n matrix of column vectors. If the receiver is not a unit quaternion, the returned matrix will not be a pure rotation.

func ScaleMat3

func ScaleMat3(a Mat3, k float32) Mat3

ScaleMat3 multiplies each 3x3 matrix component by a scalar.

func Skew

func Skew(v Vec) Mat3

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

                ⎡ 0 -z  y⎤
Skew({x,y,z}) = ⎢ z  0 -x⎥
                ⎣-y  x  0⎦

func (Mat3) Array

func (m Mat3) Array() (rowmajor [9]float32)

Array returns the matrix values in a static array copy in row major order.

func (Mat3) AsMat4

func (m Mat3) AsMat4() Mat4

AsMat4 expands the Mat3 to fill the first rows and columns of a Mat4 and sets the last diagonal element of the Mat4 to 1.

func (Mat3) Determinant

func (a Mat3) Determinant() float32

Determinant returns the determinant of a 3x3 matrix.

func (Mat3) Inverse

func (a Mat3) Inverse() Mat3

Inverse returns the inverse of a 3x3 matrix.

func (Mat3) Put

func (m Mat3) Put(b []float32)

Put stores the matrix values into slice b in row major order. If b is not of length 9 or greater Put panics.

func (Mat3) QRDecomposition

func (b Mat3) QRDecomposition() (q, r Mat3)

QRDecomposition performs QR decomposition of a 3x3 matrix using Mat3 type.

func (Mat3) SVD

func (a Mat3) SVD() (U, S, V Mat3)

SVD performs singular value decomposition on a 3x3 matrix.

func (Mat3) Transpose

func (a Mat3) Transpose() Mat3

Transpose returns the transpose of a.

func (Mat3) VecCol

func (m Mat3) VecCol(j int) Vec

VecCol returns the jth column as a Vec.

func (Mat3) VecDiag

func (m Mat3) VecDiag() Vec

VecDiag returns the matrix diagonal as a Vec.

func (Mat3) VecRow

func (m Mat3) VecRow(i int) Vec

VecRow returns the ith row as a Vec.

type Mat4

type Mat4 struct {
	// contains filtered or unexported fields
}

Mat4 is a 4x4 matrix.

func IdentityMat4

func IdentityMat4() Mat4

IdentityMat4 returns the identity 4x4 matrix.

func MulMat4

func MulMat4(a, b Mat4) Mat4

MulMat4 multiplies two 4x4 matrices and returns the result.

func NewMat4

func NewMat4(v []float32) (m Mat4)

NewMat4 instantiates a new 4x4 Mat4 matrix from the first 16 values in row major order. If v is shorter than 16 NewMat4 panics.

func RotatingBetweenVecsMat4

func RotatingBetweenVecsMat4(start, dest Vec) Mat4

RotatingBetweenVecsMat4 returns the rotation matrix that transforms "start" onto the same direction as "dest".

func RotatingMat4

func RotatingMat4(angleRadians float32, axis Vec) Mat4

RotatingMat4 returns an orthographic 4x4 rotation matrix (right hand rule).

func ScalingMat4

func ScalingMat4(v Vec) Mat4

ScalingMat4 returns a 4x4 scaling matrix. Scaling does not preserve distance. See: ScaleUniform3D()

func TranslatingMat4

func TranslatingMat4(v Vec) Mat4

TranslatingMat4 returns a 4x4 translation matrix.

func (Mat4) Array

func (m Mat4) Array() (rowmajor [16]float32)

Array returns the matrix values in a static array copy in row major order.

func (Mat4) Determinant

func (a Mat4) Determinant() float32

Determinant returns the determinant of a 4x4 matrix.

func (Mat4) Inverse

func (a Mat4) Inverse() Mat4

Inverse returns the inverse of a 4x4 matrix. Does not check for singularity.

func (Mat4) MulBox

func (a Mat4) MulBox(box Box) Box

MulBox rotates/translates a 3d bounding box and resizes for axis-alignment.

func (Mat4) MulPosition

func (a Mat4) MulPosition(b Vec) Vec

MulPosition multiplies a r3.Vec position with a rotate/translate matrix.

func (*Mat4) Put

func (m *Mat4) Put(b []float32)

Put puts elements of the matrix in row-major order in b. If b is not of at least length 16 then Put panics.

func (Mat4) Transpose

func (a Mat4) Transpose() Mat4

Transpose returns the transpose of a.

type Quat

type Quat struct {
	// V contains I, J and K imaginary parts.
	I, J, K float32
	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 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 QuatLookAt

func QuatLookAt(eye, center, upDir Vec) Quat

QuatLookAt creates a rotation from an eye point to a center point.

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 QuatSlerp

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

QuatSlerp is Spherical Linear intERPolation, 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 RotationBetweenVecsQuat

func RotationBetweenVecsQuat(start, dest Vec) Quat

RotationBetweenVecsQuat calculates the rotation between start and dest.

func RotationQuat

func RotationQuat(angle float32, axis Vec) Quat

RotationQuat creates a rotation quaternion that rotates an angle relative an axis. Call Rotate method on Quat to apply rotation.

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

func (q Quat) IJK() Vec

IJK returns I,J,K fields of q as a vector with set fields X,Y,Z, respectively.

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

func (q Quat) RotationMat3() Mat3

RotationMat3 returns a rotation 3x3 matrix.

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.

func (Quat) WithIJK

func (q Quat) WithIJK(ijk Vec) Quat

WithIJK replaces I, J and K fields of q with X,Y and Z fields of argument Vec ijk and returns the result.

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
	// contains filtered or unexported fields
}

Vec is a 3D vector. It is composed of 3 float32 fields for x, y, and z values in that order. Padding is added to reach 16 byte size for use with OpenGL with 1-to-1 mapping with vec3 and dvec3 types.

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 AddScalar

func AddScalar(f float32, v Vec) Vec

AddScalar adds f to all of v's components and returns the result.

func AppendGrid

func AppendGrid(dst []Vec, bounds Box, nx, ny, nz int) []Vec

AppendGrid splits the argument bounds Box x,y,z axes by nx,ny,nz, respectively and generates points on the vertices generated by the division and appends them to dst, returning the result.

Indexing is x-major, y-second-major:

grid := ms3.AppendGrid(nil, bb, nx, ny, nz)
ix, iy, iz := 1, 0, 3
pos := grid[iz*(nx+ny) + iy*nx + ix]

func CeilElem

func CeilElem(a Vec) Vec

CeilElem returns a with Ceil applied to each component.

func ClampElem

func ClampElem(v, Min, Max Vec) Vec

Clamp returns v with its elements clamped to Min and Max's components.

func CosElem

func CosElem(a Vec) Vec

CosElem returns cos(a) component-wise.

func Cross

func Cross(p, q Vec) Vec

Cross returns the cross product p×q.

func DivElem

func DivElem(a, b Vec) Vec

DivElem returns the Hadamard product between vector a and the inverse components of vector b.

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

func FloorElem

func FloorElem(a Vec) Vec

FloorElem returns a with Floor applied to each component.

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 InterpElem

func InterpElem(x, y, a Vec) Vec

InterpElem performs a linear interpolation between x and y's elements, mapping with a's values in interval [0,1]. This function is also known as "mix" in OpenGL.

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 MulMatVec

func MulMatVec(m Mat3, v Vec) (result Vec)

MulMatVec performs matrix multiplication on v:

result = M * v

func MulMatVecTrans

func MulMatVecTrans(m Mat3, v Vec) (result Vec)

MulMatVecTrans Performs transposed matrix multiplication on v:

result = Mᵀ * v

func RoundElem

func RoundElem(a Vec) Vec

Round rounds the individual elements of a vector.

func Scale

func Scale(f float32, p Vec) Vec

Scale returns the vector p scaled by f.

func SignElem

func SignElem(a Vec) Vec

Sign returns sign function applied to each individual component of a. If a component is zero then zero is returned.

func SinElem

func SinElem(a Vec) Vec

SinElem returns sin(a) component-wise.

func SincosElem

func SincosElem(a Vec) (s, c Vec)

SincosElem returns (sin(a), cos(a)). Is more efficient than calling both SinElem and CosElem.

func SmoothStepElem

func SmoothStepElem(e0, e1, x Vec) Vec

SmoothStepElem performs element-wise smooth cubic hermite interpolation between 0 and 1 when e0 < x < e1.

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.

func (Vec) AllNonzero

func (a Vec) AllNonzero() bool

AllNonzero returns true if all elements of a are nonzero.

func (Vec) Array

func (a Vec) Array() [3]float32

Array returns the ordered components of Vec in a 3 element array [a.x,a.y,a.z].

func (Vec) Max

func (a Vec) Max() float32

Max returns the maximum component of a.

func (Vec) Min

func (a Vec) Min() float32

Min returns the minimum component of a.

Jump to

Keyboard shortcuts

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