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 implements the common operators + - * / <> ==

vec3

alias of glm.dvec3

mat3

alias of glm.dmat3x3

mat4

alias of glm.dmat4x4

quat

alias of glm.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

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)

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

project(vec, dir) glm.dvec3

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) glm.dvec3

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) glm.dvec3

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
perp(v: glm.dvec2) glm.dvec2

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

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

Alias to glm.lxNorm

See the glm complete reference

Transformations

transform(*args) glm.dmat4x4

create an affine transformation matrix.

supported inputs:
mat4

obviously returns 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

dirbase(dir, align=dvec3(1, 0, 0))

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

scaledir(dir, factor=None) glm.dmat3x3

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.

rotatearound(angle, *args) glm.dmat4x4

return a transformation matrix for a rotation around an axis

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

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

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 lenghts, 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)

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 lenghts, that version gives a result close to a sphere surface

intri_parabolic(pts, ptangents, a, b, etangents=None)

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

Distances

distance_pa(pt, axis)

point - axis distance

distance_pe(pt, edge)

point - edge distance

distance_aa(a1, a2)

axis - axis distance

distance_ae(axis, edge)

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

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

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: glm.dvec3

mid coordinates of the box

property width: glm.dvec3

diagonal vector of the box

corners() [vec3]

create a list of the corners of the box

volume() float

volume inside

isvalid()

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

isempty()

return True if the box contains a non null volume

contain(point)

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

inside(point)

return True if the given point is strictly inside the box

intersection(other) madcad.mathutils.Box

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) madcad.mathutils.Box

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

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

union_update(other) self

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

transform(trans) madcad.mathutils.Box

box bounding the current one in a transformed space