Geometry¶
The geometry kernel measures every length in base units of 0.4 mm and compares only integers.
units
¶
Exact integer units for LEGO® System geometry.
bricky measures every length in base units of 0.4 mm, the largest length that divides every System dimension exactly. Positions are therefore integers, and every check compares integers.
Agents work in studs (x and y) and plates (z), never in base units. The helpers below convert both ways and refuse values that land off the grid.
STUD_HEIGHT
module-attribute
¶
STUD_HEIGHT: Final = 4
Stud height: 1.7 mm in reality, rounded down to 1.6 mm to stay on the grid.
studs
¶
Convert a horizontal length in studs to base units.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the length is not a whole number of base units. |
plates
¶
Convert a height in plates to base units.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the height is not a whole number of base units. |
geometry
¶
Integer geometry: vectors, the 24 grid rotations, poses, boxes and convex solids.
Every element takes one of the 24 rotations that map grid axes onto grid axes. Each rotation is a signed permutation, so all arithmetic stays exact. Boxes stay axis-aligned under every rotation, which reduces most collision tests to a handful of integer comparisons. The body of a slope, a round part or any other part that boxes cannot describe is a union of convex solids with integer corners. Every face of such a solid lies in a plane with an integer normal, and separating axes decide exactly whether two solids overlap.
ALIASES
module-attribute
¶
Short names for the four rotations about the vertical axis.
The rotations run counter-clockwise, seen from above.
Vector
dataclass
¶
Rotation
dataclass
¶
A proper rotation mapping grid axes onto grid axes: one of 24.
A rotation's name gives the images of the local x and y axes: "+x+y" is the
identity, and "+y-x" rotates a part 90° counter-clockwise seen from above.
:data:ALIASES gives short names to the four rotations about the vertical axis.
z_axis
class-attribute
instance-attribute
¶
Where the rotation takes the z axis: the cross product of the other two.
parse
classmethod
¶
Parse a rotation name such as "+y-x" or an alias such as "R90".
Raises:
| Type | Description |
|---|---|
ValueError
|
If the text names no rotation. |
Pose
dataclass
¶
Box
dataclass
¶
A half-open, axis-aligned box [min, max) with integer corners.
vertices
property
¶
The eight corners.
Bit 1 of a corner's index picks high x, bit 2 high y and bit 4 high z.
faces
property
¶
Each face's indices into :attr:vertices, counter-clockwise from outside.
directions
property
¶
The distinct directions of the edges: the three grid axes.
spanning
classmethod
¶
Return the box with opposite corners a and b, in any order.
bounding
classmethod
¶
Return the smallest box that contains all the given boxes.
Raises:
| Type | Description |
|---|---|
ValueError
|
If no boxes are given. |
extent
¶
Return the minimum and maximum of axis.dot(vertex) over the vertices.
contains
¶
Return whether a point lies in the box.
Low faces count as inside, and high faces as outside.
overlaps
¶
Return whether the boxes share positive volume.
Faces that only touch do not count.
intersection
¶
Return the box both boxes share, or None if they share no volume.
Convex
dataclass
¶
A convex solid with integer corners, such as the body of a slope.
Each face lists corner indices counter-clockwise seen from outside. The solid keeps every face's plane as an integer outward normal and offset, so the tests for a point inside and for an overlap never round.
Raises:
| Type | Description |
|---|---|
ValueError
|
If a face has fewer than three corners, is not flat or faces inward, or the solid is concave. |
directions
class-attribute
instance-attribute
¶
The distinct directions of the edges, each as a primitive vector.
prism
classmethod
¶
prism(
polygon: Sequence[tuple[int, int]],
axis: Literal["x", "y", "z"],
start: int,
end: int,
) -> Convex
Extrude a convex polygon along an axis, from start to end.
The polygon runs counter-clockwise in its plane, in coordinates (a, b)
chosen so that a, b and the axis are right-handed: (x, y) along z, (y,
z) along x, and (z, x) along y.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the polygon is not convex and counter-clockwise, or ``start
|
transformed
¶
Return the solid placed by a pose.
Proper rotations keep the faces wound outward.
contains
¶
Return whether a point lies in the solid.
A point on a face counts as inside when the face looks toward lower coordinates
(its normal's first nonzero component is negative) and outside otherwise, as
with :meth:Box.contains, so solids that share a face never both contain a
point on it.
overlaps
¶
overlaps(a: Solid, b: Solid) -> bool
Return whether two solids share positive volume.
Touching faces or edges do not count. The test uses separating axes. Two convex solids keep their insides apart exactly when some axis, among their face normals and the cross products of their edge directions, puts them on opposite sides, touching at most.