kumiki.rule¶
Flat import path
kumiki/__init__.py re-exports everything on this page via from kumiki import *, so every name below is also available directly as kumiki.scalar -- you do not need to import from the submodule path shown in the heading above.
kumiki.rule
¶
The library uses RHS coordinates with Z facing up, Y facing north, and X facing east. The main class is the Orientation class which stores rotation in 2 components.
Coordinate System (RHS):
(up) Z ^ ^ Y (north) | / |/ +-----> X (east) / / v -Y (south)
RHS = Right Hand System - X-axis: points east - Y-axis: points north - Z-axis: points up - Thumb = X, Index = Y, Middle = Z
All numeric values in this library are plain Python floats. Users declare
measurements with the helpers below (scalar, inches, mm, degrees, ...)
for convenience and unit-conversion, but the values themselves are ordinary
floats -- there is no lazy/symbolic expression tree, and no separate
"numeric mode" to switch between.
Matrix
¶
Immutable: _data is set once at construction and never written to
again (enforced both by omitting __setitem__ and by marking the
underlying numpy buffer read-only), matching the frozen dataclasses
(Transform/Orientation/Axis) that hold Matrix-typed fields elsewhere in
this module -- without this, some_frozen_transform.position[0] = 5
would silently succeed despite the dataclass being frozen.
Source code in kumiki/rule.py
det
¶
cross
¶
equals
¶
equals(other: Matrix, tolerance: Optional[float] = None) -> bool
Elementwise approximate equality (tolerates float noise from trig/sqrt).
Source code in kumiki/rule.py
norm
¶
tolist
¶
__getitem__
¶
Source code in kumiki/rule.py
__iter__
¶
__len__
¶
__mul__
¶
__rmul__
¶
__truediv__
¶
__add__
¶
__radd__
¶
__sub__
¶
__rsub__
¶
__neg__
¶
__eq__
¶
Transform
dataclass
¶
Transform(position: V3, orientation: Orientation)
Represents a 3D transformation with position and orientation. Encapsulates both translation and rotation for objects in 3D space.
identity
classmethod
¶
identity() -> Transform
Create an identity transform at origin with identity orientation.
local_to_global
¶
Convert a point from local coordinates to global world coordinates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
local_point
|
V3
|
A point in local coordinates |
required |
Returns:
| Type | Description |
|---|---|
V3
|
The same point in global world coordinates |
Source code in kumiki/rule.py
global_to_local
¶
Convert a point from global world coordinates to local coordinates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
global_point
|
V3
|
A point in global world coordinates |
required |
Returns:
| Type | Description |
|---|---|
V3
|
The same point in local coordinates |
Source code in kumiki/rule.py
numeric_local_to_global
¶
Convert local to global using numeric (Float) math. For hot paths like CSG.
numeric_global_to_local
¶
Convert global to local using numeric (Float) math. For hot paths like CSG.
to_global_transform
¶
Convert this transform to global coordinates relative to a parent transform.
invert
¶
invert() -> Transform
Return the inverse of this transform.
For a transform T that converts local to global (global = T * local), the inverse converts global to local (local = T^-1 * global).
Source code in kumiki/rule.py
__mul__
¶
Compose two transforms: result = self * other.
This applies other first, then self. Equivalent to: global = self.local_to_global(other.local_to_global(local))
Source code in kumiki/rule.py
to_local_transform
¶
Convert this transform to local coordinates relative to a parent transform.
rotate_around_axis
¶
Rotate this transform counterclockwise around an axis and return the new transform.
The axis can be positioned anywhere in space (not just through the origin). Uses Rodrigues' rotation formula after translating to make the axis pass through origin.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axis
|
Axis
|
Axis with position and direction to rotate around |
required |
radians
|
Numeric
|
Angle to rotate in radians (counterclockwise when looking along axis direction) |
required |
Returns:
| Type | Description |
|---|---|
Transform
|
New Transform with rotated position and orientation |
Source code in kumiki/rule.py
Comparison
¶
Bases: Enum
Enum for safe comparison operations
Orientation
dataclass
¶
Represents a 3D rotation using a 3x3 rotation matrix. I guess we never slerp and don't care about memory usage so apparently we're using matrices to implement this class.
matrix
class-attribute
instance-attribute
¶
__post_init__
¶
Convert to Matrix and validate that the matrix is 3x3.
Source code in kumiki/rule.py
multiply
¶
multiply(other: Orientation) -> Orientation
Multiply this orientation with another orientation. Returns a new Orientation representing the combined rotation.
Source code in kumiki/rule.py
invert
¶
invert() -> Orientation
Return the inverse of this orientation. For rotation matrices, the inverse is the transpose.
flip
¶
flip(flip_x: bool = False, flip_y: bool = False, flip_z: bool = False) -> Orientation
Return the orientation with the given axes flipped.
Source code in kumiki/rule.py
__mul__
¶
__mul__(other: Orientation) -> Orientation
__repr__
¶
rotate_right
classmethod
¶
rotate_right() -> Orientation
Rotate right: +X axis rotates to -Y axis (clockwise around Z)
rotate_left
classmethod
¶
rotate_left() -> Orientation
Rotate left: +X axis rotates to +Y axis (counterclockwise around Z)
from_angle_axis
classmethod
¶
from_angle_axis(radians: Numeric, axis: Direction3D) -> Orientation
Create an orientation from an angle-axis rotation (Rodrigues' formula).
Source code in kumiki/rule.py
identity
staticmethod
¶
identity() -> Orientation
from_z_and_y
staticmethod
¶
from_z_and_y(z_direction: Direction3D, y_direction: Direction3D) -> Orientation
Create an Orientation from z and y direction vectors. Computes x = y × z to complete the right-handed coordinate system.
Source code in kumiki/rule.py
from_z_and_x
staticmethod
¶
from_z_and_x(z_direction: Direction3D, x_direction: Direction3D) -> Orientation
Create an Orientation from z and x direction vectors. Computes y = z × x to complete the right-handed coordinate system.
Source code in kumiki/rule.py
from_x_and_y
staticmethod
¶
from_x_and_y(x_direction: Direction3D, y_direction: Direction3D) -> Orientation
Create an Orientation from x and y direction vectors. Computes z = x × y to complete the right-handed coordinate system.
Source code in kumiki/rule.py
from_axis_angle
staticmethod
¶
from_axis_angle(axis: Direction3D, radians: Numeric) -> Orientation
Create an Orientation representing a rotation around an axis by an angle. Uses Rodrigues' rotation formula.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axis
|
Direction3D
|
Direction vector to rotate around (will be normalized) |
required |
radians
|
Numeric
|
Angle to rotate in radians |
required |
Returns:
| Type | Description |
|---|---|
Orientation
|
Orientation object representing the rotation |
Source code in kumiki/rule.py
from_euleryZYX
staticmethod
¶
from_euleryZYX(yaw: Numeric, pitch: Numeric, roll: Numeric) -> Orientation
Create an Orientation from Euler angles using ZYX rotation sequence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
yaw
|
Numeric
|
Rotation around Z-axis (radians) |
required |
pitch
|
Numeric
|
Rotation around Y-axis (radians) |
required |
roll
|
Numeric
|
Rotation around X-axis (radians) |
required |
Returns:
| Type | Description |
|---|---|
Orientation
|
Orientation object with combined rotation matrix |
The rotation sequence is: 1. Yaw (Z-axis rotation) 2. Pitch (Y-axis rotation) 3. Roll (X-axis rotation)
Source code in kumiki/rule.py
facing_west
staticmethod
¶
facing_west() -> Orientation
Horizontal timber with top face up. This is the IDENTITY orientation.
- Length: +X (local) = -X (west) in global
- Width: +Y (local) = -Y (south) in global
- Facing: +Z (up)
Source code in kumiki/rule.py
facing_east
staticmethod
¶
facing_east() -> Orientation
Horizontal timber with top face up. 180° rotation around Z axis from facing_west.
- Length: +X (local) = +X (east) in global
- Width: +Y (local) = +Y (north) in global
- Facing: +Z (up)
Source code in kumiki/rule.py
facing_north
staticmethod
¶
facing_north() -> Orientation
Horizontal timber with top face up. 90° counterclockwise rotation around Z axis from facing_west.
- Length: +X (local) = +Y (north) in global
- Width: +Y (local) = -X (west) in global
- Facing: +Z (up)
Source code in kumiki/rule.py
facing_south
staticmethod
¶
facing_south() -> Orientation
Horizontal timber with top face up. 90° clockwise rotation around Z axis from facing_west.
- Length: +X (local) = -Y (south) in global
- Width: +Y (local) = +X (east) in global
- Facing: +Z (up)
Source code in kumiki/rule.py
pointing_up
staticmethod
¶
pointing_up() -> Orientation
Vertical timber with LENGTH pointing upward (+Z). This is the same as pointing_forward.
- Length (local +X) → +Z (up) in global
- Width (local +Y) → +Y (north) in global
- Facing (local +Z) → -X (west) in global
Source code in kumiki/rule.py
pointing_down
staticmethod
¶
pointing_down() -> Orientation
Vertical timber with LENGTH pointing downward (-Z).
- Length (local +X) → -Z (down) in global
- Width (local +Y) → +Y (north) in global
- Facing (local +Z) → +X (east) in global
Source code in kumiki/rule.py
pointing_forward
staticmethod
¶
pointing_forward() -> Orientation
Vertical timber with LENGTH pointing upward (+Z). Identical to pointing_up.
- Length (local +X) → +Z (up) in global
- Width (local +Y) → +Y (north) in global
- Facing (local +Z) → -X (west) in global
Source code in kumiki/rule.py
pointing_backward
staticmethod
¶
pointing_backward() -> Orientation
Vertical timber with LENGTH pointing upward (+Z), rotated 180° from pointing_forward.
- Length (local +X) → +Z (up) in global
- Width (local +Y) → -Y (south) in global
- Facing (local +Z) → +X (east) in global
Source code in kumiki/rule.py
pointing_left
staticmethod
¶
pointing_left() -> Orientation
Vertical timber with LENGTH pointing upward (+Z), rotated 90° CCW from pointing_forward.
- Length (local +X) → +Z (up) in global
- Width (local +Y) → -X (west) in global
- Facing (local +Z) → -Y (south) in global
Source code in kumiki/rule.py
pointing_right
staticmethod
¶
pointing_right() -> Orientation
Vertical timber with LENGTH pointing upward (+Z), rotated 90° CW from pointing_forward.
- Length (local +X) → +Z (up) in global
- Width (local +Y) → +X (east) in global
- Facing (local +Z) → +Y (north) in global
Source code in kumiki/rule.py
scalar
¶
Create a float scalar value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
numerator
|
The numerator (can be int, float, or str) |
required | |
denominator
|
The denominator (default=1) |
1
|
Returns:
| Type | Description |
|---|---|
float
|
float value |
Examples:
scalar(3) # 3.0 scalar(1, 2) # 0.5 scalar(2.5) # 2.5 scalar("1.5") # 1.5 from string scalar("1/32") # Parses fraction string
Source code in kumiki/rule.py
sqrt
¶
Source code in kumiki/rule.py
simplify
¶
No-op: floats need no symbolic simplification. Kept so old call sites
(mostly simplify(a - b) == 0-style exactness checks) still parse; see
safe_equality_test/safe_zero_test for the epsilon-based replacement.
Source code in kumiki/rule.py
prune
¶
giraffe_evalf
¶
giraffe_simplify
¶
giraffe_compare
¶
giraffe_compare(a, b, comparison: Comparison, collapse_mode=None, eps: Optional[float] = None) -> bool
Compare two values: evaluates a - b and applies comparison against zero.
eps overrides the default comparison tolerance for this one call.
Examples:
giraffe_compare(x, y, Comparison.GT) # x > y ? giraffe_compare(x, 0, Comparison.EQ) # x == 0 ?
Source code in kumiki/rule.py
giraffe_dot_product
¶
giraffe_transform_vector
¶
giraffe_normalize_vector
¶
create_v2
¶
create_v3
¶
cross_product
¶
radians
¶
Identity function for angles already in radians. Use this to make it explicit that an angle is in radians.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
angle
|
Numeric
|
Angle value in radians |
required |
Returns:
| Type | Description |
|---|---|
Numeric
|
The same angle value (unchanged) |
Examples:
radians(pi / 2) # 90 degrees in radians radians(pi / 4) # 45 degrees in radians
Source code in kumiki/rule.py
degrees
¶
Convert an angle from degrees to radians.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
angle
|
Numeric
|
Angle value in degrees |
required |
Returns:
| Type | Description |
|---|---|
Numeric
|
Angle value in radians |
Examples:
degrees(90) # 90 degrees = pi/2 radians degrees(45) # 45 degrees = pi/4 radians degrees(180) # 180 degrees = pi radians
Source code in kumiki/rule.py
inches
¶
Create a measurement in meters from inches.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
numerator
|
The numerator (can be int, float, or str) |
required | |
denominator
|
The denominator (default=1) |
1
|
Returns:
| Type | Description |
|---|---|
|
float value in meters |
Examples:
inches(1, 32) # 1/32 inch inches(4) # 4 inches inches(3.5) # 3.5 inches inches("1.5") # 1.5 inches from string inches("1/32") # Parses fraction string
Source code in kumiki/rule.py
feet
¶
Create a measurement in meters from feet.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
numerator
|
The numerator (can be int, float, or str) |
required | |
denominator
|
The denominator (default=1) |
1
|
Returns:
| Type | Description |
|---|---|
|
float value in meters |
Examples:
feet(8) # 8 feet feet(1, 2) # 1/2 foot feet(6.5) # 6.5 feet
Source code in kumiki/rule.py
mm
¶
Create a measurement in meters from millimeters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
numerator
|
The numerator (can be int, float, or str) |
required | |
denominator
|
The denominator (default=1) |
1
|
Returns:
| Type | Description |
|---|---|
|
float value in meters |
Examples:
mm(90) # 90 millimeters mm(1, 2) # 1/2 millimeter mm(25.4) # 25.4 millimeters
Source code in kumiki/rule.py
cm
¶
Create a measurement in meters from centimeters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
numerator
|
The numerator (can be int, float, or str) |
required | |
denominator
|
The denominator (default=1) |
1
|
Returns:
| Type | Description |
|---|---|
|
float value in meters |
Examples:
cm(9) # 9 centimeters cm(1, 2) # 1/2 centimeter cm(2.54) # 2.54 centimeters
Source code in kumiki/rule.py
m
¶
Create a measurement in meters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
numerator
|
The numerator (can be int, float, or str) |
required | |
denominator
|
The denominator (default=1) |
1
|
Returns:
| Type | Description |
|---|---|
|
float value in meters |
Examples:
m(1) # 1 meter m(1, 2) # 1/2 meter m(2.5) # 2.5 meters
Source code in kumiki/rule.py
shaku
¶
Create a measurement in meters from shaku (尺). Traditional Japanese carpentry unit.
1 shaku ≈ 303.03 mm (exactly 10/33 meters)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
numerator
|
The numerator (can be int, float, or str) |
required | |
denominator
|
The denominator (default=1) |
1
|
Returns:
| Type | Description |
|---|---|
|
float value in meters |
Examples:
shaku(1) # 1 shaku shaku(3, 2) # 3/2 shaku (1.5 shaku) shaku(2.5) # 2.5 shaku
Source code in kumiki/rule.py
sun
¶
Create a measurement in meters from sun (寸). Traditional Japanese carpentry unit.
1 sun = 1/10 shaku ≈ 30.303 mm
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
numerator
|
The numerator (can be int, float, or str) |
required | |
denominator
|
The denominator (default=1) |
1
|
Returns:
| Type | Description |
|---|---|
|
float value in meters |
Examples:
sun(1) # 1 sun sun(5) # 5 sun sun(1, 2) # 1/2 sun
Source code in kumiki/rule.py
bu
¶
Create a measurement in meters from bu (分). Traditional Japanese carpentry unit.
1 bu = 1/10 sun = 1/100 shaku ≈ 3.0303 mm
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
numerator
|
The numerator (can be int, float, or str) |
required | |
denominator
|
The denominator (default=1) |
1
|
Returns:
| Type | Description |
|---|---|
|
float value in meters |
Examples:
bu(1) # 1 bu bu(5) # 5 bu bu(1, 2) # 1/2 bu
Source code in kumiki/rule.py
safe_zero_test
¶
Test if a value is approximately zero, within eps (default EPSILON_GENERIC).
safe_equality_test
¶
Test if two values are approximately equal, within eps (default EPSILON_GENERIC).
safe_zero_test_sq
¶
Test whether a SQUARED quantity is approximately zero.
Takes a LINEAR tolerance and squares it internally, so eps means the same thing here as everywhere else in the library: a distance in model units, never a distance squared.
safe_zero_test_sq(dx * dx + dy * dy, eps) # is the distance ~0?
Use this rather than safe_zero_test wherever the value under test is a square. Passing a squared value to safe_zero_test compares it against a linear tolerance, which sounds harmless and is not: at eps=5e-4 it treats any length below 22mm as zero. That has been the shape of two real bugs here already -- polygon edges declared degenerate, and pick tolerances meaning millimetres on one primitive and centimetres on another.
Source code in kumiki/rule.py
are_vectors_parallel
¶
Check if two vectors are parallel.
For normalized vectors: dot product ≈ ±1 means parallel
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vector1
|
Matrix
|
First direction vector |
required |
vector2
|
Matrix
|
Second direction vector |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if |abs(dot_product) - 1| is approximately zero (vectors are parallel) |
Source code in kumiki/rule.py
are_vectors_perpendicular
¶
Check if two vectors are perpendicular.
For any vectors: dot product ≈ 0 means perpendicular
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vector1
|
Matrix
|
First direction vector |
required |
vector2
|
Matrix
|
Second direction vector |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if dot_product is approximately zero (vectors are perpendicular) |