Skip to content

geomotif.motifs.solids

Polyhedra, flattened onto the page.

Three dimensions reach the plotter the only way they can: as a wireframe. A solid here is a list of corners in space and a rule for which of them are joined; :class:Projection turns that into two dimensions, and the rest is the segment machinery every other graph motif already uses.

The rule for which corners are joined is the same one for all six regular and semi-regular solids in this module: join every pair of corners that are as close together as any pair gets. On a shape whose corners are all alike that is exactly its edge set, so the whole catalog below is six tables of numbers and nothing else. :class:Polyhedron is for the shapes that are not like that, and takes its edges as given.

Nothing is hidden. A wireframe drawn complete is what a plotter can draw and what the eye can read as a solid seen through -- and it is also, not by accident, what makes :class:~geomotif.motifs.illusions.NeckerCube ambiguous.

Classes:

Name Description
Projection

How a corner in space becomes a point on the page.

PolyhedronBase

Base for a solid: corners in space, joined and flattened onto the page.

Tetrahedron

Four triangles: the simplest solid there is, and its own dual.

Cube

Six squares. Dual to the octahedron, and the one everybody can check.

Octahedron

Eight triangles: a corner of the cube's every face, joined up.

Dodecahedron

Twelve pentagons, built on a cube and the golden ratio.

Icosahedron

Twenty triangles: three golden rectangles at right angles to each other.

TruncatedIcosahedron

The football: twelve pentagons and twenty hexagons.

Polyhedron

Any solid you like: your corners, your edges.

Projection dataclass

Projection(kind: View = 'isometric', yaw: float = 0.0, pitch: float = 0.0, roll: float = 0.0, distance: float = 3.0)

How a corner in space becomes a point on the page.

Parameters:

Name Type Description Default
kind str

"isometric" for the draughtsman's view, in which the three axes leave a corner at equal angles; "orthographic" for a straight drop of the depth, which is what makes a cube read as a square until you turn it; "perspective" for a view from a finite distance, in which the far side of the solid comes out smaller.

'isometric'
yaw float

Extra turns applied after the base orientation: about the vertical, about the horizontal, and about the line of sight.

0.0
pitch float

Extra turns applied after the base orientation: about the vertical, about the horizontal, and about the line of sight.

0.0
roll float

Extra turns applied after the base orientation: about the vertical, about the horizontal, and about the line of sight.

0.0
distance float

How far the eye is from the middle, in circumradii. Only "perspective" uses it, and it must be greater than 1 or the eye would be inside the solid.

3.0

Methods:

Name Description
oriented

Return vertex turned into the view's own frame, still in space.

oriented

oriented(vertex: Vertex) -> Vertex

Return vertex turned into the view's own frame, still in space.

Source code in src/geomotif/motifs/solids.py
def oriented(self, vertex: Vertex) -> Vertex:
    """Return ``vertex`` turned into the view's own frame, still in space."""
    if self.kind == "isometric":
        vertex = _turned(vertex, *_ISOMETRIC, 0.0)
    return _turned(vertex, self.yaw, self.pitch, self.roll)

PolyhedronBase dataclass

PolyhedronBase(*, merge: bool = False, show_nodes: bool = False, size: float = 200.0, projection: Projection = Projection(), center: Point = (0.0, 0.0))

Bases: SegmentMotif, ABC

Base for a solid: corners in space, joined and flattened onto the page.

Implement :meth:vertices. :meth:edges joins every pair of corners that are as close together as any pair gets, which is the edge set of any solid whose corners are all alike; override it for one whose corners are not.

Parameters:

Name Type Description Default
size float

Diameter of the sphere the corners sit on. The drawing itself is usually smaller, since a projection foreshortens.

200.0
projection Projection

How space becomes the page.

Projection()
center (float, float)

Where the middle lands.

(0.0, 0.0)

Methods:

Name Description
vertices

Return the corners, in any scale: they are normalized before drawing.

edges

Join every pair of corners as close together as any pair gets.

vertices abstractmethod

vertices() -> Sequence[Vertex]

Return the corners, in any scale: they are normalized before drawing.

Source code in src/geomotif/motifs/solids.py
@abstractmethod
def vertices(self) -> Sequence[Vertex]:
    """Return the corners, in any scale: they are normalized before drawing."""

edges

edges() -> Iterable[tuple[int, int]]

Join every pair of corners as close together as any pair gets.

Source code in src/geomotif/motifs/solids.py
@override
def edges(self) -> Iterable[tuple[int, int]]:
    """Join every pair of corners as close together as any pair gets."""
    return _nearest(self.vertices())

Tetrahedron dataclass

Tetrahedron(*, merge: bool = False, show_nodes: bool = False, size: float = 200.0, projection: Projection = Projection(), center: Point = (0.0, 0.0))

Bases: PolyhedronBase

Four triangles: the simplest solid there is, and its own dual.

Cube dataclass

Cube(*, merge: bool = False, show_nodes: bool = False, size: float = 200.0, projection: Projection = Projection(), center: Point = (0.0, 0.0))

Bases: PolyhedronBase

Six squares. Dual to the octahedron, and the one everybody can check.

Octahedron dataclass

Octahedron(*, merge: bool = False, show_nodes: bool = False, size: float = 200.0, projection: Projection = Projection(), center: Point = (0.0, 0.0))

Bases: PolyhedronBase

Eight triangles: a corner of the cube's every face, joined up.

Dodecahedron dataclass

Dodecahedron(*, merge: bool = False, show_nodes: bool = False, size: float = 200.0, projection: Projection = Projection(), center: Point = (0.0, 0.0))

Bases: PolyhedronBase

Twelve pentagons, built on a cube and the golden ratio.

Icosahedron dataclass

Icosahedron(*, merge: bool = False, show_nodes: bool = False, size: float = 200.0, projection: Projection = Projection(), center: Point = (0.0, 0.0))

Bases: PolyhedronBase

Twenty triangles: three golden rectangles at right angles to each other.

TruncatedIcosahedron dataclass

TruncatedIcosahedron(*, merge: bool = False, show_nodes: bool = False, size: float = 200.0, projection: Projection = Projection(), center: Point = (0.0, 0.0))

Bases: PolyhedronBase

The football: twelve pentagons and twenty hexagons.

Made by cutting each of the icosahedron's twelve corners off a third of the way along every edge that meets it. The cut leaves a pentagon where the corner was and turns each triangle into a hexagon.

Polyhedron dataclass

Polyhedron(corners: tuple[Vertex, ...], links: tuple[tuple[int, int], ...] = (), *, merge: bool = False, show_nodes: bool = False, size: float = 200.0, projection: Projection = Projection(), center: Point = (0.0, 0.0))

Bases: PolyhedronBase

Any solid you like: your corners, your edges.

For the shapes whose corners are not all alike, where "join the nearest pairs" is not the edge set -- a pyramid, a prism, a stellation, a scaffold. Leave links empty to fall back to joining the nearest pairs anyway.

Parameters:

Name Type Description Default
corners tuple of (float, float, float)

The corners, in any scale.

required
links tuple of (int, int)

Index pairs into corners. Empty means the nearest pairs.

()