mathutils - All the basic math types and functions

Most of the names here are coming from the glm module. But the goal is to harvest at one point all the basic math functions and objects that are used all around madcad.

Tip

All the present functions and types are present in the root madcad module.

Most common glm types

All following objects implement the common operators + - * / <> ==

vec3

alias of dvec3

mat3

alias of dmat3x3

mat4

alias of dmat4x4

quat

alias of dquat

All glm types exists with several element types and in several precision:

Prefix Precision
d f64 aka double precisin floating point
f f32 aka for simple precision floating point
i i32 aka integer
i16 16 bits integer
i8 8 bits integer aka byte
u unsigned integer (also declines in u16 and u32)
b bit aka boolean
  • Precision specification is put as prefix: dvec3, fvec3, imat4. Notation without prefix refers to the madcad implementation precision: float64 (prefix ‘d’).
  • Object dimension is put as suffix.

In this documentation, when we refer to a ‘vector’ without explicit type, we obviously mean a vec3 aka. dvec3.

Note

The default glm precision type is float32 (prefix ‘f’). For convenience, these are overriden in madcad to use float64 for a better precision.

Common vector operations

dot(x: float, y: float) float

Returns the dot product of x and y, i.e., result = x * y. dot(x: vecN, y: vecN) -> float

Returns the dot product of x and y, i.e., result = x[0] * y[0] + x[1] * y[1] + ...
dot(x: quat, y: quat) -> float
Returns dot product of x and y, i.e., x[0] * y[0] + x[1] * y[1] + ...
../_images/mathutils-dot.svg
cross(x: vec3, y: vec3) vec3

Returns the cross product of x and y. cross(x: quat, y: quat) -> quat

Compute a cross product.
../_images/mathutils-cross.svg
length(x: float) float

Returns the length of x, i.e., abs(x). length(x: vecN) -> float

Returns the length of x, i.e., sqrt(x * x).
length(x: quat) -> float
Returns the norm of a quaternion.
../_images/mathutils-length.svg
distance(p0: float, p1: float) float

Returns the distance between p0 and p1, i.e., length(p0 - p1). distance(p0: vecN, p1: vecN) -> float

Returns the distance between p0 and p1, i.e., length(p0 - p1).
../_images/mathutils-distance.svg
normalize(x) vecN

Returns x normalized. ie. x / length(x)

The new vector has the same direction than x but with length 1.

anglebt(x, y) float[source]

Angle between two vectors

The result is not sensitive to the lengths of x and y

../_images/mathutils-anglebt.svg
arclength(p1, p2, n1, n2)[source]

Length of an arc between p1 and p2, normal to the given vectors in respective points

project(vec, dir) dvec3[source]

Component of vec along dir, equivalent to dot(vec,dir) / dot(dir,dir) * dir

The result is not sensitive to the length of dir

../_images/mathutils-project.svg
noproject(vec, dir) dvec3[source]

Components of vec not along dir, equivalent to vec - project(vec,dir)

The result is not sensitive to the length of dir

../_images/mathutils-noproject.svg
unproject(vec, dir) dvec3[source]

Return the vector in the given direction as if vec was its projection on it, equivalent to dot(vec,vec) / dot(vec,dir) * dir

The result is not sensitive to the length of dir

../_images/mathutils-unproject.svg
reflect(I: float, N: float) float
For the incident vector I and surface orientation N, returns the reflection direction:
result = I - 2.0 * dot(N, I) * N.
reflect(I: vecN, N: vecN) -> vecN
For the incident vector I and surface orientation N, returns the reflection direction: result = I - 2.0 * dot(N, I) * N.
../_images/mathutils-reflect.svg
perp(v: dvec2) dvec2[source]

Perpendicular vector to the given vector

../_images/mathutils-perp.svg
norm1(x) float

norm L1 ie. abs(x) + abs(y) + abs(z)

Alias to glm.l1Norm

norm2(x) float

norm L2 ie. sqrt(x**2 + y**2 + z**2) the usual distance also known as manhattan distance

Alias to glm.l2Norm alias glm.length

norminf(x) float[source]

norm L infinite ie. max(abs(x), abs(y), abs(z))

Alias to glm.lxNorm

See the glm complete reference

Transformations

transform(*args) dmat4x4[source]

Create an affine transformation matrix.

Supported inputs:
mat4:obviously return it unmodified
float:scale using the given ratio
vec3:translation only
quat, mat3, mat4:
 rotation only
(vec3,vec3), (vec3,mat3), (vec3,quat):
 (o,T) translation and rotation
(vec3,vec3,vec3):
 (x,y,z) base of vectors for rotation
(vec3,vec3,vec3,vec3):
 (o,x,y,z) translation and base of vectors for rotation
translate(v: vec3) mat4x4

Builds a translation 4 x 4 matrix created from a vector of 3 components. translate(v: vec2) -> mat3x3

Builds a translation 3 x 3 matrix created from a vector of 2 components.
translate(m: mat4x4, v: vec3) -> mat4x4
Builds a translation 4 x 4 matrix created from a vector of 3 components. m is the input matrix multiplied by this translation matrix
translate(m: mat3x3, v: vec2) -> mat3x3
Builds a translation 3 x 3 matrix created from a vector of 2 components. m is the input matrix multiplied by this translation matrix
../_images/mathutils-translate.svg
rotate(angle: number, axis: vec3) mat4x4

Builds a rotation 4 x 4 matrix created from an axis vector and an angle. rotate(angle: number) -> mat3x3

Builds a rotation 3 x 3 matrix created from an angle.
rotate(m: mat4x4, angle: number, axis: vec3) -> mat4x4
Builds a rotation 4 x 4 matrix created from an axis vector and an angle. m is the input matrix multiplied by this translation matrix
rotate(m: mat3x3, angle: number) -> mat3x3
Builds a rotation 3 x 3 matrix created from an angle. m is the input matrix multiplied by this translation matrix
rotate(v: vec2, angle: float) -> vec2
Rotate a two dimensional vector.
rotate(v: vec3, angle: float, normal: vec3) -> vec3
Rotate a three dimensional vector around an axis.
rotate(v: vec4, angle: float, normal: vec3) -> vec4
Rotate a four dimensional vector around an axis.
rotate(q: quat, angle: float, axis: vec3) -> quat
Rotates a quaternion from a vector of 3 components axis and an angle.
../_images/mathutils-rotate.svg
scaledir(dir, factor=None) dmat3x3[source]

Return a mat3 scaling in the given direction, with the given factor (1 means original scale) If factor is None, the length of dir is used, but it can leads to precision loss on direction when too small.

../_images/mathutils-scaledir.svg
scale(v: vec3) mat4x4

Builds a scale 4 x 4 matrix created from 3 scalars. scale(v: vec2) -> mat3x3

Builds a scale 3 x 3 matrix created from a vector of 2 components.
scale(m: mat4x4, v: vec3) -> mat4x4
Builds a scale 4 x 4 matrix created from 3 scalars. m is the input matrix multiplied by this translation matrix
scale(m: mat3x3, v: vec2) -> mat3x3
Builds a scale 3 x 3 matrix created from a vector of 2 components. m is the input matrix multiplied by this translation matrix
../_images/mathutils-scale.svg
rotatearound(angle, *args) dmat4x4[source]

Return a transformation matrix for a rotation around an axis

rotatearound(angle, axis) rotatearound(angle, origin, dir)

dirbase(dir, align=dvec3(1, 0, 0))[source]

Return a base using the given direction as z axis (and the nearer vector to align as x)

transpose(x: matNxM) matMxN

Returns the transposed matrix of x.

inverse(m: matSxS) matSxS

Return the inverse of a squared matrix. inverse(q: quat) -> quat

Return the inverse of a quaternion.
affineInverse(m: matSxS) matSxS

Fast matrix inverse for affine matrix.

angle(x: quat) float

Returns the quaternion rotation angle.

axis(x: quat) vec3

Returns the q rotation axis.

angleAxis(angle: float, axis: vec3) quat

Build a quaternion from an angle and a normalized axis.

lerp(x: float, y: float, a: float) float
Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the
floating-point value a. The value for a is not restricted to the range [0, 1].
lerp(x: vecN, y: vecN, a: float) -> vecN
Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1].
lerp(x: vecN, y: vecN, a: vecN) -> vecN
Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the vector a. The value for a is not restricted to the range [0, 1].
lerp(x: quat, y: quat, a: float) -> quat
Linear interpolation of two quaternions. The interpolation is oriented.
slerp(x: quat, y: quat, a: float) quat
Spherical linear interpolation of two quaternions. The interpolation always take the short
path and the rotation is performed at constant speed.
slerp(x: vec3, y: vec3, a: float) -> vec3
Returns Spherical interpolation between two vectors.

Scalar functions

mix(x: number, y: number, a: float) number
Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point
value a. The value for a is not restricted to the range [0, 1].
mix(x: number, y: number, a: bool) -> number
Returns y if a is True and x otherwise.
mix(x: vecN, y: vecN, a: fvecN) -> vecN
Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1].
mix(x: vecN, y: vecN, a: bvecN) -> vecN
For each component index i: Returns y[i] if a[i] is True and x[i] otherwise.
mix(x: matNxM, y: matNxM, a: fmatNxM) -> matNxM
Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a for each component. The value for a is not restricted to the range [0, 1].
mix(x: matNxM, y: matNxM, a: float) -> matNxM
Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a for each component. The value for a is not restricted to the range [0, 1].
mix(x: quat, y: quat, a: float) -> quat
Spherical linear interpolation of two quaternions. The interpolation is oriented and the rotation is performed at constant speed. For short path spherical linear interpolation, use the slerp function.
../_images/mathutils-mix.svg
hermite(a, b, x)

3rd order polynomial interpolation a and b are iterable of successive derivatives of a[0] and b[0]

../_images/mathutils-hermite.svg
step(edge: number, x: number) float

Returns 0.0 if x < edge, otherwise it returns 1.0. step(edge: number, x: vecN) -> vecN

For every component c of x: Returns 0.0 if c < edge, otherwise it returns 1.0.
step(edge: vecN, x: vecN) -> vecN
For every index i: Returns 0.0 if x[i] < edge[i], otherwise it returns 1.0.
../_images/mathutils-step.svg
smoothstep(edge0: number, edge1: number, x: number) float
Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth Hermite interpolation
between 0 and 1 when edge0 < x < edge1. This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to : t = clamp((x - edge0) / (edge1 - edge0), 0, 1) return t * t * (3 - 2 * t) Results are undefined if edge0 >= edge1.
smoothstep(edge0: number, edge1: number, x: vecN) -> vecN
Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth Hermite interpolation between 0 and 1 when edge0 < x < edge1. This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to : t = clamp((x - edge0) / (edge1 - edge0), 0, 1) return t * t * (3 - 2 * t) Results are undefined if edge0 >= edge1.
smoothstep(edge0: vecN, edge1: vecN, x: vecN) -> vecN
Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth Hermite interpolation between 0 and 1 when edge0 < x < edge1. This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to : t = clamp((x - edge0) / (edge1 - edge0), 0, 1) return t * t * (3 - 2 * t) Results are undefined if edge0 >= edge1.
../_images/mathutils-smoothstep.svg
clamp(x: number, minVal: number, maxVal: number) number

Returns min(max(x, minVal), maxVal). clamp(x: vecN, minVal: number, maxVal: number) -> vecN

Returns min(max(x, minVal), maxVal) for each component in x using the floating-point values minVal and maxVal.
clamp(x: vecN, minVal: vecN, maxVal: vecN) -> vecN
Returns min(max(x, minVal), maxVal) for each component in x using the floating-point values minVal and maxVal.
../_images/mathutils-clamp.svg
intri_smooth(pts, ptangents, a, b)[source]

Cubic interpolation over a triangle, edges are guaranteed to fit an interpol2 curve using the edge tangents

Note

If the tangents lengths are set to the edge lengths, that version gives a result that only blends between the curved edges, a less bulky result than intri_sphere

intri_sphere(pts, ptangents, a, b, etangents=None)[source]

Cubic interpolation over a triangle (2 dimension space), edges are guaranteed to fit an interpol2 curve using the edge tangents

Note

If the tangents lengths are set to the edge lengths, that version gives a result close to a sphere surface

intri_parabolic(pts, ptangents, a, b, etangents=None)[source]

Quadratic interpolation over a triangle, edges are NOT fitting an interpol2 curve

Distances

distance_pa(pt, axis)[source]

Point - axis distance

distance_pe(pt, edge)[source]

Point - edge distance

distance_aa(a1, a2)[source]

Axis - axis distance

distance_ae(axis, edge)[source]

Axis - edge distance

Constants

NUMPREC

Numeric precision of a unit float (using the default precision)

COMPREC

unit complement of NUMPREC for convenience: 1 - NUMPREC

Localy defined data types

linrange(start, stop=None, step=None, div=0, end=True)[source]

Yield successive intermediate values between start and stop

stepping:

  • if step is given, it will be the amount between raised value until it gets over stop
  • if div is given, it will be the number of intermediate steps between start and stop (with linear spacing)

ending:

  • if end is True, it will stop iterate with value stop (or just before)
  • if end is False, it will stop iterating just before stop and never with stop

Example

>>> list(linrange(5, -5, div=1))
[5, 0, -5]
>>> list(linrange(5, -5, div=10)

Note

If step is given and is not a multiple of stop-start then end has no influence

class Box(min=None, max=None, center=dvec3(0, 0, 0), width=dvec3(-inf, -inf, -inf))[source]

This class describes a box always orthogonal to the base axis, used as convex for area delimitations

This class is independent from the dimension or number precision of the used vectors. You can for instance have a Box of vec2 as well as a box of vec3. However boxes with different vector types cannot interperate.

min

vector of minimum coordinates of the box (usually bottom left corner)

max

vector of maximum coordinates of the box (usually top right corner)

property center: dvec3

Mid coordinates of the box

property width: dvec3

Diagonal vector of the box

corners() [vec3][source]

Create a list of the corners of the box

volume() float[source]

Volume inside

isvalid()[source]

Return True if the box defines a valid space (min coordinates <= max coordinates)

isempty()[source]

Return True if the box contains a non null volume

contain(point)[source]

Return True if the given point is inside or on the surface of the box

inside(point)[source]

Return True if the given point is strictly inside the box

intersection(other) Box[source]

Return a box for the volume common to the current and the given box

Example

>>> Box(vec2(-1,2), vec2(2,3)) .intersection(Box(vec3(1,-4), vec3(2,8)))
Box(vec2(1,2), vec3(2,3))
union(other) Box[source]

Return a box containing the current and the given box (or point)

Example

>>> Box(vec2(1,2), vec2(2,3)) .union(vec3(1,4))
Box(vec2(1,2), vec2(2,4))
>>> Box(vec2(1,2), vec2(2,3)) .union(Box(vec3(1,-4), vec3(2,8)))
Box(vec2(1,-4), vec3(2,8))
intersection_update(other) self[source]

Reduce the volume of the current box to the intersection between the 2 boxes

union_update(other) self[source]

Extend the volume of the current box to bound the given point or box

transform(trans) Box[source]

Box bounding the current one in a transformed space