Skip to content

base

pleat.geometries.base

Abstract base class and shared utilities for 2D geometry backends.

A :class:Geometry exposes the operations that the rest of pleat needs to lay out tiles in arbitrary curvature: translation, rotation, distance, angle, and centre of mass. Each backend (Euclidean, hyperbolic, spherical) implements a small set of primitives; the rest are derived in this base class.

A point in the Euclidean and hyperbolic backends is a 2D position; in the spherical backend it is a 3D unit vector. Use :meth:Geometry.to_euclidean to obtain a 2D image suitable for plotting.

Geometry

Base class for 2D geometries (Euclidean, hyperbolic, spherical).

origin classmethod

origin()

Return the origin of the geometry.

Source code in pleat/geometries/base.py
@classmethod
def origin(cls):
    """Return the origin of the geometry."""
    raise NotImplementedError

translation classmethod

translation(p1, p2)

Return a callable that translates points from p1 to p2.

Source code in pleat/geometries/base.py
@classmethod
def translation(cls, p1, p2):
    """Return a callable that translates points from p1 to p2."""
    raise NotImplementedError

center_of_mass classmethod

center_of_mass(points, masses=None)

Compute the center of mass of point masses at the given positions.

Source code in pleat/geometries/base.py
@classmethod
def center_of_mass(cls, points, masses=None):
    """Compute the center of mass of point masses at the given positions."""
    raise NotImplementedError

distance_to_origin classmethod

distance_to_origin(p)

Compute the distance from point p to the origin.

Source code in pleat/geometries/base.py
@classmethod
def distance_to_origin(cls, p):
    """Compute the distance from point p to the origin."""
    raise NotImplementedError

angle_to_axis classmethod

angle_to_axis(p)

Compute the angle from the standard ray to the ray from the origin through p.

Source code in pleat/geometries/base.py
@classmethod
def angle_to_axis(cls, p):
    """Compute the angle from the standard ray to the ray from the origin through p."""
    raise NotImplementedError

point_along_axis classmethod

point_along_axis(x)

Return the point on the standard axis at signed distance x from the origin.

Source code in pleat/geometries/base.py
@classmethod
def point_along_axis(cls, x):
    """Return the point on the standard axis at signed distance x from the origin."""
    raise NotImplementedError

to_euclidean classmethod

to_euclidean(pts)

Convert points from this geometry's representation to Euclidean 2D coordinates.

Source code in pleat/geometries/base.py
@classmethod
def to_euclidean(cls, pts):
    """Convert points from this geometry's representation to Euclidean 2D coordinates."""
    raise NotImplementedError

invert classmethod

invert(p)

Return the point diametrically opposite to p through the origin.

Source code in pleat/geometries/base.py
@classmethod
def invert(cls, p):
    """Return the point diametrically opposite to p through the origin."""
    return cls.translation(p, cls.origin())(cls.origin())

rotation classmethod

rotation(p1, a1)

Return a callable that rotates points by angle a1 around point p1.

Source code in pleat/geometries/base.py
@classmethod
def rotation(cls, p1, a1):
    """Return a callable that rotates points by angle a1 around point p1."""
    t1 = cls.translation(p1, cls.origin())
    r = cls._rotate_around_origin(a1)
    t2 = cls.translation(cls.origin(), p1)

    def rotate(pts):
        return t2(r(t1(pts)))

    return rotate

angle classmethod

angle(p1, p2, p3)

Return the angle from p1 to p3 with apex at p2.

Source code in pleat/geometries/base.py
@classmethod
def angle(cls, p1, p2, p3):
    """Return the angle from p1 to p3 with apex at p2."""
    p1, p3 = cls.translation(p2, cls.origin())(np.array([p1, p3]))
    a1, a3 = cls.angle_to_axis(p1), cls.angle_to_axis(p3)
    return (a1 - a3) % (2 * np.pi)

to_polar classmethod

to_polar(p)

Compute polar coordinates (distance, angle) of point p.

Source code in pleat/geometries/base.py
@classmethod
def to_polar(cls, p):
    """Compute polar coordinates (distance, angle) of point p."""
    return cls.distance_to_origin(p), cls.angle_to_axis(p)

distance classmethod

distance(p1, p2)

Compute the distance between points p1 and p2.

Source code in pleat/geometries/base.py
@classmethod
def distance(cls, p1, p2):
    """Compute the distance between points p1 and p2."""
    return cls.distance_to_origin(cls.translation(p1, cls.origin())(p2))

from_polar classmethod

from_polar(r, a)

Construct a point from polar coordinates (radius r, angle a).

Source code in pleat/geometries/base.py
@classmethod
def from_polar(cls, r, a):
    """Construct a point from polar coordinates (radius r, angle a)."""
    return cls.rotation(cls.origin(), a)(cls.point_along_axis(r))

unit_vector classmethod

unit_vector(a)

Return the point at unit distance from the origin at angle a.

Source code in pleat/geometries/base.py
@classmethod
def unit_vector(cls, a):
    """Return the point at unit distance from the origin at angle a."""
    return cls.from_polar(r=1, a=a)

construct_next_poly_point classmethod

construct_next_poly_point(a, b, angle, length)

Construct point c such that angle(a, b, c) = angle and dist(b, c) = length.

Source code in pleat/geometries/base.py
@classmethod
def construct_next_poly_point(cls, a, b, angle, length):
    """Construct point c such that angle(a, b, c) = angle and dist(b, c) = length."""
    a0 = cls.translation(b, cls.origin())(a)
    c0 = cls.from_polar(length, cls.angle_to_axis(a0) - angle)
    c = cls.translation(cls.origin(), b)(c0)
    return c

regular_poly_in_angle classmethod

regular_poly_in_angle(n, r)

Compute the interior angle of a regular n-gon with circumradius r.

Source code in pleat/geometries/base.py
@classmethod
def regular_poly_in_angle(cls, n, r):
    """Compute the interior angle of a regular n-gon with circumradius r."""
    return 2 * cls.angle(cls.from_polar(r, -np.pi / n), cls.from_polar(r, np.pi / n), cls.origin())

regular_poly_side_length classmethod

regular_poly_side_length(n, r)

Compute the side length of a regular n-gon with circumradius r.

Source code in pleat/geometries/base.py
@classmethod
def regular_poly_side_length(cls, n, r):
    """Compute the side length of a regular n-gon with circumradius r."""
    return cls.distance(cls.from_polar(r, -np.pi / n), cls.from_polar(r, np.pi / n))

platonic_side_length classmethod

platonic_side_length(n, k)

Find the side length of a regular n-gon with interior angle 2*pi/k.

Source code in pleat/geometries/base.py
@classmethod
def platonic_side_length(cls, n, k):
    """Find the side length of a regular n-gon with interior angle 2*pi/k."""
    raise NotImplementedError

platonic_side_length_to_radius classmethod

platonic_side_length_to_radius(n, l)

Find the circumradius of a regular n-gon with side length l.

Source code in pleat/geometries/base.py
@classmethod
@root_return
def platonic_side_length_to_radius(cls, n, l):
    """Find the circumradius of a regular n-gon with side length l."""
    return root_scalar(lambda r: cls.regular_poly_side_length(n, r) - l, x0=0.1, x1=0.01)

archimedean_side_length classmethod

archimedean_side_length(
    faces_around_corner,
    **archimedean_side_length_root_kwargs
)

Find the common side length for an Archimedean vertex with the given face types.

Source code in pleat/geometries/base.py
@classmethod
@root_return
def archimedean_side_length(cls, faces_around_corner, **archimedean_side_length_root_kwargs):
    """Find the common side length for an Archimedean vertex with the given face types."""
    multiplicities = Counter(faces_around_corner)

    def length_to_angle_deficit(l):
        return (
            sum(
                k * cls.regular_poly_in_angle(n, cls.platonic_side_length_to_radius(n, l))
                for n, k in multiplicities.items()
            )
            - 2 * np.pi
        )

    if not archimedean_side_length_root_kwargs:
        archimedean_side_length_root_kwargs = dict(x0=1, x1=2)

    return root_scalar(
        lambda l: np.sign(l) * length_to_angle_deficit(abs(l)), **archimedean_side_length_root_kwargs
    )

archimedean_side_length_and_angles classmethod

archimedean_side_length_and_angles(faces_around_corner)

Return the side length and a dict of interior angles for an Archimedean vertex.

Source code in pleat/geometries/base.py
@classmethod
def archimedean_side_length_and_angles(cls, faces_around_corner):
    """Return the side length and a dict of interior angles for an Archimedean vertex."""
    length = cls.archimedean_side_length(faces_around_corner)
    return length, {
        n: cls.regular_poly_in_angle(n, cls.platonic_side_length_to_radius(n, length))
        for n in set(faces_around_corner)
    }

barycentric_to_euclidean_map classmethod

barycentric_to_euclidean_map(tri)

Return a callable mapping barycentric coordinates to points in the given triangle.

Source code in pleat/geometries/base.py
@classmethod
def barycentric_to_euclidean_map(cls, tri):
    """Return a callable mapping barycentric coordinates to points in the given triangle."""
    return lambda masses: cls.center_of_mass(tri, masses)

root_return

root_return(func)

Decorator that extracts the root from a root_scalar result or raises on failure.

Source code in pleat/geometries/base.py
def root_return(func):
    """Decorator that extracts the root from a root_scalar result or raises on failure."""

    def inner(*args, **kwargs):
        result = func(*args, **kwargs)
        if result.converged:
            return result.root
        else:
            raise ValueError("No root was found")

    return inner