Package github.com/matjam/bunyip/lin
lin
Package lin provides the engine's linear algebra: vectors, matrices and quaternions in float32. Mat3 and Mat4 use column-major storage; Affine uses a row-major 2x3 layout. Projection helpers use right-handed coordinates and Vulkan's clip space (depth 0..1, +Y down).
Values are plain structs passed by value. Every operation returns a new value and never modifies its receiver. Angles are radians unless a function explicitly converts degrees. Matrices have all-zero zero values; use Identity, Identity3 or Identity2 for identity transforms.
eye := target.Add(lin.V3(0, 2, 5)) view := lin.LookAt(eye, target, lin.V3(0, 1, 0))
Index
func Clamp(v, lo, hi float32) float32func Degrees(rad float32) float32func Radians(deg float32) float32- type Affine
func Identity2() Affinefunc Rotate2(angle float32) Affinefunc Scale2(sx, sy float32) Affinefunc Shear2(kx, ky float32) Affinefunc Translate2(x, y float32) Affinefunc (m Affine) Apply(p Vec2) Vec2func (m Affine) ApplyVec(v Vec2) Vec2func (m Affine) Inverse() Affinefunc (m Affine) IsIdentity() boolfunc (m Affine) Mat4() Mat4func (m Affine) Mul(n Affine) Affinefunc (m Affine) Scale() float32func (m Affine) TransformRect(r Rect) Rect
- type Mat3
- type Mat4
func Identity() Mat4func LookAt(eye, target, up Vec3) Mat4func Ortho(left, right, bottom, top, near, far float32) Mat4func Ortho2D(width, height float32) Mat4func Perspective(fovy, aspect, near, far float32) Mat4func Rotate(angle float32, axis Vec3) Mat4func Scale(v Vec3) Mat4func TRS(t Vec3, r Quat, s Vec3) Mat4func Translate(v Vec3) Mat4func (m Mat4) At(row, col int) float32func (m Mat4) Decompose() (t Vec3, r Quat, s Vec3)func (m Mat4) Inverse() Mat4func (m Mat4) Mat3() Mat3func (m Mat4) Mul(n Mat4) Mat4func (m Mat4) MulAffine(n Mat4) Mat4func (m Mat4) MulPoint(p Vec3) Vec3func (m Mat4) MulVec4(v Vec4) Vec4func (m Mat4) NormalMatrix() Mat3func (m Mat4) Translation() Vec3func (m Mat4) Transpose() Mat4
- type Quat
func AxisAngle(axis Vec3, angle float32) Quatfunc FromEuler(yaw, pitch, roll float32) Quatfunc QuatFromMat4(m Mat4) Quatfunc QuatIdentity() Quatfunc QuatLookAt(forward, up Vec3) Quatfunc (q Quat) AxisAngle() (axis Vec3, angle float32)func (q Quat) Euler() (yaw, pitch, roll float32)func (q Quat) Mat4() Mat4func (q Quat) Mul(p Quat) Quatfunc (q Quat) Norm() Quatfunc (q Quat) Rotate(v Vec3) Vec3func (q Quat) Slerp(p Quat, t float32) Quat
- type Rect
func R(x, y, w, h float32) Rectfunc RectAround(center Vec2, w, h float32) Rectfunc RectBetween(a, b Vec2) Rectfunc (r Rect) Center() Vec2func (r Rect) Clamp(p Vec2) Vec2func (r Rect) Contains(p Vec2) boolfunc (r Rect) Empty() boolfunc (r Rect) Inset(d float32) Rectfunc (r Rect) Intersect(s Rect) Rectfunc (r Rect) Intersects(s Rect) boolfunc (r Rect) Max() Vec2func (r Rect) Min() Vec2func (r Rect) Offset(d Vec2) Rectfunc (r Rect) Scaled(s float32) Rectfunc (r Rect) Size() Vec2func (r Rect) Union(s Rect) Rect
- type Vec2
func V2(x, y float32) Vec2func (a Vec2) Abs() Vec2func (a Vec2) Add(b Vec2) Vec2func (a Vec2) Angle() float32func (a Vec2) Distance(b Vec2) float32func (a Vec2) Dot(b Vec2) float32func (a Vec2) Len() float32func (a Vec2) Lerp(b Vec2, t float32) Vec2func (a Vec2) Max(b Vec2) Vec2func (a Vec2) Min(b Vec2) Vec2func (a Vec2) Mul(s float32) Vec2func (a Vec2) Neg() Vec2func (a Vec2) Norm() Vec2func (a Vec2) Perp() Vec2func (a Vec2) Rotate(angle float32) Vec2func (a Vec2) Sub(b Vec2) Vec2
- type Vec3
func V3(x, y, z float32) Vec3func (a Vec3) Abs() Vec3func (a Vec3) Add(b Vec3) Vec3func (a Vec3) Cross(b Vec3) Vec3func (a Vec3) Distance(b Vec3) float32func (a Vec3) Dot(b Vec3) float32func (a Vec3) Len() float32func (a Vec3) Lerp(b Vec3, t float32) Vec3func (a Vec3) Max(b Vec3) Vec3func (a Vec3) Min(b Vec3) Vec3func (a Vec3) Mul(s float32) Vec3func (a Vec3) Neg() Vec3func (a Vec3) Norm() Vec3func (a Vec3) Project(b Vec3) Vec3func (a Vec3) Reflect(n Vec3) Vec3func (a Vec3) Sub(b Vec3) Vec3func (a Vec3) Vec4(w float32) Vec4
- type Vec4
Functions
Degrees source
func Degrees(rad float32) float32
Degrees converts radians, for showing an angle to a person: the engine's own angles are radians throughout.
Types
type Affine source
type Affine struct{ A, B, C, D, E, F float32 }
Affine is a 2D affine transform: a 2×3 matrix in row-major order,
[A B C] [D E F]
mapping (x, y) to (A·x + B·y + C, D·x + E·y + F). The zero value is not a valid transform; use Identity2.
Identity2 source
func Identity2() Affine
Identity2 is the transform that leaves points where they are.
Rotate2 source
func Rotate2(angle float32) Affine
Rotate2 rotates by angle radians, anticlockwise in a y-up space and clockwise on a y-down screen.
ApplyVec source
func (m Affine) ApplyVec(v Vec2) Vec2
ApplyVec transforms a direction, ignoring translation.
Inverse source
func (m Affine) Inverse() Affine
Inverse returns the transform that undoes m; a singular transform (zero scale) returns the zero Affine.
IsIdentity source
func (m Affine) IsIdentity() bool
IsIdentity reports whether m leaves points unchanged.
Mat4 source
func (m Affine) Mat4() Mat4
Mat4 lifts the transform to a 4×4 matrix acting on the x-y plane.
Mul source
func (m Affine) Mul(n Affine) Affine
Mul composes transforms so that (m.Mul(n)).Apply(p) == m.Apply(n.Apply(p)): n is applied first.
Scale source
func (m Affine) Scale() float32
Scale reports the transform's largest scale factor along any direction, the amount by which it can stretch a length.
TransformRect source
func (m Affine) TransformRect(r Rect) Rect
TransformRect returns the axis-aligned bounds of r's four transformed corners. Negative dimensions and zero-width or zero-height rectangles are treated geometrically, so a transformed line can have nonzero bounds.
type Mat3 source
type Mat3 [9]float32
Mat3 is a 3x3 matrix stored column-major, as Mat4 is: element (row r, column c) is at index c*3+r. It carries rotations and scales without translation, which is what normals need.
type Mat4 source
type Mat4 [16]float32
Mat4 is a 4x4 matrix stored column-major: element (row r, column c) is at index c*4+r, which is the layout WGSL expects in a uniform buffer.
Ortho source
func Ortho(left, right, bottom, top, near, far float32) Mat4
Ortho maps the box [left,right]×[bottom,top]×[near,far] to Vulkan clip space, where bottom maps to clip Y = -1, which is the top of the screen. Ortho2D is the usual way to get screen coordinates with +Y down.
Ortho2D source
func Ortho2D(width, height float32) Mat4
Ortho2D maps pixel coordinates with the origin at the top-left and +Y down onto the screen, with depth from -1 (front) to 1 (back).
Perspective source
func Perspective(fovy, aspect, near, far float32) Mat4
Perspective builds a right-handed projection with depth in [0,1] and +Y up in view space, flipped for Vulkan's +Y-down clip space.
Rotate source
func Rotate(angle float32, axis Vec3) Mat4
Rotate builds a rotation of angle radians about axis.
Scale source
func Scale(v Vec3) Mat4
Scale is the matrix that scales each axis by the matching component of v.
TRS source
func TRS(t Vec3, r Quat, s Vec3) Mat4
TRS composes translation, rotation and scale into one matrix: the product Translate(t) × r.Mat4() × Scale(s), which scales first, then rotates, then translates. It writes the product's entries directly instead of multiplying the three matrices, and gives the same values apart from the sign of zero entries.
Translate source
func Translate(v Vec3) Mat4
Translate is the matrix that moves points by v.
Example
package main
import (
"fmt"
"github.com/matjam/bunyip/lin"
)
func main() {
// Matrices compose right to left: scale first, then move.
m := lin.Translate(lin.V3(10, 0, 0)).Mul(lin.Scale(lin.V3(2, 2, 2)))
fmt.Println(m.MulPoint(lin.V3(1, 1, 1)))
}
{12 2 2}
Decompose source
func (m Mat4) Decompose() (t Vec3, r Quat, s Vec3)
Decompose splits an affine matrix into translation, rotation and scale, assuming it was built as TRS with positive scales.
Inverse source
func (m Mat4) Inverse() Mat4
Inverse returns the inverse, or the identity for a singular matrix.
MulAffine source
func (m Mat4) MulAffine(n Mat4) Mat4
MulAffine returns m × n for two affine matrices, applying n first. To compose placements (translation, rotation and scale, as TRS builds), call it in place of Mul: it skips the products with the constant bottom row and costs less than half as much. Both matrices must have a bottom row of 0, 0, 0, 1; the result then has that bottom row and agrees with Mul to within rounding in the last bit, since the compiler may fuse the multiplies and adds differently in the two. For a projection or any other matrix with a different bottom row, use Mul.
MulPoint source
func (m Mat4) MulPoint(p Vec3) Vec3
MulPoint transforms a point (w = 1) and drops w without perspective division. Use MulVec4 and divide XYZ by W when projecting a point.
NormalMatrix source
func (m Mat4) NormalMatrix() Mat3
NormalMatrix is the inverse transpose of the upper 3x3, which carries normals correctly through non-uniform scales.
Translation source
func (m Mat4) Translation() Vec3
Translation is the position the matrix moves the origin to.
type Quat source
type Quat struct{ X, Y, Z, W float32 }
Quat is a quaternion (X, Y, Z, W) representing a rotation when it has unit length. Use QuatIdentity for no rotation and Norm after repeated composition; the zero quaternion is not a unit quaternion.
AxisAngle source
func AxisAngle(axis Vec3, angle float32) Quat
AxisAngle builds a rotation of angle radians about axis.
Example
package main
import (
"fmt"
"github.com/matjam/bunyip/lin"
)
func main() {
q := lin.AxisAngle(lin.V3(0, 1, 0), lin.Radians(90))
p := q.Rotate(lin.V3(1, 0, 0))
fmt.Printf("%.1f %.1f %.1f\n", p.X, p.Y, p.Z)
}
0.0 0.0 -1.0
FromEuler source
func FromEuler(yaw, pitch, roll float32) Quat
FromEuler builds a rotation from yaw about +Y, pitch about +X and roll about +Z, in radians, applied roll first, then pitch, then yaw: the order a camera or a ship expects.
QuatFromMat4 source
func QuatFromMat4(m Mat4) Quat
QuatFromMat4 extracts the rotation of an orthonormal matrix.
QuatIdentity source
func QuatIdentity() Quat
QuatIdentity is the rotation that leaves vectors unchanged.
QuatLookAt source
func QuatLookAt(forward, up Vec3) Quat
QuatLookAt is the rotation that turns the local -Z axis, the engine's forward, to face along forward with up as near to up as it can be. Zero or parallel vectors give the identity.
AxisAngle source
func (q Quat) AxisAngle() (axis Vec3, angle float32)
AxisAngle returns the unit axis and the angle in radians of the rotation, the inverse of the AxisAngle constructor. The identity gives the +Y axis and zero.
Euler source
func (q Quat) Euler() (yaw, pitch, roll float32)
Euler returns the yaw, pitch and roll that FromEuler would take to make q. Pitch is in [-π/2, π/2]; at the poles yaw and roll share one angle.
type Rect source
type Rect struct{ X, Y, W, H float32 }
Rect is an axis-aligned rectangle: its top-left corner and its size, in whatever units the caller uses (view units for drawing and interface layout, world units for a camera). The zero Rect is empty. Clip rectangles, interface widgets, cameras and nine-slices all use it.
RectAround source
func RectAround(center Vec2, w, h float32) Rect
RectAround makes a Rect of the given size centred on a point.
RectBetween source
func RectBetween(a, b Vec2) Rect
RectBetween makes the Rect spanning two corners, in any order.
Clamp source
func (r Rect) Clamp(p Vec2) Vec2
Clamp moves p to the nearest point inside the rectangle.
Contains source
func (r Rect) Contains(p Vec2) bool
Contains reports whether the point lies inside, the top and left edges included and the bottom and right excluded, so adjacent rectangles do not both claim their shared edge.
Inset source
func (r Rect) Inset(d float32) Rect
Inset shrinks the rectangle by d on every side; a negative d grows it.
Intersect source
func (r Rect) Intersect(s Rect) Rect
Intersect returns the overlap of the rectangles, or an empty Rect at the would-be corner when they do not overlap.
Intersects source
func (r Rect) Intersects(s Rect) bool
Intersects reports whether the rectangles overlap with positive area.
type Vec2 source
type Vec2 struct{ X, Y float32 }
Vec2 is a point or direction in the plane.
Angle source
func (a Vec2) Angle() float32
Angle is the direction of a in radians, measured from +X towards +Y.
Norm source
func (a Vec2) Norm() Vec2
Norm returns the unit vector in a's direction; the zero vector stays zero.
Perp source
func (a Vec2) Perp() Vec2
Perp returns a turned a quarter turn anticlockwise in a y-up space (clockwise on a y-down screen): (-y, x).
type Vec3 source
type Vec3 struct{ X, Y, Z float32 }
Vec3 is a point or direction in space.
Cross source
func (a Vec3) Cross(b Vec3) Vec3
Cross is the cross product, perpendicular to both a and b.
Example
package main
import (
"fmt"
"github.com/matjam/bunyip/lin"
)
func main() {
x, y := lin.V3(1, 0, 0), lin.V3(0, 1, 0)
fmt.Println(x.Cross(y))
fmt.Println(x.Dot(y))
}
{0 0 1}
0
Norm source
func (a Vec3) Norm() Vec3
Norm returns the unit vector in a's direction; the zero vector stays zero.
Project source
func (a Vec3) Project(b Vec3) Vec3
Project returns the part of a that lies along b; a zero b gives zero.
type Vec4 source
type Vec4 struct{ X, Y, Z, W float32 }
Vec4 is a homogeneous point (W 1) or direction (W 0), or a colour.
Source files
affine.go affine_bounds_test.go affine_mat_test.go euler.go example_test.go lin_test.go mat.go mat3.go quat.go rect.go rect_test.go vec.go