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
andy
, i.e.,result = x * y
. dot(x: vecN, y: vecN) -> floatReturns the dot product ofx
andy
, i.e.,result = x[0] * y[0] + x[1] * y[1] + ...
- dot(x: quat, y: quat) -> float
- Returns dot product of
x
andy
, i.e.,x[0] * y[0] + x[1] * y[1] + ...
-
cross
(x: vec3, y: vec3) vec3 Returns the cross product of
x
andy
. cross(x: quat, y: quat) -> quatCompute a cross product.
-
length
(x: float) float Returns the length of
x
, i.e.,abs(x)
. length(x: vecN) -> floatReturns the length ofx
, i.e.,sqrt(x * x)
.- length(x: quat) -> float
- Returns the norm of a quaternion.
-
distance
(p0: float, p1: float) float Returns the distance between
p0
andp1
, i.e.,length(p0 - p1)
. distance(p0: vecN, p1: vecN) -> floatReturns the distance betweenp0
andp1
, i.e.,length(p0 - p1)
.
-
normalize
(x) vecN Returns
x
normalized. ie.x / length(x)
The new vector has the same direction than
x
but with length1
.
-
anglebt
(x, y) float [source] Angle between two vectors
The result is not sensitive to the lengths of x and y
-
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
alongdir
, equivalent todot(vec,dir) / dot(dir,dir) * dir
The result is not sensitive to the length of
dir
-
noproject
(vec, dir) dvec3 [source] Components of
vec
not alongdir
, equivalent tovec - project(vec,dir)
The result is not sensitive to the length of
dir
-
unproject
(vec, dir) dvec3 [source] Return the vector in the given direction as if
vec
was its projection on it, equivalent todot(vec,vec) / dot(vec,dir) * dir
The result is not sensitive to the length of
dir
-
reflect
(I: float, N: float) float - For the incident vector
I
and surface orientationN
, 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 orientationN
, returns the reflection direction:result = I - 2.0 * dot(N, I) * N
.
- For the incident vector
-
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 distanceAlias to
glm.l2Norm
aliasglm.length
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
-
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.
-
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.
-
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
-
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 ofx
andy
using the - floating-point value
a
. The value fora
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 ofx
andy
using the floating-point valuea
. The value fora
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 ofx
andy
using the vectora
. The value fora
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.
- Returns
-
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 ofx
andy
using the floating-point - value
a
. The value fora
is not restricted to the range[0, 1]
. - mix(x: number, y: number, a: bool) -> number
- Returns
y
ifa
isTrue
andx
otherwise. - mix(x: vecN, y: vecN, a: fvecN) -> vecN
- Returns
x * (1.0 - a) + y * a
, i.e., the linear blend ofx
andy
using the floating-point valuea
. The value fora
is not restricted to the range[0, 1]
. - mix(x: vecN, y: vecN, a: bvecN) -> vecN
- For each component index
i
: Returnsy[i]
ifa[i]
isTrue
andx[i]
otherwise. - mix(x: matNxM, y: matNxM, a: fmatNxM) -> matNxM
- Returns
x * (1.0 - a) + y * a
, i.e., the linear blend ofx
andy
using the floating-point valuea
for each component. The value fora
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 ofx
andy
using the floating-point valuea
for each component. The value fora
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.
- Returns
-
hermite
(a, b, x) 3rd order polynomial interpolation a and b are iterable of successive derivatives of a[0] and b[0]
-
step
(edge: number, x: number) float Returns
0.0
ifx < edge
, otherwise it returns1.0
. step(edge: number, x: vecN) -> vecNFor every componentc
ofx
: Returns0.0
ifc < edge
, otherwise it returns1.0
.- step(edge: vecN, x: vecN) -> vecN
- For every index
i
: Returns0.0
ifx[i] < edge[i]
, otherwise it returns1.0
.
-
smoothstep
(edge0: number, edge1: number, x: number) float - Returns
0.0
ifx <= edge0
and1.0
ifx >= edge1
and performs smooth Hermite interpolation - between
0
and1
whenedge0 < 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 ifedge0 >= edge1
. - smoothstep(edge0: number, edge1: number, x: vecN) -> vecN
- Returns
0.0
ifx <= edge0
and1.0
ifx >= edge1
and performs smooth Hermite interpolation between0
and1
whenedge0 < 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 ifedge0 >= edge1
. - smoothstep(edge0: vecN, edge1: vecN, x: vecN) -> vecN
- Returns
0.0
ifx <= edge0
and1.0
ifx >= edge1
and performs smooth Hermite interpolation between0
and1
whenedge0 < 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 ifedge0 >= edge1
.
- Returns
-
clamp
(x: number, minVal: number, maxVal: number) number Returns
min(max(x, minVal), maxVal)
. clamp(x: vecN, minVal: number, maxVal: number) -> vecNReturnsmin(max(x, minVal), maxVal)
for each component inx
using the floating-point valuesminVal
andmaxVal
.- clamp(x: vecN, minVal: vecN, maxVal: vecN) -> vecN
- Returns
min(max(x, minVal), maxVal)
for each component inx
using the floating-point valuesminVal
andmaxVal
.
-
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
Distances
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 overstop
- if
div
is given, it will be the number of intermediate steps betweenstart
andstop
(with linear spacing)
ending:
- if
end
is True, it will stop iterate with valuestop
(or just before) - if
end
is False, it will stop iterating just beforestop
and never withstop
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
thenend
has no influence- if
-
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
ofvec2
as well as a box ofvec3
. 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
-
isvalid
()[source] Return True if the box defines a valid space (min coordinates <= max coordinates)
-
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
-