Module pavpen.geometry_calculator

Disparate utilities for calculating coordinates and other elements of geometric constructions

See the …_calculator sub-modules for each calculation utility.

Other sub-modules, such as faults, and defaults contain the core code shared by the various calculators.

class pavpen.geometry_calculator.CircleCalculator[Vector](vector_field_operations: FloatVectorFieldOperations, center: Vector, radius: float, x_hat: Vector | None = None, y_hat: Vector | None = None)[source]

Bases: Generic

Calculates the location of points on a circle (or an ellipse, if the norms of x_hat, and y_hat are different)

Example:

>>> import math
>>> from pavpen.geometry_calculator import CircleCalculator
>>> from pavpen.geometry_calculator.vector_field_implementations import (
...     TupleFloatVectorFieldOperations,
... )
>>>
>>> (x, y) = CircleCalculator(
...     vector_field_operations=TupleFloatVectorFieldOperations.for_2d(),
...     center=(0, 0),
...     radius=1,
...     x_hat=(1, 0),
...     y_hat=(0, 1),
... ).point_at_angle_rad(math.pi / 4)
>>> print(f"({x:.4f}, {y:.4f})")
(0.7071, 0.7071)
point_at_angle_rad(angle_rad: float) Vector[source]

Location of the point at angle angle_rad in the right direction from x_hat the on this circle

The value of the x_hat argument is defined when calling the constructor.

class pavpen.geometry_calculator.FloatVectorFieldOperations[Vector][source]

Bases: VectorFieldOperations[float, Vector], Generic

Base class for VectorFieldOperations whose coordinates are floats

Knowing the type of the coordinates allows us to provide default implementations for some properties, and methods.

property multiplicative_negator: float[source]

The ‘-1’ scalar, i.e. x, such that for any vector (or scalar) v: v * x + v = 0

norm(value: Vector) float[source]
normalized(value: Vector) Vector[source]
projection_length_along(projected: Vector, direction: Vector) float[source]

The norm of the component of the projection of projected on direction

We recommend always calling this method with keyword arguments, since projected, and direction can easily be confused when unnamed.

class pavpen.geometry_calculator.OrthonormalBasisCalculator[Vector](vector_field_operations: FloatVectorFieldOperations, points: list[Vector], float_tolerance: float = 1e-09)[source]

Bases: Generic

Calculates an orthonormal basis of a space that spans a given set of points

Example:

>>> import math
>>> from pavpen.geometry_calculator import OrthonormalBasisCalculator
>>> from pavpen.geometry_calculator.vector_field_implementations import (
...     TupleFloatVectorFieldOperations,
... )
>>>
>>> OrthonormalBasisCalculator(
...     vector_field_operations=TupleFloatVectorFieldOperations.for_3d(),
...     float_tolerance=1e-8,
...     points=((0, 0, 0), (0, 2, 0), (0, 0, -2)),
... ).calculate().basis_vectors
[(0.0, 1.0, 0.0), (0.0, 0.0, -1.0)]
calculate(*, require_points_are_non_redundant: bool = False) Self[source]

Calculates, and sets self.basis_vectors: List[Vector]

The values in basis_vectors are orthonormal vectors spanning the space that contains the points passed in during construction. Two non-redundant points define a line, three points define a plane, etc.

Setting require_points_are_non_redundant to True makes it an exception for points to be spanned by less than len(points) - 1 basis vectors. In this case [CalculationPrecisionExceededError] is raised, if two points are too close to each other, or if two different pairs of points define directions that are close to colinear, or if a computation’s maximum tolerance exceeds float_tolerance (specified during object construction) for any other reason.

class pavpen.geometry_calculator.PlanarRotationDirection(*values)[source]

Bases: Enum

CLOCKWISE = 2[source]
RIGHT = 1[source]
class pavpen.geometry_calculator.RoundedCornerCalculator[Vector](vector_field_operations: FloatVectorFieldOperations, previous_vertex: Vector, corner_vertex: Vector, next_vertex: Vector, radius: float, x_hat: Vector | None = None, y_hat: Vector | None = None, float_tolerance: float = 1e-09)[source]

Bases: Generic

Calculates the parameters of a rounded corner’s circular arc

The non-rounded corner, for which a rounded corner arc is to be calculated is determined by previous_vertex, corner_vertex, and next_vertex.

If x_hat, and y_hat are specified, they define the coordinate system basis for outputs, such as the center of the rouded corner circle, and the start and end point of the rounded corner arc.

Parameters:
  • vector_field_operations – defines how to calculate vector operations for vectors, such as previous_vertex, corner_vertex, and next_vertex

  • radius – the radius of the rounded corner’s circle

calculate() Self[source]

Calculates, and sets the folowing output parameters of the rounded corner arc as attributes of self:

  • center

  • radius

  • arc_start

  • arc_midpoint

  • arc_end

class pavpen.geometry_calculator.RoundedCornerCalculatorComputedValueNames(*values)[source]

Bases: Enum

ARC_END = 'arc_end'[source]
ARC_MIDPOINT = 'arc_midpoint'[source]
ARC_START = 'arc_start'[source]
CENTER = 'center'[source]
RADIUS = 'radius'[source]
class pavpen.geometry_calculator.VectorFieldOperations[Scalar, Vector][source]

Bases: ABC, Generic

Provides an implementation of vector operations for a given data type which can be interpreted as storing vectors

Having this as a separate object allows decoupling the data type storing vectors from an implementation of vector operations (such as addition, scaling, norm). This, in turn, allows us to treat existing data objects (e.g., tuples) as vectors without having to patch their data type’s algebraic operations (e.g., a tuple multiplied by a scalar is already defined), which may break other code relying on them, or adding a wrapper type, which may introduce the need for marshalling.

abstractmethod added(addend1: Vector, addend2: Vector) Vector[source]

Return the vector sum of addend1, and addend2

abstract property additive_identity: Vector[source]

The ‘zero’ vector, i.e. x, such that for any vector v: x + v = v

abstractmethod inner_multiplied(multiplicand1: Vector, multiplicand2: Vector) Scalar[source]

Returns the inner product of multiplicand1, and multiplicand2

In an orthonormal basis, this is the same as the dot (component-wise) product. In either case, the result of the inner product must be the product of the norms of each multiplicand, and of the orthogonal projection of one multiplicand on the other (the result being negative, if the projeciton endpoint is in the opposite direction of the vector).

abstract property multiplicative_negator: Scalar[source]

The ‘-1’ scalar, i.e. x, such that for any vector (or scalar) v: v * x + v = 0

negated(value: Vector) Vector[source]
abstractmethod norm(value: Vector) Scalar[source]
abstractmethod normalized(value: Vector) Vector[source]
abstractmethod projection_length_along(projected: Vector, direction: Vector) Scalar[source]

The norm of the component of the projection of projected on direction

We recommend always calling this method with keyword arguments, since projected, and direction can easily be confused when unnamed.

abstractmethod scaled(multiplicand: Vector, scalar: Scalar) Vector[source]

Returns multiplicand scaled (multiplied) by scalar

subtracted(diminuend: Vector, subtrahend: Vector) Vector[source]
summed(addend1: Vector, *rest_addends: Vector) Vector[source]
pavpen.geometry_calculator.__commit_id__: Final[str | None] = 'gdbc8421'[source]

May be undefined

pavpen.geometry_calculator.__version__: Final[str] = '0.2.2.dev6'[source]

The module version string.

It may contain suffixes, such as ".dev7+dirty".

pavpen.geometry_calculator.__version_tuple__: Final[tuple[int | str, ...] | None] = (0, 2, 2, 'dev6')[source]

This module’s version components as a tuple

  • May include suffixes.

  • May be undefined.