Skip to content

Edge curves

isotile.EdgeShape dataclass

EdgeShape(
    shape: Shape, points: Array, mode: Mode = "spline"
)

A curve on the canonical edge together with the shape that constrains it.

Create it with EdgeShape.from_points, which projects the points onto the constraint of the shape; the constructor stores the arrays as given.

Attributes:

  • shape ({'I', 'J', 'U', 'S'}) –

    Edge shape.

  • points ((m, 2) ndarray) –

    Control points from (0, 0) to (1, 0) (read-only), with the symmetry of the shape.

  • mode ({'spline', 'linear'}) –

    How the curve between the control points is drawn, see interpolate.

Methods:

from_points classmethod

from_points(
    shape: str,
    points: ArrayLike | None = None,
    mode: str = "spline",
) -> EdgeShape

The curve with the symmetry of shape that enforce_symmetry makes of the points.

Parameters:

  • shape (('I', 'J', 'U', 'S'), default: "I" ) –
  • points ((m, 2) array-like, default: None ) –

    Control points; the segment when omitted. Ignored for "I".

  • mode (('spline', 'linear'), default: "spline" ) –

Raises:

  • ValueError –

    If the shape or mode is unknown, the points are not a finite (m, 2) array with m >= 2 or the projected curve does not run from (0, 0) to (1, 0).

pieces

pieces() -> Array

The curve as cubic Bezier pieces, as computed by bezier_pieces.

samples

samples(n_points: int | None = None) -> Array

The curve as a polyline, see interpolate.

isotile.EdgeInfo dataclass

EdgeInfo(
    index: int,
    shape_id: int,
    shape: str,
    reversed: bool,
    curve: EdgeShape,
)

One edge of the prototile.

Attributes:

  • index (int) –

    Position of the edge: it joins vertex index to vertex index + 1.

  • shape_id (int) –

    Id of the edge shape; edges with the same id have the same curve.

  • shape ({'I', 'J', 'U', 'S'}) –

    Constraint on the curve of the edge.

  • reversed (bool) –

    True if the edge is traversed against the direction of its shape's canonical edge.

  • curve (EdgeShape) –

    The curve of the shape id on the canonical edge (the segment for an edge without a curve).

isotile.enforce_symmetry

enforce_symmetry(points: ArrayLike, shape: str) -> Array

Project edge curve control points onto the curves that the edge shape allows.

The projection is by index. For U and S, point k of the first half is kept and point m - 1 - k is replaced by its mirror image (U: (1 - x, y)) or its image under a rotation by 180 degrees about (0.5, 0) (S: (1 - x, -y)). The middle point of an odd number of points is moved onto the axis of the mirror (U: x = 0.5, y kept) or onto the center of the rotation (S: (0.5, 0)). J returns the points unchanged and I the segment (0, 0), (1, 0).

Applying the function to its own result returns the same array, and a curve that already has the symmetry of its shape is returned unchanged.

Parameters:

  • points ((m, 2) array-like) –

    Control points, m >= 2.

  • shape (('I', 'J', 'U', 'S'), default: "I" ) –

    Edge shape.

Returns:

  • (m, 2) ndarray –

    The projected points ((2, 2) for I).

Raises:

  • ValueError –

    If the shape is unknown or points is not a finite array of at least 2 points of shape (m, 2).

isotile.is_symmetric

is_symmetric(
    points: ArrayLike, shape: str, tol: float = 1e-09
) -> bool

True if the control points have the symmetry of the edge shape, to within tol in each coordinate.

J is always true; I requires the points to be the segment (0, 0), (1, 0). Equivalent to np.allclose(enforce_symmetry(points, shape), points, rtol=0, atol=tol) for the other shapes.

Parameters:

  • points ((m, 2) array-like) –
  • shape (('I', 'J', 'U', 'S'), default: "I" ) –
  • tol (float, default: 1e-9 ) –

    Largest allowed absolute difference.

Raises:

isotile.interpolate

interpolate(
    points: ArrayLike,
    mode: str = "spline",
    n_points: int | None = None,
) -> Array

Sample an edge curve.

"spline" is a parametric natural cubic spline (x(t), y(t)) through the control points, with t the cumulative chord length scaled to [0, 1], evaluated at n_points equally spaced values of t. The curve passes through every control point, may turn back in x and keeps the symmetry of its control points (the samples at index k and n_points - 1 - k are related by it). Consecutive control points that coincide count once. With one or two distinct points the result is the control points. "linear" returns the control points unchanged (n_points is ignored).

Parameters:

  • points ((m, 2) array-like) –

    Control points.

  • mode (('spline', 'linear'), default: "spline" ) –
  • n_points (int, default: None ) –

    Number of samples of the spline, at least 2. Default max(100, 10 * m).

Returns:

  • (k, 2) ndarray –

Raises:

  • ValueError –

    If the mode is unknown, n_points < 2 or points is not a finite array of at least 2 points of shape (m, 2).