API Reference¶
geo
A Python package for computational geometry. Provides primitives, operations, and utilities for 2D and 3D geometric tasks.
- class geo.AABB(min_pt: Point3D, max_pt: Point3D)[source]¶
Bases:
object
Axis-Aligned Bounding Box.
- class geo.BezierCurve(control_points: Sequence[Point2D])[source]¶
Bases:
Curve2D
Arbitrary-degree 2-D Bezier curve.
- Parameters:
control_points – Iterable of :class: geo.core.Point2D. At least two are required (a single point would be a degenerate curve; for that, use :class: geo.primitives_2d.curve.base.Curve2D directly or a degenerate curve subclass).
Notes
Degree = len(control_points) - 1
point_at uses Bernstein polynomials by default; can switch to De Casteljau for improved numerical stability on very high degrees via the use_casteljau flag.
- derivative_curve() BezierCurve [source]¶
Returns the derivative of this Bezier curve as a new BezierCurve object. The resulting control points are vectors interpreted as new points.
- point_at(t: float, *, use_casteljau: bool = False) Point2D [source]¶
Evaluate the curve at parameter t.
- Parameters:
t (float) – Parameter value. 0 ≤ t ≤ 1 is the usual domain; other values extrapolate linearly.
use_casteljau (bool, default=False) – When True, uses the recursive De Casteljau algorithm, which is numerically stabler for high-degree curves.
- Return type:
- class geo.Circle(center: Point2D, radius: float)[source]¶
Bases:
object
Represents a circle in 2D space, defined by a center point and a radius.
- property area: float¶
Calculates the area of the circle.
- property circumference: float¶
Calculates the circumference (perimeter) of the circle.
- contains_point(point: Point2D, epsilon: float = 1e-09) bool [source]¶
Checks if a point is inside or on the boundary of the circle.
- Parameters:
point – The Point2D to check.
epsilon – Tolerance for floating point comparisons (for boundary).
- Returns:
True if the point is contained within or on the circle, False otherwise.
- intersection_with_circle(other: Circle, epsilon: float = 1e-09) List[Point2D] [source]¶
Calculates the intersection points of this circle with another circle.
- Parameters:
other – The other Circle to intersect with.
epsilon – Tolerance for floating point comparisons.
- Returns:
A list of intersection Point2Ds. - Empty list if no intersection (circles are separate or one contains another without touching). - One point if circles are tangent. - Two points if circles intersect at two distinct points. - Potentially infinite if circles are coincident (returns empty list for now).
- intersection_with_line(line: Line2D, epsilon: float = 1e-09) List[Point2D] [source]¶
Calculates the intersection points of this circle with a Line2D.
- Parameters:
line – The Line2D to intersect with.
epsilon – Tolerance for floating point comparisons.
- Returns:
A list of intersection Point2Ds. - Empty list if no intersection. - One point if the line is tangent to the circle. - Two points if the line secants the circle.
- class geo.Circle3D(center: Point3D, radius: float, normal: Vector3D)[source]¶
Bases:
object
Represents a circle in 3D space, defined by a center point, radius, and plane normal.
- class geo.Cone(apex: Point3D, base_center: Point3D, base_radius: float)[source]¶
Bases:
object
Represents a finite right circular cone in 3D space. Defined by its apex point, the center of its circular base, and the radius of the base. The height and axis direction are derived from these.
- property base_area: float¶
pi * r^2.
- Type:
Calculates the area of the circular base
- contains_point(point: Point3D, epsilon: float = 1e-09) bool [source]¶
Checks if a point is inside or on the boundary of the cone. 1. Point must be between the base plane and a plane through the apex parallel to base. 2. For a point P, let its projection onto the cone’s axis be Q.
The distance from P to Q (radial_dist) must be <= R_at_Q, where R_at_Q is the radius of the cone’s cross-section at Q. R_at_Q = base_radius * (distance from apex to Q) / height.
- property lateral_surface_area: float¶
pi * r * slant_height.
- Type:
Calculates the lateral surface area of the cone
- property slant_height: float¶
Calculates the slant height of the cone.
- property total_surface_area: float¶
base_area + lateral_surface_area.
- Type:
Calculates the total surface area
- property volume: float¶
(1/3) * pi * r^2 * h.
- Type:
Calculates the volume of the cone
- class geo.Cube(center: Point3D, side_length: float, axes: List[Vector3D] | None = None)[source]¶
Bases:
object
Represents a cube in 3D space.
Axis-aligned cube defined by center and side_length.
Optionally, a rotation matrix (3 orthonormal Vector3D axes) can define a non-axis-aligned cube (oriented cube).
- contains_point(point: Point3D, epsilon: float = 1e-09) bool [source]¶
Checks if a point is inside or on the boundary of the cube.
For axis-aligned cubes (default axes), this is a simple bounding box check.
For oriented cubes, transform point into cube’s local axes coords, then check if within [-half_side, half_side] along each axis.
- property faces_as_vertex_indices: List[List[int]]¶
Returns the 6 faces of the cube, each as a list of vertex indices. Vertices are ordered CCW when viewed from outside. Vertex order in self.vertices is:
index = (dx_index * 4) + (dy_index * 2) + dz_index with dx, dy, dz in (-hs, hs) ordering
The cube is built as a rectangular parallelepiped, but the order is consistent.
- property surface_area: float¶
Calculates the surface area of the cube.
- to_polyhedron() Polyhedron [source]¶
Converts this Cube to a Polyhedron object.
- property volume: float¶
Calculates the volume of the cube.
- class geo.Curve2D(control_points: Sequence[Point2D])[source]¶
Bases:
ABC
Abstract base class for a 2D parametric curve. A curve is typically defined by C(t), where t is a parameter in [0, 1].
- derivative_at(t: float) Vector2D [source]¶
Alias for tangent_at, representing the first derivative C’(t).
- length(t0: float = 0.0, t1: float = 1.0, num_segments: int = 100) float [source]¶
Approximates the curve length from t0 to t1 using numerical integration.
- Parameters:
t0 (float) – Starting parameter.
t1 (float) – Ending parameter.
num_segments (int) – Number of segments for numerical approximation.
- Returns:
Approximate curve length.
- Return type:
float
- Raises:
ValueError – If num_segments is not positive.
- abstract point_at(t: float) Point2D [source]¶
Calculates the point on the curve at parameter t. :param t: The parameter (typically in the range [0, 1]). :type t: float
- Returns:
The point on the curve.
- Return type:
- class geo.Cylinder(base_center: Point3D, axis_direction: Vector3D, radius: float, height: float)[source]¶
Bases:
object
Represents a finite right circular cylinder in 3D space. Defined by the center of its base, its axis direction, radius, and height.
- property base_area: float¶
pi * r^2.
- Type:
Calculates the area of one circular cap of the cylinder
- contains_point(point: Point3D, epsilon: float = 1e-09) bool [source]¶
Checks if a point is inside or on the boundary of the cylinder.
Steps: 1. Project point onto the cylinder’s axis. Check if projection is between base and top (with epsilon tolerance). 2. Calculate distance from point to the axis. Check if it’s within radius (with epsilon tolerance).
- Parameters:
point – The point to test.
epsilon – Tolerance for boundary checks.
- Returns:
True if point is inside or on the boundary, False otherwise.
- distance_to_axis(point: Point3D) float [source]¶
Calculates the shortest distance from a given point to the cylinder’s axis line.
- Parameters:
point – The point to measure distance from.
- Returns:
The shortest distance from point to the axis line.
- get_cap_planes() Tuple[Plane, Plane] [source]¶
Returns the two planes of the cylinder caps.
The base cap’s normal points opposite to the axis direction (outward from volume), and the top cap’s normal points along the axis direction.
- get_lateral_surface_point(angle_radians: float, height_fraction: float) Point3D [source]¶
Returns a point on the lateral surface of the cylinder given an angle around the axis and a height fraction along the axis.
- Parameters:
angle_radians – Angle around the axis in radians (0 aligned with some reference).
height_fraction – Fraction between 0 (base) and 1 (top) along the axis height.
- Returns:
A Point3D on the lateral surface of the cylinder.
- property lateral_surface_area: float¶
2 * pi * r * h.
- Type:
Calculates the lateral surface area (side) of the cylinder
- project_point_onto_axis(point: Point3D) float [source]¶
Projects a point onto the cylinder’s axis and returns the scalar distance along the axis from the base_center.
- Parameters:
point – The point to project.
- Returns:
Scalar projection length along the axis from base_center.
- property total_surface_area: float¶
2 * base_area + lateral_surface_area.
- Type:
Calculates the total surface area
- property volume: float¶
pi * r^2 * h.
- Type:
Calculates the volume of the cylinder
- class geo.Ellipse(center: Point2D, semi_major_axis: float, semi_minor_axis: float, angle_rad: float = 0.0)[source]¶
Bases:
object
Represents an ellipse in 2D space. Defined by a center, semi-major axis length (a), semi-minor axis length (b), and a rotation angle for the major axis relative to the x-axis. We assume a >= b. If b > a, they are swapped.
- property area: float¶
Calculates the area of the ellipse.
- circumference() float [source]¶
Calculates the circumference (perimeter) of the ellipse. This uses Ramanujan’s approximation, which is quite accurate. C approx = pi * [3(a+b) - sqrt((3a+b)(a+3b))]
- contains_point(point: Point2D, epsilon: float = 1e-09) bool [source]¶
Checks if a point is inside or on the boundary of the ellipse. The point is transformed to the ellipse’s local coordinate system (where it’s axis-aligned). Then, (x/a)^2 + (y/b)^2 <= 1 within a numerical tolerance.
- property eccentricity: float¶
Calculates the eccentricity (e) of the ellipse. e = c / a = sqrt(1 - (b/a)^2) Returns 0 if a is zero.
- get_foci() Tuple[Point2D, Point2D] [source]¶
Calculates the two foci of the ellipse. Foci lie along the major axis, at distance c from the center.
- property linear_eccentricity: float¶
Calculates the linear eccentricity (c), distance from center to each focus. c = sqrt(a^2 - b^2) Returns 0 if a < b (which shouldn’t happen if constructor enforces a>=b).
- class geo.Line2D(p1: Point2D, p2_or_direction: Point2D | Vector2D)[source]¶
Bases:
object
Represents an infinite line in 2D space. A line can be defined by two distinct points or by a point and a direction vector.
- contains_point(point: Point2D, epsilon: float = 1e-09) bool [source]¶
Checks if a point lies on the line.
- Parameters:
point – The Point2D to check.
epsilon – Tolerance for floating point comparisons.
- Returns:
True if the point is on the line, False otherwise.
- distance_to_point(point: Point2D) float [source]¶
Calculates the shortest distance from a point to this line. Distance = |(AP x d)| / |d|, where AP is vector from point on line to the given point, d is direction vector. For 2D, |(AP x d)| is |AP.x*d.y - AP.y*d.x|. Since d is normalized, |d|=1. So distance = |AP x d|.
- intersection_with(other: Line2D, epsilon: float = 1e-09) Point2D | None [source]¶
Calculates the intersection point with another line.
- Parameters:
other – The other Line2D.
epsilon – Tolerance for floating point comparisons.
- Returns:
The intersection Point2D, or None if lines are parallel (or coincident). If lines are coincident, this method returns None as there isn’t a single intersection point.
- is_parallel_to(other: Line2D, epsilon: float = 1e-09) bool [source]¶
Checks if this line is parallel to another line. Parallel lines have direction vectors that are scalar multiples of each other. Their 2D cross product (z-component) is zero.
- class geo.Line3D(origin: Point3D, direction_or_p2: Vector3D | Point3D)[source]¶
Bases:
object
Represents an infinite line in 3D space. Defined by an origin point and a direction vector (normalized).
- contains_point(point: Point3D, epsilon: float = 1e-09) bool [source]¶
Checks if a point lies on the line.
- distance_to_point(point: Point3D) float [source]¶
Calculates the shortest distance from a point to this line. Distance = |(P - origin) x direction| (direction is normalized).
- class geo.Plane(point_on_plane: Point3D, normal_or_p2: Vector3D | Point3D, p3: Point3D | None = None)[source]¶
Bases:
object
Represents an infinite plane in 3D space.
A plane can be defined by a point on the plane and a normal vector, or by three non-collinear points.
The plane equation is: n · (P - P0) = 0, where n is the normal, P0 is a point on the plane, and P is any point (x,y,z) on the plane.
- This can be written as:
Ax + By + Cz = D,
where (A, B, C) is the normal vector n, and D = n · P0 (note: this is the plane constant in this form).
- contains_point(point: Point3D, epsilon: float = 1e-09) bool [source]¶
Checks if a point lies on the plane.
This is true if the signed distance from the point to the plane is close to zero.
- distance_to_point(point: Point3D, epsilon: float = 1e-09) float [source]¶
Calculates the shortest (unsigned) distance from a point to the plane.
- get_coefficients() Tuple[float, float, float, float] [source]¶
- Returns the coefficients (A, B, C, D) of the plane equation:
Ax + By + Cz = D
- intersection_with_line(line: Line3D) Point3D | None [source]¶
Calculates the intersection point of this plane with a Line3D.
- Parameters:
line – The Line3D to intersect with.
- Returns:
The intersection Point3D, or None if the line is parallel to the plane and not on the plane. If the line lies on the plane, it also returns None as there is no single intersection point (infinite intersections).
- class geo.Point(*coords: TCoord)[source]¶
Bases:
Generic
[TCoord
]A base class for a point in N-dimensional space. Not intended for direct instantiation for specific dimensions, but provides common functionality.
- property coords: Sequence[TCoord]¶
Returns the coordinates of the point as a tuple.
- property dimension: int¶
Returns the dimension of the point.
- class geo.Point2D(x: float, y: float)[source]¶
Bases:
Point
[float
]Represents a point in 2D space.
- classmethod from_polar(r: float, theta: float) Point2D [source]¶
Creates a Point2D from polar coordinates.
- Parameters:
r – The radius.
theta – The angle in radians.
- Returns:
A new Point2D object.
- to_polar() tuple[float, float] [source]¶
Converts Cartesian coordinates to polar coordinates.
- Returns:
A tuple (r, theta) where r is the radius and theta is the angle in radians. Angle is in the range (-pi, pi].
- property x: float¶
Returns the x-coordinate.
- property y: float¶
Returns the y-coordinate.
- class geo.Point3D(x: float, y: float, z: float)[source]¶
Bases:
Point
[float
]Represents a point in 3D space.
- classmethod from_spherical(r: float, theta: float, phi: float) Point3D [source]¶
Creates a Point3D from spherical coordinates (ISO 80000-2:2019 convention).
- Parameters:
r – Radial distance (must be non-negative).
theta – Inclination (polar angle from positive z-axis), in radians [0, pi].
phi – Azimuth (angle from positive x-axis in xy-plane), in radians.
- Returns:
A new Point3D object.
- to_spherical() tuple[float, float, float] [source]¶
Converts Cartesian coordinates to spherical coordinates (ISO 80000-2:2019 convention). r: radial distance theta: inclination (polar angle, angle from positive z-axis), range [0, pi] phi: azimuth (angle from positive x-axis in xy-plane), range (-pi, pi]
- Returns:
A tuple (r, theta, phi).
- property x: float¶
Returns the x-coordinate.
- property y: float¶
Returns the y-coordinate.
- property z: float¶
Returns the z-coordinate.
- class geo.Polygon(vertices: Sequence[Point2D])[source]¶
Bases:
object
Represents a 2D polygon defined by a sequence of vertices. The vertices are assumed to be ordered (clockwise or counter-clockwise). This implementation primarily supports simple polygons (non-self-intersecting).
- property area: float¶
Unsigned area of the polygon.
Simple polygon → abs(signed_area)
Self-intersecting → positive cross-term sum (net enclosed area)
- centroid() Point2D [source]¶
Calculates the geometric centroid (center of mass) of a simple polygon. Formula: Cx = (1/6A) * sum_{i=0}^{n-1} (xi + x_{i+1}) * (xi*y_{i+1} - x_{i+1}*yi)
Cy = (1/6A) * sum_{i=0}^{n-1} (yi + y_{i+1}) * (xi*y_{i+1} - x_{i+1}*yi)
where A is the signed area.
- contains_point(point: Point2D, epsilon: float = 1e-09) bool [source]¶
Checks if a point is inside, on the boundary, or outside the polygon. Uses the Ray Casting algorithm (even-odd rule) or Winding Number algorithm. This implementation uses the winding number algorithm. A point is inside if its winding number is non-zero. For simple polygons, winding number is +/-1 for inside, 0 for outside.
- Parameters:
point – The Point2D to check.
epsilon – Tolerance for floating point comparisons.
- Returns:
True if the point is inside or on the boundary, False otherwise.
- property edges: List[Segment2D]¶
Returns a list of Segment2D objects representing the edges of the polygon.
- is_convex(epsilon: float = 1e-09) bool [source]¶
Checks if the polygon is convex. A polygon is convex if all its internal angles are <= 180 degrees. This can be checked by looking at the sign of the cross product of consecutive edge vectors. All cross products should have the same sign (or be zero for collinear edges). Assumes vertices are ordered (e.g., CCW).
- property num_vertices: int¶
Returns the number of vertices in the polygon.
- property perimeter: float¶
Calculates the perimeter of the polygon.
- class geo.Polyhedron(vertices: Sequence[Point3D], faces: Sequence[Sequence[int]])[source]¶
Bases:
object
Represents a polyhedron defined by a list of vertices and a list of faces. Each face is a list of indices referencing the vertices list. Vertices of a face are assumed to be ordered CCW when viewed from outside.
- get_face_normal(face_index: int) Vector3D [source]¶
Calculates the normal vector of a given face. Assumes face vertices are ordered CCW from outside. Uses a robust method by checking vertex triplets to find a non-collinear set.
- Raises:
ValueError – If all triplets are collinear and face is degenerate.
- get_face_points(face_index: int) List[Point3D] [source]¶
Returns the Point3D objects for a given face index.
- property num_edges: int¶
Calculates the number of unique edges in the polyhedron.
- property num_faces: int¶
- property num_vertices: int¶
- surface_area() float [source]¶
Calculates the total surface area of the polyhedron. Sums the area of each face by triangulating polygonal faces from the first vertex.
- volume() float [source]¶
Calculates the volume of the polyhedron. Uses the sum of signed volumes of tetrahedra formed by origin and each face triangle. Triangulates faces if needed.
- Returns:
Absolute volume (non-negative).
Note
The reference origin (0,0,0) is assumed for signed volume calculations. If polyhedron does not contain origin, volume is still correct by absolute value.
- class geo.Ray2D(origin: Point2D, direction: Vector2D)[source]¶
Bases:
object
Represents a ray in 2D space, starting at an origin and extending infinitely in a given direction.
- contains_point(point: Point2D, epsilon: float = 1e-09) bool [source]¶
Checks if a point lies on the ray. The point must be collinear with the ray’s line and on the positive side of the origin along the ray’s direction.
- class geo.Ray3D(origin: Point3D, direction: Vector3D)[source]¶
Bases:
object
Represents a ray in 3D space with origin and infinite direction.
- contains_point(point: Point3D, epsilon: float = 1e-09) bool [source]¶
Checks if a point lies on the ray.
Algorithm: 1. Check collinearity with the ray’s direction vector. 2. Ensure the point lies in the same direction as the ray (t >= 0).
- point_at(t: float) Point3D [source]¶
Returns a point on the ray: P(t) = origin + t * direction with t >= 0.
- class geo.Rectangle(p1: Point2D, p2_or_width: Point2D | float, height: float | None = None, angle_rad: float = 0.0)[source]¶
Bases:
Polygon
Represents a rectangle in 2D space. Can be initialized with two opposite corner points, or with a corner, width, height, and angle. Inherits from Polygon. Vertices are ordered counter-clockwise by default.
- property angle: float¶
Returns the rotation angle in radians from x-axis.
- property area: float¶
Returns the area of the rectangle.
- property diagonal_length: float¶
Returns the diagonal length of the rectangle.
- property height: float¶
Returns the height of the rectangle.
- property width: float¶
Returns the width of the rectangle.
- class geo.Segment2D(p1: Point2D, p2: Point2D)[source]¶
Bases:
object
Represents a line segment in 2D space, defined by two distinct endpoints.
- contains_point(point: Point2D, epsilon: float = 1e-09) bool [source]¶
Checks if a point lies on the segment within a given epsilon tolerance. Considers the point to be ‘on’ the segment if: - It lies approximately on the line (collinear within epsilon). - It projects within or near the segment bounds.
- property direction_vector: Vector2D¶
Returns the direction vector from p1 to p2 (not necessarily normalized).
- distance_to_point(point: Point2D) float [source]¶
Calculates the shortest distance from a point to this segment.
- intersection_with_segment(other: Segment2D, epsilon: float = 1e-09) Point2D | None [source]¶
Calculates the intersection point with another segment.
- Parameters:
other – The other Segment2D.
epsilon – Tolerance for floating point comparisons.
- Returns:
The intersection Point2D, or None if they do not intersect or overlap. If segments overlap along a line, this method currently returns None. Handling of overlapping segments can be complex and is omitted for simplicity.
- property length: float¶
Returns the length of the segment.
- class geo.Segment3D(p1: Point3D, p2: Point3D)[source]¶
Bases:
object
Represents a finite line segment in 3D space, defined by two distinct endpoints.
- contains_point(point: Point3D, epsilon: float = 1e-09) bool [source]¶
Checks if a point lies on the segment.
Algorithm: 1. Check collinearity with the line defined by segment endpoints. 2. Verify if point lies between p1 and p2 by projection dot products.
- Parameters:
point – Point3D to check.
epsilon – Tolerance for floating comparisons.
- Returns:
True if point lies on or very close to the segment.
- distance_to_point(point: Point3D) float [source]¶
Calculates the shortest distance from a point to the segment.
Uses clamped projection to find closest point on segment.
- property length: float¶
Returns the Euclidean length of the segment.
- class geo.Sphere(center: Point3D, radius: float)[source]¶
Bases:
object
Represents a sphere in 3D space, defined by a center point and a radius.
- contains_point(point: Point3D, on_surface_epsilon: float | None = None) bool [source]¶
Checks if a point is inside or on the boundary of the sphere.
- Parameters:
point – The Point3D to check.
on_surface_epsilon – If provided, checks if the point is on the surface within this epsilon. Otherwise, checks if inside or on surface.
- Returns:
True if condition met, False otherwise.
- intersection_with_line(line: Line3D) List[Point3D] [source]¶
Calculates intersection points of the sphere with a Line3D. Algorithm: Solve (X-C).(X-C) = r^2 where X = L0 + t*L_dir. This leads to a quadratic equation in t: at^2 + bt + c = 0.
- intersection_with_plane(plane: Plane) Circle3D | None [source]¶
Calculates the intersection of the sphere with a Plane. Returns a Circle3D if intersection is a circle, or a Circle3D with radius 0 if tangent, or None if no intersection.
- intersection_with_sphere(other: Sphere) Circle3D | None [source]¶
Calculates the intersection of this sphere with another sphere. Returns a Circle3D representing the circle of intersection, or None if no intersection or spheres are tangent at a point.
Reference: https://mathworld.wolfram.com/Sphere-SphereIntersection.html
- on_surface(point: Point3D, epsilon: float = 1e-09) bool [source]¶
Checks if a point lies exactly on the surface of the sphere within epsilon.
- point_from_spherical_coords(theta: float, phi: float) Point3D [source]¶
Returns a point on the sphere surface given spherical coordinates. theta: azimuthal angle in radians [0, 2*pi] phi: polar angle in radians [0, pi]
- scale(factor: float) Sphere [source]¶
Returns a new Sphere scaled by the given factor relative to the origin.
- strictly_inside(point: Point3D, epsilon: float = 1e-09) bool [source]¶
Checks if a point is strictly inside the sphere (excluding surface within epsilon).
- strictly_outside(point: Point3D, epsilon: float = 1e-09) bool [source]¶
Checks if a point is strictly outside the sphere (excluding surface within epsilon).
- property surface_area: float¶
4 * pi * r^2.
- Type:
Calculates the surface area of the sphere
- property volume: float¶
(4/3) * pi * r^3.
- Type:
Calculates the volume of the sphere
- class geo.SphereSphereIntersectionResult(type: str, point: Point3D | None = None, circle_center: Point3D | None = None, circle_radius: float | None = None, circle_normal: Vector3D | None = None)[source]¶
Bases:
object
Result for sphere-sphere intersection.
- circle_radius: float | None = None¶
- type: str¶
- class geo.SplineCurve(control_points: Sequence[Point2D], degree: int = 3, knots: Sequence[float] | None = None)[source]¶
Bases:
Curve2D
Open, clamped B-spline curve in 2D.
- basis_function_derivatives(i: int, u: float, d: int = 1) List[List[float]] [source]¶
Return derivatives up to order d (≤ p) of basis at u. Uses algorithm A2-3 (Piegl & Tiller).
- basis_functions(i: int, u: float) List[float] [source]¶
Compute p + 1 non-zero basis functions N_{i-p, …, i}(u).
- insert_knot(u: float, r: int = 1) None [source]¶
Insert parameter u (p ≥ multiplicity + current mult.) up to r times.
- point_at(t: float) Point2D [source]¶
Calculates the point on the curve at parameter t. :param t: The parameter (typically in the range [0, 1]). :type t: float
- Returns:
The point on the curve.
- Return type:
- class geo.Triangle(p1: Point2D, p2: Point2D, p3: Point2D)[source]¶
Bases:
Polygon
Represents a triangle in 2D space, defined by three vertices. Inherits from Polygon.
- property angles_deg: Tuple[float, float, float]¶
Returns the three internal angles in degrees.
- property angles_rad: Tuple[float, float, float]¶
Returns the three internal angles of the triangle in radians. (angle_at_p1, angle_at_p2, angle_at_p3) Uses the Law of Cosines: c^2 = a^2 + b^2 - 2ab*cos(C) => cos(C) = (a^2 + b^2 - c^2) / (2ab)
- property area: float¶
Calculates the area of the triangle. Overrides Polygon.area for potential direct calculation, though Shoelace is fine. Area = 0.5 * |x1(y2−y3) + x2(y3−y1) + x3(y1−y2)|
- property circumcircle: Circle | None¶
Calculates the circumcircle of the triangle (the circle passing through all three vertices). Returns None if the triangle is degenerate (vertices are collinear), though the constructor should prevent this.
- property incircle: Circle | None¶
Calculates the incircle of the triangle (the largest circle contained within the triangle). Returns None if the triangle is degenerate. Incenter Ix = (a*x1 + b*x2 + c*x3) / (a+b+c) Incenter Iy = (a*y1 + b*y2 + c*y3) / (a+b+c) Inradius r = Area / s, where s is semi-perimeter (a+b+c)/2.
- property side_lengths: Tuple[float, float, float]¶
Returns the lengths of the three sides (a, b, c). a: length of side opposite p1 (segment p2-p3) b: length of side opposite p2 (segment p1-p3) c: length of side opposite p3 (segment p1-p2)
- class geo.Vector(*components: TComponent)[source]¶
Bases:
Generic
[TComponent
]A base class for a vector in N-dimensional space. Provides common vector operations.
- angle_between(other: Vector[TComponent], in_degrees: bool = False) float [source]¶
Calculates the angle between this vector and another vector.
- Parameters:
other – The other Vector object.
in_degrees – If True, returns the angle in degrees. Otherwise, in radians.
- Returns:
The angle in radians or degrees.
- Raises:
ValueError – If either vector is a zero vector or dimensions mismatch.
- property components: Sequence[TComponent]¶
Returns the components of the vector as a tuple.
- property dimension: int¶
Returns the dimension of the vector.
- dot(other: Vector[TComponent]) float [source]¶
Calculates the dot product with another vector.
- Parameters:
other – The other Vector object.
- Returns:
The dot product.
- Raises:
ValueError – If the vectors have different dimensions.
- class geo.Vector2D(x: float, y: float)[source]¶
Bases:
Vector
[float
]Represents a vector in 2D space.
- angle() float [source]¶
Calculates the angle of the vector with respect to the positive x-axis. The angle is in radians, in the range (-pi, pi].
- cross(other: Vector2D) float [source]¶
Calculates the 2D cross product (magnitude of the 3D cross product’s z-component). This is a scalar value: self.x * other.y - self.y * other.x. It’s useful for determining orientation or signed area.
- Parameters:
other – The other Vector2D object.
- Returns:
The scalar result of the 2D cross product.
- perpendicular(clockwise: bool = False) Vector2D [source]¶
Returns a 2D vector perpendicular to this one. By default, returns the counter-clockwise perpendicular vector (-y, x).
- Parameters:
clockwise – If True, returns the clockwise perpendicular vector (y, -x).
- Returns:
A new Vector2D perpendicular to this one.
- property x: float¶
Returns the x-component.
- property y: float¶
Returns the y-component.
- class geo.Vector3D(x: float, y: float, z: float)[source]¶
Bases:
Vector
[float
]Represents a vector in 3D space.
- cross(other: Vector3D) Vector3D [source]¶
Calculates the 3D cross product with another vector.
- Parameters:
other – The other Vector3D object.
- Returns:
A new Vector3D representing the cross product.
- property x: float¶
Returns the x-component.
- property y: float¶
Returns the y-component.
- property z: float¶
Returns the z-component.
- geo.check_point_left_of_line(point: Point2D, line_p1: Point2D, line_p2: Point2D) float [source]¶
Returns > 0 if point is left of the directed line from line_p1 to line_p2, < 0 if right, and 0 if collinear.
- geo.clip_polygon_sutherland_hodgman(subject: Polygon, clip: Polygon) Polygon | None [source]¶
Clip subject (any polygon, CW or CCW) against convex clip (CCW).
Returns clipped polygon or None if empty.
- geo.closest_point_on_segment_to_point(segment: Segment2D | Segment3D, point: Point2D | Point3D, *, epsilon: float = 1e-09) Point2D | Point3D [source]¶
Return the point on segment closest to point (inclusive ends).
- geo.closest_points_segments_2d(seg1: Segment2D, seg2: Segment2D, *, epsilon: float = 1e-09) Tuple[Point2D, Point2D] [source]¶
Pair of closest points (p_on_seg1, p_on_seg2) for two 2D segments.
- geo.constrained_delaunay_triangulation(polygon: Polygon) List[Triangle] [source]¶
Placeholder for Constrained Delaunay Triangulation that preserves polygon edges. Not implemented.
- Parameters:
polygon – Polygon to triangulate.
- Raises:
NotImplementedError –
- geo.convex_hull_2d_monotone_chain(points: Sequence[Point2D], *, keep_collinear: bool = False) List[Point2D] [source]¶
Andrew monotone-chain convex hull.
- Parameters:
points – The input point cloud (any iterable).
keep_collinear – False (default) removes collinear points on edges of the hull, returning the minimal vertex set. True keeps them.
- geo.convex_hull_3d(points: Sequence[Point3D]) Polyhedron [source]¶
Compute the 3‑D convex hull using SciPy.
Returns a
Polyhedron
whose vertices are the unique points of points and faces given by the SciPy simplices (oriented CCW seen from outside).
- geo.delaunay_triangulation_points_2d(points: Sequence[Point2D]) List[Triangle] [source]¶
Computes the Delaunay triangulation of a set of 2D points.
- Parameters:
points – Sequence of Point2D objects.
- Returns:
List of Triangle objects forming the Delaunay triangulation.
- Raises:
ValueError if fewer than 3 points are provided. –
- geo.distance_line_line_3d(line1: Line3D, line2: Line3D, *, epsilon: float = 1e-09) Tuple[float, Point3D | None, Point3D | None] [source]¶
Shortest distance between two 3D infinite lines plus closest points.
Parallel lines - returns the perpendicular distance, points None.
Intersecting lines - distance 0, identical closest points.
Skew lines - distance > 0 and the unique closest points on each line.
- geo.distance_point_line_3d(point: Point3D, line: Line3D) float [source]¶
Alias for line.distance_to_point(point) kept for API symmetry.
- geo.distance_point_plane(point: Point3D, plane: Plane) float [source]¶
Alias for plane.distance_to_point(point) kept for API symmetry.
- geo.distance_segment_segment_2d(seg1: Segment2D, seg2: Segment2D, *, epsilon: float = 1e-09) float [source]¶
Shortest distance between two closed 2D segments (0 if they touch).
- geo.format_point_to_string(point: Point2D | Point3D, delimiter: str = ', ', precision: int = 6) str [source]¶
Formats a Point2D or Point3D object into a string.
- geo.is_equal(a: float, b: float, epsilon: float = 1e-09) bool [source]¶
Checks if two floating-point numbers are equal within a specified tolerance.
- Parameters:
a – The first float.
b – The second float.
epsilon – The tolerance. Defaults to DEFAULT_EPSILON.
- Returns:
True if the absolute difference between a and b is less than epsilon, False otherwise.
- geo.is_negative(a: float, epsilon: float = 1e-09) bool [source]¶
Checks if a floating-point number is definitively negative (less than -epsilon).
- Parameters:
a – The float to check.
epsilon – The tolerance. Defaults to DEFAULT_EPSILON.
- Returns:
True if a is less than -epsilon, False otherwise.
- geo.is_polygon_simple(polygon: Polygon, epsilon: float = 1e-09) bool [source]¶
Checks if a polygon is simple (i.e., edges do not intersect except at shared vertices).
- geo.is_positive(a: float, epsilon: float = 1e-09) bool [source]¶
Checks if a floating-point number is definitively positive (greater than epsilon).
- Parameters:
a – The float to check.
epsilon – The tolerance. Defaults to DEFAULT_EPSILON.
- Returns:
True if a is greater than epsilon, False otherwise.
- geo.is_zero(a: float, epsilon: float = 1e-09) bool [source]¶
Checks if a floating-point number is close enough to zero.
- Parameters:
a – The float to check.
epsilon – The tolerance. Defaults to DEFAULT_EPSILON.
- Returns:
True if the absolute value of a is less than epsilon, False otherwise.
- geo.line_polygon_intersections(line: Line2D, polygon: Polygon, epsilon: float = 1e-09) List[Point2D] [source]¶
Finds all intersection points between an infinite line and a polygon’s edges.
- Parameters:
line – The Line2D.
polygon – The Polygon.
epsilon – Tolerance for floating point comparisons.
- Returns:
A list of unique Point2D intersection points.
- geo.line_triangle_intersection_moller_trumbore(ray_origin: Point3D, ray_direction: Vector3D, tri_v0: Point3D, tri_v1: Point3D, tri_v2: Point3D, epsilon: float = 1e-09, cull_back_faces: bool = False) Tuple[Point3D, float] | None [source]¶
Möller-Trumbore ray-triangle intersection.
- Parameters:
ray_origin – Ray or line origin.
ray_direction – Direction vector (not necessarily normalized).
tri_v0 – Triangle vertices.
tri_v1 – Triangle vertices.
tri_v2 – Triangle vertices.
epsilon – Numerical tolerance.
cull_back_faces – Ignore intersections with back faces if True.
- Returns:
Tuple of (intersection_point, t_parameter) if intersection occurs. None otherwise.
- geo.load_polygon2d_from_csv(file_path: str | PathLike, delimiter: str = ',', encoding: str = 'utf-8') Polygon [source]¶
Loads a 2D Polygon from a CSV file.
- geo.load_polyhedron_from_obj_simple(file_path: str | PathLike, encoding: str = 'utf-8') Polyhedron [source]¶
Loads a Polyhedron from a simplified OBJ file (vertices and faces only).
- geo.parse_points_from_string(data_string: str, delimiter: str = ',', point_dim: int = 2) list[Point2D | Point3D] [source]¶
Parses a string of coordinates into a list of Point2D or Point3D objects. Supports 2D and 3D points; validates for supported dimensions.
- geo.plane_plane_intersection(plane1: Plane, plane2: Plane, epsilon: float = 1e-09, debug: bool = False) Line3D | None [source]¶
Compute the intersection line of two planes.
- Returns:
Line3D if planes intersect in a line. None if planes are parallel or coincident (no unique line).
If debug=True, logs warnings if numerical inconsistencies occur.
- geo.plot_convex_hull_2d(points: Sequence[Point2D], hull: Sequence[Point2D] | None = None, *, ax=None, show: bool = True, point_kwargs=None, hull_kwargs=None)[source]¶
Quick matplotlib visualisation of a 2D hull.
- geo.plot_convex_hull_3d(points: Sequence[Point3D], hull: Polyhedron | None = None, *, ax=None, show: bool = True)[source]¶
Matplotlib 3D plot of point cloud and its convex hull triangles.
- geo.point_in_convex_polygon_2d(point: Point2D, polygon: Polygon, epsilon: float = 1e-09) bool [source]¶
Checks if a point is inside or on the boundary of a convex polygon. Assumes vertices are ordered CCW.
The point must be left of or on every directed edge.
- geo.point_in_polyhedron_convex(point: Point3D, polyhedron: Polyhedron, epsilon: float = 1e-09) bool [source]¶
Checks if a point is inside or on the boundary of a convex polyhedron.
The point must lie on the non-positive side of all face planes (normals point outward).
- geo.point_on_polygon_boundary(point: Point2D, polygon: Polygon, epsilon: float = 1e-09) bool [source]¶
Returns True if point lies exactly on any edge of the polygon.
- geo.polyhedron_difference(a: Polyhedron, b: Polyhedron) List[Polyhedron] [source]¶
- geo.polyhedron_intersection(a: Polyhedron, b: Polyhedron) List[Polyhedron] [source]¶
- geo.polyhedron_union(a: Polyhedron, b: Polyhedron) List[Polyhedron] [source]¶
- geo.rotate_2d(entity: Point2D | Vector2D, angle_rad: float, origin: Point2D | None = None) Point2D | Vector2D [source]¶
Rotates a 2D Point or Vector counter-clockwise by a given angle around an origin.
- Parameters:
entity – The Point2D or Vector2D to rotate.
angle_rad – The angle of rotation in radians.
origin – The Point2D about which to rotate. If None, rotation is performed about the coordinate system origin (0,0). For Vectors, origin is usually ignored if it’s a direction vector. If it’s a position vector, treat it like a point for rotation logic.
- Returns:
A new Point2D or Vector2D, rotated.
- Raises:
TypeError – If the entity is not a Point2D or Vector2D.
- geo.rotate_3d(entity: Point3D | Vector3D, axis: Vector3D, angle_rad: float, origin: Point3D | None = None) Point3D | Vector3D [source]¶
Rotates a 3D Point or Vector by a given angle around an arbitrary axis. Uses Rodrigues’ rotation formula.
- Parameters:
entity – The Point3D or Vector3D to rotate.
axis – The Vector3D representing the axis of rotation. Must be non-zero.
angle_rad – The angle of rotation in radians (counter-clockwise when looking down the axis vector towards the origin of the axis).
origin –
The Point3D about which to rotate. - If entity is Point3D: If None, rotation is about the coordinate
system origin (0,0,0) along an axis passing through it.
- If entity is Vector3D: This parameter is ignored; vectors are rotated
about an axis passing through the coordinate system origin.
- Returns:
A new Point3D or Vector3D, rotated.
- Raises:
TypeError – If the entity is not Point3D/Vector3D, or axis is not Vector3D.
ValueError – If the rotation axis is a zero vector.
- geo.save_polygon2d_to_csv(polygon: Polygon, file_path: str | PathLike, delimiter: str = ',', encoding: str = 'utf-8') None [source]¶
Saves a 2D Polygon’s vertices to a CSV file (x,y per line).
- geo.save_polyhedron_to_obj_simple(polyhedron: Polyhedron, file_path: str | PathLike, precision: int = 6, encoding: str = 'utf-8') None [source]¶
Saves a Polyhedron object to a simple OBJ file format.
- geo.scale(entity: GeomEntityType, factors: float | Vector, origin: Point | None = None) GeomEntityType [source]¶
Scales a geometric entity (Point or Vector) by given factors.
- Parameters:
entity – The Point or Vector to scale.
factors –
A single float for uniform scaling across all dimensions.
A Vector of the same dimension as the entity for non-uniform scaling.
origin –
- The Point about which to scale. If None, scaling is done about the
coordinate system origin (0,0) or (0,0,0).
- For Vectors, origin is typically ignored unless the vector is treated as a
position vector relative to an origin. If scaling a direction vector, origin is usually not applicable. This implementation scales components directly.
- Returns:
A new Point or Vector of the same type as the input entity, scaled.
- Raises:
TypeError – If the entity is not a Point or Vector, or if factors type is invalid.
ValueError – If dimensions mismatch or factors are invalid.
- geo.segment_circle_intersections(segment: Segment2D, circle: Circle, epsilon: float = 1e-09) List[Point2D] [source]¶
Finds intersection points between a line segment and a circle.
- Parameters:
segment – The Segment2D.
circle – The Circle.
epsilon – Tolerance for floating point comparisons.
- Returns:
A list of unique Point2D intersection points.
- geo.segment_contains_point_collinear(line_origin: Point2D, line_dir: Vector2D, pt_to_check: Point2D, seg_p1: Point2D, seg_p2: Point2D, epsilon: float) bool [source]¶
Helper for line_polygon_intersections: checks if pt_to_check (known collinear with line) is on segment.
- Parameters:
line_origin – Origin point of the line.
line_dir – Direction vector of the line.
pt_to_check – The point to check.
seg_p1 – Segment endpoint 1.
seg_p2 – Segment endpoint 2.
epsilon – Tolerance for floating point comparisons.
- Returns:
True if pt_to_check lies on the segment, False otherwise.
- geo.segment_segment_intersection_detail(seg1: Segment2D, seg2: Segment2D, epsilon: float = 1e-09) Tuple[Literal['none', 'point', 'overlap', 'collinear_no_overlap'], Point2D | Tuple[Point2D, Point2D] | None] [source]¶
Determines the intersection of two 2D line segments with more detail.
- Parameters:
seg1 – The first Segment2D.
seg2 – The second Segment2D.
epsilon – Tolerance for floating point comparisons.
- Returns:
IntersectionType: “none”, “point”, “overlap”, “collinear_no_overlap”.
- Optional[Union[Point2D, Tuple[Point2D, Point2D]]]:
If “point”, the intersection Point2D.
If “overlap”, a tuple of two Point2Ds representing the overlapping segment.
None otherwise.
- Return type:
A tuple
- geo.signed_angle_between_vectors_2d(v1: Vector2D, v2: Vector2D) float [source]¶
Signed angle v1 → v2 in radians (CCW positive, range (-π, π]).
- geo.sphere_sphere_intersection(s1: Sphere, s2: Sphere, epsilon: float = 1e-09) SphereSphereIntersectionResult [source]¶
Calculate intersection between two spheres.
- Returns:
type ‘none’ if no intersection.
type ‘point’ with point attribute if tangent.
type ‘circle’ with center, radius, and normal if intersect in circle.
type ‘coincident’ if spheres are coincident.
- Return type:
- geo.tetrahedralise(points: Sequence[Point3D]) List[Tuple[Point3D, Point3D, Point3D, Point3D]] [source]¶
Computes the 3D Delaunay tetrahedralization of a set of 3D points.
- Parameters:
points – Sequence of Point3D objects.
- Returns:
List of tetrahedra, each represented by a tuple of four Point3D vertices.
- Raises:
ValueError if fewer than 4 points are provided. –
- geo.translate(entity: GeomEntityType, offset: Vector) GeomEntityType [source]¶
Translates a geometric entity (Point or Vector) by an offset vector.
- Parameters:
entity – The Point or Vector to translate.
offset – The Vector representing the translation.
- Returns:
A new Point or Vector of the same type as the input entity, translated.
- Raises:
TypeError – If the entity is not a Point or Vector, or if dimensions mismatch.
ValueError – If dimensions of entity and offset vector do not match.
- geo.triangulate_simple_polygon_ear_clipping(polygon: Polygon, ensure_ccw: bool = True) List[Triangle] [source]¶
Triangulates a simple 2D polygon using the Ear Clipping (Ear Cutting) method. Assumes the polygon is simple (no self-intersections). Vertices should be ordered (e.g., counter-clockwise for this implementation).
- Parameters:
polygon – The simple Polygon to triangulate.
ensure_ccw – If True, ensures polygon vertices are CCW. If False, assumes they are.
- Returns:
A list of Triangle objects that form the triangulation. Returns empty list if polygon has < 3 vertices or is degenerate.
- geo.validate_list_of_points(points: Sequence[Any], min_points: int = 0, point_type: Type[Point2D] | Type[Point3D] | None = None, name: str = 'Point list') None [source]¶
Validates if the input is a sequence of Point2D or Point3D objects.
- Parameters:
points – The sequence to validate.
min_points – Minimum number of points required in the sequence.
point_type – Expected type of points (Point2D or Point3D). If None, allows either.
name – Name of the list (for error messages).
- Raises:
TypeError – If points is not a sequence or contains non-Point objects.
ValueError – If the number of points is less than min_points.
- geo.validate_non_negative(value: int | float, name: str = 'Value') None [source]¶
Validates if a numeric value is non-negative.
- Parameters:
value – The numeric value to check.
name – The name of the value (for error messages).
- Raises:
ValueError – If the value is negative.
TypeError – If the value is not numeric.
- geo.validate_polygon_vertices(vertices: ~typing.Sequence[~typing.Any], point_type: ~typing.Type[~geo.core.point.Point2D] = <class 'geo.core.point.Point2D'>, name: str = 'Polygon vertices') None [source]¶
Validates vertices for a Polygon. Specifically for 2D polygons.
- Parameters:
vertices – Sequence of potential vertices.
point_type – Expected type of point (default Point2D).
name – Name for error messages.
- Raises:
TypeError – If vertices is not a sequence or elements are not of point_type.
ValueError – If fewer than 3 vertices are provided.
- geo.validate_positive(value: int | float, name: str = 'Value') None [source]¶
Validates if a numeric value is strictly positive.
- Parameters:
value – The numeric value to check.
name – The name of the value (for error messages).
- Raises:
ValueError – If the value is not positive.
TypeError – If the value is not numeric.
Core module for the geo package. This module aggregates the fundamental classes and functions from its submodules, making them easily accessible from the ‘core’ namespace.
- class geo.core.Point(*coords: TCoord)[source]¶
Bases:
Generic
[TCoord
]A base class for a point in N-dimensional space. Not intended for direct instantiation for specific dimensions, but provides common functionality.
- property coords: Sequence[TCoord]¶
Returns the coordinates of the point as a tuple.
- property dimension: int¶
Returns the dimension of the point.
- class geo.core.Point2D(x: float, y: float)[source]¶
Bases:
Point
[float
]Represents a point in 2D space.
- classmethod from_polar(r: float, theta: float) Point2D [source]¶
Creates a Point2D from polar coordinates.
- Parameters:
r – The radius.
theta – The angle in radians.
- Returns:
A new Point2D object.
- to_polar() tuple[float, float] [source]¶
Converts Cartesian coordinates to polar coordinates.
- Returns:
A tuple (r, theta) where r is the radius and theta is the angle in radians. Angle is in the range (-pi, pi].
- property x: float¶
Returns the x-coordinate.
- property y: float¶
Returns the y-coordinate.
- class geo.core.Point3D(x: float, y: float, z: float)[source]¶
Bases:
Point
[float
]Represents a point in 3D space.
- classmethod from_spherical(r: float, theta: float, phi: float) Point3D [source]¶
Creates a Point3D from spherical coordinates (ISO 80000-2:2019 convention).
- Parameters:
r – Radial distance (must be non-negative).
theta – Inclination (polar angle from positive z-axis), in radians [0, pi].
phi – Azimuth (angle from positive x-axis in xy-plane), in radians.
- Returns:
A new Point3D object.
- to_spherical() tuple[float, float, float] [source]¶
Converts Cartesian coordinates to spherical coordinates (ISO 80000-2:2019 convention). r: radial distance theta: inclination (polar angle, angle from positive z-axis), range [0, pi] phi: azimuth (angle from positive x-axis in xy-plane), range (-pi, pi]
- Returns:
A tuple (r, theta, phi).
- property x: float¶
Returns the x-coordinate.
- property y: float¶
Returns the y-coordinate.
- property z: float¶
Returns the z-coordinate.
- class geo.core.Vector(*components: TComponent)[source]¶
Bases:
Generic
[TComponent
]A base class for a vector in N-dimensional space. Provides common vector operations.
- angle_between(other: Vector[TComponent], in_degrees: bool = False) float [source]¶
Calculates the angle between this vector and another vector.
- Parameters:
other – The other Vector object.
in_degrees – If True, returns the angle in degrees. Otherwise, in radians.
- Returns:
The angle in radians or degrees.
- Raises:
ValueError – If either vector is a zero vector or dimensions mismatch.
- property components: Sequence[TComponent]¶
Returns the components of the vector as a tuple.
- property dimension: int¶
Returns the dimension of the vector.
- dot(other: Vector[TComponent]) float [source]¶
Calculates the dot product with another vector.
- Parameters:
other – The other Vector object.
- Returns:
The dot product.
- Raises:
ValueError – If the vectors have different dimensions.
- class geo.core.Vector2D(x: float, y: float)[source]¶
Bases:
Vector
[float
]Represents a vector in 2D space.
- angle() float [source]¶
Calculates the angle of the vector with respect to the positive x-axis. The angle is in radians, in the range (-pi, pi].
- cross(other: Vector2D) float [source]¶
Calculates the 2D cross product (magnitude of the 3D cross product’s z-component). This is a scalar value: self.x * other.y - self.y * other.x. It’s useful for determining orientation or signed area.
- Parameters:
other – The other Vector2D object.
- Returns:
The scalar result of the 2D cross product.
- perpendicular(clockwise: bool = False) Vector2D [source]¶
Returns a 2D vector perpendicular to this one. By default, returns the counter-clockwise perpendicular vector (-y, x).
- Parameters:
clockwise – If True, returns the clockwise perpendicular vector (y, -x).
- Returns:
A new Vector2D perpendicular to this one.
- property x: float¶
Returns the x-component.
- property y: float¶
Returns the y-component.
- class geo.core.Vector3D(x: float, y: float, z: float)[source]¶
Bases:
Vector
[float
]Represents a vector in 3D space.
- cross(other: Vector3D) Vector3D [source]¶
Calculates the 3D cross product with another vector.
- Parameters:
other – The other Vector3D object.
- Returns:
A new Vector3D representing the cross product.
- property x: float¶
Returns the x-component.
- property y: float¶
Returns the y-component.
- property z: float¶
Returns the z-component.
- geo.core.is_equal(a: float, b: float, epsilon: float = 1e-09) bool [source]¶
Checks if two floating-point numbers are equal within a specified tolerance.
- Parameters:
a – The first float.
b – The second float.
epsilon – The tolerance. Defaults to DEFAULT_EPSILON.
- Returns:
True if the absolute difference between a and b is less than epsilon, False otherwise.
- geo.core.is_negative(a: float, epsilon: float = 1e-09) bool [source]¶
Checks if a floating-point number is definitively negative (less than -epsilon).
- Parameters:
a – The float to check.
epsilon – The tolerance. Defaults to DEFAULT_EPSILON.
- Returns:
True if a is less than -epsilon, False otherwise.
- geo.core.is_positive(a: float, epsilon: float = 1e-09) bool [source]¶
Checks if a floating-point number is definitively positive (greater than epsilon).
- Parameters:
a – The float to check.
epsilon – The tolerance. Defaults to DEFAULT_EPSILON.
- Returns:
True if a is greater than epsilon, False otherwise.
- geo.core.is_zero(a: float, epsilon: float = 1e-09) bool [source]¶
Checks if a floating-point number is close enough to zero.
- Parameters:
a – The float to check.
epsilon – The tolerance. Defaults to DEFAULT_EPSILON.
- Returns:
True if the absolute value of a is less than epsilon, False otherwise.
- geo.core.rotate_2d(entity: Point2D | Vector2D, angle_rad: float, origin: Point2D | None = None) Point2D | Vector2D [source]¶
Rotates a 2D Point or Vector counter-clockwise by a given angle around an origin.
- Parameters:
entity – The Point2D or Vector2D to rotate.
angle_rad – The angle of rotation in radians.
origin – The Point2D about which to rotate. If None, rotation is performed about the coordinate system origin (0,0). For Vectors, origin is usually ignored if it’s a direction vector. If it’s a position vector, treat it like a point for rotation logic.
- Returns:
A new Point2D or Vector2D, rotated.
- Raises:
TypeError – If the entity is not a Point2D or Vector2D.
- geo.core.rotate_3d(entity: Point3D | Vector3D, axis: Vector3D, angle_rad: float, origin: Point3D | None = None) Point3D | Vector3D [source]¶
Rotates a 3D Point or Vector by a given angle around an arbitrary axis. Uses Rodrigues’ rotation formula.
- Parameters:
entity – The Point3D or Vector3D to rotate.
axis – The Vector3D representing the axis of rotation. Must be non-zero.
angle_rad – The angle of rotation in radians (counter-clockwise when looking down the axis vector towards the origin of the axis).
origin –
The Point3D about which to rotate. - If entity is Point3D: If None, rotation is about the coordinate
system origin (0,0,0) along an axis passing through it.
- If entity is Vector3D: This parameter is ignored; vectors are rotated
about an axis passing through the coordinate system origin.
- Returns:
A new Point3D or Vector3D, rotated.
- Raises:
TypeError – If the entity is not Point3D/Vector3D, or axis is not Vector3D.
ValueError – If the rotation axis is a zero vector.
- geo.core.scale(entity: GeomEntityType, factors: float | Vector, origin: Point | None = None) GeomEntityType [source]¶
Scales a geometric entity (Point or Vector) by given factors.
- Parameters:
entity – The Point or Vector to scale.
factors –
A single float for uniform scaling across all dimensions.
A Vector of the same dimension as the entity for non-uniform scaling.
origin –
- The Point about which to scale. If None, scaling is done about the
coordinate system origin (0,0) or (0,0,0).
- For Vectors, origin is typically ignored unless the vector is treated as a
position vector relative to an origin. If scaling a direction vector, origin is usually not applicable. This implementation scales components directly.
- Returns:
A new Point or Vector of the same type as the input entity, scaled.
- Raises:
TypeError – If the entity is not a Point or Vector, or if factors type is invalid.
ValueError – If dimensions mismatch or factors are invalid.
- geo.core.translate(entity: GeomEntityType, offset: Vector) GeomEntityType [source]¶
Translates a geometric entity (Point or Vector) by an offset vector.
- Parameters:
entity – The Point or Vector to translate.
offset – The Vector representing the translation.
- Returns:
A new Point or Vector of the same type as the input entity, translated.
- Raises:
TypeError – If the entity is not a Point or Vector, or if dimensions mismatch.
ValueError – If dimensions of entity and offset vector do not match.
Operations module for the geometry package.
This module provides functions for various geometric operations and algorithms, such as intersection detection, measurements, containment checks, etc.
- class geo.operations.AABB(min_pt: Point3D, max_pt: Point3D)[source]¶
Bases:
object
Axis-Aligned Bounding Box.
- class geo.operations.SphereSphereIntersectionResult(type: str, point: Point3D | None = None, circle_center: Point3D | None = None, circle_radius: float | None = None, circle_normal: Vector3D | None = None)[source]¶
Bases:
object
Result for sphere-sphere intersection.
- circle_radius: float | None = None¶
- type: str¶
- geo.operations.check_point_left_of_line(point: Point2D, line_p1: Point2D, line_p2: Point2D) float [source]¶
Returns > 0 if point is left of the directed line from line_p1 to line_p2, < 0 if right, and 0 if collinear.
- geo.operations.clip_polygon_sutherland_hodgman(subject: Polygon, clip: Polygon) Polygon | None [source]¶
Clip subject (any polygon, CW or CCW) against convex clip (CCW).
Returns clipped polygon or None if empty.
- geo.operations.closest_point_on_segment_to_point(segment: Segment2D | Segment3D, point: Point2D | Point3D, *, epsilon: float = 1e-09) Point2D | Point3D [source]¶
Return the point on segment closest to point (inclusive ends).
- geo.operations.closest_points_segments_2d(seg1: Segment2D, seg2: Segment2D, *, epsilon: float = 1e-09) Tuple[Point2D, Point2D] [source]¶
Pair of closest points (p_on_seg1, p_on_seg2) for two 2D segments.
- geo.operations.constrained_delaunay_triangulation(polygon: Polygon) List[Triangle] [source]¶
Placeholder for Constrained Delaunay Triangulation that preserves polygon edges. Not implemented.
- Parameters:
polygon – Polygon to triangulate.
- Raises:
NotImplementedError –
- geo.operations.convex_hull_2d_monotone_chain(points: Sequence[Point2D], *, keep_collinear: bool = False) List[Point2D] [source]¶
Andrew monotone-chain convex hull.
- Parameters:
points – The input point cloud (any iterable).
keep_collinear – False (default) removes collinear points on edges of the hull, returning the minimal vertex set. True keeps them.
- geo.operations.convex_hull_3d(points: Sequence[Point3D]) Polyhedron [source]¶
Compute the 3‑D convex hull using SciPy.
Returns a
Polyhedron
whose vertices are the unique points of points and faces given by the SciPy simplices (oriented CCW seen from outside).
- geo.operations.delaunay_triangulation_points_2d(points: Sequence[Point2D]) List[Triangle] [source]¶
Computes the Delaunay triangulation of a set of 2D points.
- Parameters:
points – Sequence of Point2D objects.
- Returns:
List of Triangle objects forming the Delaunay triangulation.
- Raises:
ValueError if fewer than 3 points are provided. –
- geo.operations.distance_line_line_3d(line1: Line3D, line2: Line3D, *, epsilon: float = 1e-09) Tuple[float, Point3D | None, Point3D | None] [source]¶
Shortest distance between two 3D infinite lines plus closest points.
Parallel lines - returns the perpendicular distance, points None.
Intersecting lines - distance 0, identical closest points.
Skew lines - distance > 0 and the unique closest points on each line.
- geo.operations.distance_point_line_3d(point: Point3D, line: Line3D) float [source]¶
Alias for line.distance_to_point(point) kept for API symmetry.
- geo.operations.distance_point_plane(point: Point3D, plane: Plane) float [source]¶
Alias for plane.distance_to_point(point) kept for API symmetry.
- geo.operations.distance_segment_segment_2d(seg1: Segment2D, seg2: Segment2D, *, epsilon: float = 1e-09) float [source]¶
Shortest distance between two closed 2D segments (0 if they touch).
- geo.operations.is_polygon_simple(polygon: Polygon, epsilon: float = 1e-09) bool [source]¶
Checks if a polygon is simple (i.e., edges do not intersect except at shared vertices).
- geo.operations.line_polygon_intersections(line: Line2D, polygon: Polygon, epsilon: float = 1e-09) List[Point2D] [source]¶
Finds all intersection points between an infinite line and a polygon’s edges.
- Parameters:
line – The Line2D.
polygon – The Polygon.
epsilon – Tolerance for floating point comparisons.
- Returns:
A list of unique Point2D intersection points.
- geo.operations.line_triangle_intersection_moller_trumbore(ray_origin: Point3D, ray_direction: Vector3D, tri_v0: Point3D, tri_v1: Point3D, tri_v2: Point3D, epsilon: float = 1e-09, cull_back_faces: bool = False) Tuple[Point3D, float] | None [source]¶
Möller-Trumbore ray-triangle intersection.
- Parameters:
ray_origin – Ray or line origin.
ray_direction – Direction vector (not necessarily normalized).
tri_v0 – Triangle vertices.
tri_v1 – Triangle vertices.
tri_v2 – Triangle vertices.
epsilon – Numerical tolerance.
cull_back_faces – Ignore intersections with back faces if True.
- Returns:
Tuple of (intersection_point, t_parameter) if intersection occurs. None otherwise.
- geo.operations.plane_plane_intersection(plane1: Plane, plane2: Plane, epsilon: float = 1e-09, debug: bool = False) Line3D | None [source]¶
Compute the intersection line of two planes.
- Returns:
Line3D if planes intersect in a line. None if planes are parallel or coincident (no unique line).
If debug=True, logs warnings if numerical inconsistencies occur.
- geo.operations.plot_convex_hull_2d(points: Sequence[Point2D], hull: Sequence[Point2D] | None = None, *, ax=None, show: bool = True, point_kwargs=None, hull_kwargs=None)[source]¶
Quick matplotlib visualisation of a 2D hull.
- geo.operations.plot_convex_hull_3d(points: Sequence[Point3D], hull: Polyhedron | None = None, *, ax=None, show: bool = True)[source]¶
Matplotlib 3D plot of point cloud and its convex hull triangles.
- geo.operations.point_in_convex_polygon_2d(point: Point2D, polygon: Polygon, epsilon: float = 1e-09) bool [source]¶
Checks if a point is inside or on the boundary of a convex polygon. Assumes vertices are ordered CCW.
The point must be left of or on every directed edge.
- geo.operations.point_in_polyhedron_convex(point: Point3D, polyhedron: Polyhedron, epsilon: float = 1e-09) bool [source]¶
Checks if a point is inside or on the boundary of a convex polyhedron.
The point must lie on the non-positive side of all face planes (normals point outward).
- geo.operations.point_on_polygon_boundary(point: Point2D, polygon: Polygon, epsilon: float = 1e-09) bool [source]¶
Returns True if point lies exactly on any edge of the polygon.
- geo.operations.polyhedron_difference(a: Polyhedron, b: Polyhedron) List[Polyhedron] [source]¶
- geo.operations.polyhedron_intersection(a: Polyhedron, b: Polyhedron) List[Polyhedron] [source]¶
- geo.operations.polyhedron_union(a: Polyhedron, b: Polyhedron) List[Polyhedron] [source]¶
- geo.operations.segment_circle_intersections(segment: Segment2D, circle: Circle, epsilon: float = 1e-09) List[Point2D] [source]¶
Finds intersection points between a line segment and a circle.
- Parameters:
segment – The Segment2D.
circle – The Circle.
epsilon – Tolerance for floating point comparisons.
- Returns:
A list of unique Point2D intersection points.
- geo.operations.segment_contains_point_collinear(line_origin: Point2D, line_dir: Vector2D, pt_to_check: Point2D, seg_p1: Point2D, seg_p2: Point2D, epsilon: float) bool [source]¶
Helper for line_polygon_intersections: checks if pt_to_check (known collinear with line) is on segment.
- Parameters:
line_origin – Origin point of the line.
line_dir – Direction vector of the line.
pt_to_check – The point to check.
seg_p1 – Segment endpoint 1.
seg_p2 – Segment endpoint 2.
epsilon – Tolerance for floating point comparisons.
- Returns:
True if pt_to_check lies on the segment, False otherwise.
- geo.operations.segment_segment_intersection_detail(seg1: Segment2D, seg2: Segment2D, epsilon: float = 1e-09) Tuple[Literal['none', 'point', 'overlap', 'collinear_no_overlap'], Point2D | Tuple[Point2D, Point2D] | None] [source]¶
Determines the intersection of two 2D line segments with more detail.
- Parameters:
seg1 – The first Segment2D.
seg2 – The second Segment2D.
epsilon – Tolerance for floating point comparisons.
- Returns:
IntersectionType: “none”, “point”, “overlap”, “collinear_no_overlap”.
- Optional[Union[Point2D, Tuple[Point2D, Point2D]]]:
If “point”, the intersection Point2D.
If “overlap”, a tuple of two Point2Ds representing the overlapping segment.
None otherwise.
- Return type:
A tuple
- geo.operations.signed_angle_between_vectors_2d(v1: Vector2D, v2: Vector2D) float [source]¶
Signed angle v1 → v2 in radians (CCW positive, range (-π, π]).
- geo.operations.sphere_sphere_intersection(s1: Sphere, s2: Sphere, epsilon: float = 1e-09) SphereSphereIntersectionResult [source]¶
Calculate intersection between two spheres.
- Returns:
type ‘none’ if no intersection.
type ‘point’ with point attribute if tangent.
type ‘circle’ with center, radius, and normal if intersect in circle.
type ‘coincident’ if spheres are coincident.
- Return type:
- geo.operations.tetrahedralise(points: Sequence[Point3D]) List[Tuple[Point3D, Point3D, Point3D, Point3D]] [source]¶
Computes the 3D Delaunay tetrahedralization of a set of 3D points.
- Parameters:
points – Sequence of Point3D objects.
- Returns:
List of tetrahedra, each represented by a tuple of four Point3D vertices.
- Raises:
ValueError if fewer than 4 points are provided. –
- geo.operations.triangulate_simple_polygon_ear_clipping(polygon: Polygon, ensure_ccw: bool = True) List[Triangle] [source]¶
Triangulates a simple 2D polygon using the Ear Clipping (Ear Cutting) method. Assumes the polygon is simple (no self-intersections). Vertices should be ordered (e.g., counter-clockwise for this implementation).
- Parameters:
polygon – The simple Polygon to triangulate.
ensure_ccw – If True, ensures polygon vertices are CCW. If False, assumes they are.
- Returns:
A list of Triangle objects that form the triangulation. Returns empty list if polygon has < 3 vertices or is degenerate.
Utilities sub-package for the geometry library.
Contains helper functions for validation, I/O, and other miscellaneous tasks that are not core geometric primitives or operations but support the library.
- geo.utils.format_point_to_string(point: Point2D | Point3D, delimiter: str = ', ', precision: int = 6) str [source]¶
Formats a Point2D or Point3D object into a string.
- geo.utils.load_polygon2d_from_csv(file_path: str | PathLike, delimiter: str = ',', encoding: str = 'utf-8') Polygon [source]¶
Loads a 2D Polygon from a CSV file.
- geo.utils.load_polygon2d_from_json(file_path: str | PathLike, encoding: str = 'utf-8') Polygon [source]¶
Loads a 2D Polygon from a JSON file containing a list of point dictionaries.
- geo.utils.load_polyhedron_from_obj_simple(file_path: str | PathLike, encoding: str = 'utf-8') Polyhedron [source]¶
Loads a Polyhedron from a simplified OBJ file (vertices and faces only).
- geo.utils.parse_points_from_string(data_string: str, delimiter: str = ',', point_dim: int = 2) list[Point2D | Point3D] [source]¶
Parses a string of coordinates into a list of Point2D or Point3D objects. Supports 2D and 3D points; validates for supported dimensions.
- geo.utils.save_polygon2d_to_csv(polygon: Polygon, file_path: str | PathLike, delimiter: str = ',', encoding: str = 'utf-8') None [source]¶
Saves a 2D Polygon’s vertices to a CSV file (x,y per line).
- geo.utils.save_polygon2d_to_json(polygon: Polygon, file_path: str | PathLike, encoding: str = 'utf-8') None [source]¶
Saves a 2D Polygon to a JSON file with a list of point dictionaries.
- geo.utils.save_polyhedron_to_obj_simple(polyhedron: Polyhedron, file_path: str | PathLike, precision: int = 6, encoding: str = 'utf-8') None [source]¶
Saves a Polyhedron object to a simple OBJ file format.
- geo.utils.validate_list_of_points(points: Sequence[Any], min_points: int = 0, point_type: Type[Point2D] | Type[Point3D] | None = None, name: str = 'Point list') None [source]¶
Validates if the input is a sequence of Point2D or Point3D objects.
- Parameters:
points – The sequence to validate.
min_points – Minimum number of points required in the sequence.
point_type – Expected type of points (Point2D or Point3D). If None, allows either.
name – Name of the list (for error messages).
- Raises:
TypeError – If points is not a sequence or contains non-Point objects.
ValueError – If the number of points is less than min_points.
- geo.utils.validate_non_negative(value: int | float, name: str = 'Value') None [source]¶
Validates if a numeric value is non-negative.
- Parameters:
value – The numeric value to check.
name – The name of the value (for error messages).
- Raises:
ValueError – If the value is negative.
TypeError – If the value is not numeric.
- geo.utils.validate_polygon_vertices(vertices: ~typing.Sequence[~typing.Any], point_type: ~typing.Type[~geo.core.point.Point2D] = <class 'geo.core.point.Point2D'>, name: str = 'Polygon vertices') None [source]¶
Validates vertices for a Polygon. Specifically for 2D polygons.
- Parameters:
vertices – Sequence of potential vertices.
point_type – Expected type of point (default Point2D).
name – Name for error messages.
- Raises:
TypeError – If vertices is not a sequence or elements are not of point_type.
ValueError – If fewer than 3 vertices are provided.
- geo.utils.validate_positive(value: int | float, name: str = 'Value') None [source]¶
Validates if a numeric value is strictly positive.
- Parameters:
value – The numeric value to check.
name – The name of the value (for error messages).
- Raises:
ValueError – If the value is not positive.
TypeError – If the value is not numeric.