geomotif.bases.segments
¶
Base for motifs that are straight lines between a set of points.
Nodes and edges, nothing more. That covers the complete graphs, chord
diagrams, modular-arithmetic circles (connect i to k*i mod n, the
times-table cardioid) and every form of string art -- all of which are the
same motif with a different edge rule.
Classes:
| Name | Description |
|---|---|
SegmentMotif |
Base for a motif built from straight segments between indexed points. |
SegmentMotif
dataclass
¶
Bases: Motif, ABC
Base for a motif built from straight segments between indexed points.
Implement :meth:nodes and :meth:edges; :meth:build turns them into
strokes. A ten-line class gets you the whole times-table family::
@register("modular.multiplication", family="graph", example={"modulus": 200})
@dataclass(frozen=True, slots=True)
class ModularMultiplication(SegmentMotif):
modulus: int = 200
factor: int = 2
def nodes(self) -> Sequence[Point]:
step = math.tau / self.modulus
return [(math.cos(i * step), math.sin(i * step)) for i in range(self.modulus)]
def edges(self) -> Iterable[tuple[int, int]]:
return ((i, self.factor * i % self.modulus) for i in range(self.modulus))
Notes
Edges are undirected: (i, j) and (j, i) are the same segment and
the duplicate is dropped, as is any self-loop (i, i). Both are
routine outputs of an arithmetic edge rule rather than mistakes, so
neither is an error -- but drawing them would waste plotter time on
nothing.
Methods:
| Name | Description |
|---|---|
nodes |
Return the points the edges are drawn between. |
edges |
Return index pairs into :meth: |