Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

raygeo

PyPI CI

A high-performance 2D/3D geometry library for Python, built in Rust with PyO3.

raygeo provides vector path construction, polygon boolean operations, curve fitting, path transformations, and geometric queries — all backed by a native Rust extension.

Showcase

Concave hull, arc fitting, nesting, directional bites, raster power modulation, smoothing, linearization, HSM peeling, cylindrical transform, conical helix, 3D polyline offset, and 3D fillet polyline

Installation

pip install raygeo

Requires Python 3.10+ and a compatible platform (Linux, Windows, macOS Intel, or macOS Apple Silicon). Pre-compiled wheels are available on PyPI.

Quick Start

Building Paths

The Geometry class is the core abstraction. It stores a vector path as a sequence of move, line, arc, and cubic Bezier commands. All mutating methods return self for chaining:

from raygeo.geo import Geometry

# Create a 10x10 square
g = Geometry()
g.move_to(0, 0)
g.line_to(10, 0)
g.line_to(10, 10)
g.line_to(0, 10)
g.close_path()

print(g.area())    # 100.0
print(g.rect())    # (0.0, 0.0, 10.0, 10.0)
print(g.is_closed())  # True

Builder methods can be chained:

g = Geometry()
g.move_to(0, 0).line_to(10, 0).line_to(10, 10).line_to(0, 10).close_path()

You can also create paths from point lists:

triangle = Geometry.from_points([(0, 0), (10, 0), (5, 8.66)])

Arcs and Bezier Curves

g = Geometry()
g.move_to(0, 0)
g.arc_to(10, 0, i=5, j=0, clockwise=False)  # semicircular arc
g.close_path()

# Bezier curves
g2 = Geometry()
g2.move_to(0, 0)
g2.bezier_to(10, 0, c1x=3, c1y=5, c2x=7, c2y=5)

# Convert arcs to Bezier curves (for non-uniform scaling)
g3 = Geometry()
g3.move_to(0, 0)
g3.arc_to_as_bezier(10, 0, i=5, j=0)
g3.upgrade_to_scalable()

Path Analysis

print(g.distance())       # total path length
print(g.area())           # signed enclosed area
print(g.rect())           # bounding box (x_min, y_min, x_max, y_max)
print(g.is_closed())      # path closure check
print(g.segments())       # split into sub-paths

# Find closest point on path
result = g.find_closest_point(5, 5)  # (segment_index, t, (x, y)) or None

# Point and tangent at parameter t on a segment
point = g.get_point_at(segment_index=0, t=0.5)
tangent = g.get_tangent_at(segment_index=0, t=0.5)

Transformations

All transformation methods mutate the geometry in place and return self, allowing chaining. Use .copy() first if you need to preserve the original:

import numpy as np
from raygeo.geo import Geometry

g = Geometry.from_points([(0, 0), (10, 0), (10, 10), (0, 10)])

# Offset (grow/shrink) — mutates in place
g.grow(1.0)   # offset outward by 1 unit (each side moves by the amount)
print(g.area())  # 144.0 — 12×12

# Use .copy() to preserve the original
original = Geometry.from_points([(0, 0), (10, 0), (10, 10), (0, 10)])
shrunk = original.copy()
shrunk.grow(-1.0)  # offset inward by 1 unit

# Affine transform (4x4 matrix) — mutates in place
matrix = [
    [1, 0, 0, 5],  # translate x by 5
    [0, 1, 0, 3],  # translate y by 3
    [0, 0, 1, 0],
    [0, 0, 0, 1],
]
g.transform(matrix)

# Map geometry into a frame — mutates in place
g.map_to_frame(
    origin=(0, 0),
    p_width=(100, 0),
    p_height=(0, 100),
)

g.flip_x()  # negate all x coordinates
g.flip_y()  # negate all y coordinates

# Chaining is possible since all methods return self
g2 = Geometry.from_points([(0, 0), (10, 0), (10, 10), (0, 10)])
g2.transform(matrix).flip_x().grow(1.0)

Contour Operations

All contour methods mutate the geometry in place and return self:

# Split into separate closed contours (returns list, does not mutate)
contours = g.split_into_contours()

# Split into disconnected components (returns list, does not mutate)
components = g.split_into_components()

# Separate holes from solids (returns tuple, does not mutate)
inner, outer = g.split_inner_and_outer_contours()

# Normalize winding orders — mutates in place
g.normalize_winding_orders()

# Filter to only external contours — mutates in place
g.filter_to_external_contours()

# Remove shared edges between sub-paths — mutates in place
g.remove_inner_edges()

Polygon Operations

The geo.shape.polygon submodule provides polygon-specific operations powered by Clipper2:

from raygeo.geo import Geometry
from raygeo.geo.shape.polygon import (
    get_polygon_area,
    get_polygon_bounds,
    offset_polygon,
    get_polygons_union,
    get_polygons_intersection,
    get_polygons_difference,
    is_point_inside_polygon,
    polygons_intersect,
    get_polygon_convex_hull,
)

square = [(0, 0), (10, 0), (10, 10), (0, 10)]
circle_approx = [(5 + 5 * math.cos(a), 5 + 5 * math.sin(a))
                 for a in [i * math.pi / 20 for i in range(40)]]

get_polygon_area(square)                # 100.0
get_polygon_bounds(square)              # (0.0, 0.0, 10.0, 10.0)
is_point_inside_polygon((5, 5), square) # True

# Boolean operations
union = get_polygons_union([square, circle_approx])
intersection = get_polygons_intersection(square, circle_approx)
difference = get_polygons_difference(square, circle_approx)

# Offset
inflated = offset_polygon(square, 2.0)

# NumPy variants are also available (suffixed with _numpy)
import numpy as np
sq_np = np.array(square)
get_polygon_area(sq_np)  # also works with numpy arrays

Curve Fitting

All fitting methods mutate the geometry in place and return self:

from raygeo.geo import Geometry

# Simplify a path
g.simplify(tolerance=0.1)

# Convert curves to line segments
g.linearize(tolerance=0.01)

# Fit arcs and beziers to linear data
g.fit_arcs(tolerance=0.5)
g.fit_curves(tolerance=0.5, beziers=True, arcs=True)

# Convert geometry to polygons (returns list, does not mutate)
polygons = g.to_polygons(tolerance=0.01)

Self-Intersection Detection

g.has_self_intersections()          # check for self-intersections
g.intersects_with(other_geometry)   # check intersection with another geometry
g.encloses(other_geometry)          # check if this fully encloses another

Serialization

# Serialize to dict (JSON-safe)
data = g.to_dict()

# Deserialize from dict
g2 = Geometry.from_dict(data)

# Pickle support (via __reduce_ex__)
import pickle
g3 = pickle.loads(pickle.dumps(g))

Documentation

Full API reference documentation is generated from the source type stubs. Run make docs to build it locally — this produces Markdown pages in docs/api/ with inline visual examples.

The docs are also published online with the RayForge Developer Docs.

Development

Prerequisites

  • Rust toolchain (latest stable)
  • Python 3.10+
  • maturin (pip install maturin)
  • Node.js (only needed for make lint-python, which runs pyright via npx)

Quick Start

# Create and activate a virtual environment (Unix)
python -m venv .venv
source .venv/bin/activate   # on Windows: .venv\Scripts\activate

# Install build tool and build the extension
pip install maturin pytest
make dev                   # builds Rust extension and installs into venv

# Run tests
make test

# Full check (lint + test)
make check

Available Make Targets

Target Description
make dev Build and install into the active venv
make build Build release wheel to dist/
make test Run pytest
make lint Lint Rust + Python (including pyright)
make format Auto-format Rust + Python
make check Lint + test
make stubs Regenerate .pyi type stubs
make docs Build API docs with inline visual examples
make visual Launch Streamlit visual test playground

Visual Testing

The make visual target launches an interactive Streamlit playground with real-time plots for geometry construction, polygon booleans, curve fitting, image processing, SVG parsing, tab operations, overscan, lead- in/out, merging, rasterization, concave hull, and nesting.

pip install -e ".[visual]"
make visual

See Visual Testing for a full walkthrough of every page and its controls.

CLI Tools

The raygeo command provides subcommands for tracing, inspecting, and profiling adaptive clearing runs.

pip install -e ".[cli]"
raygeo trace /tmp/trace.bin --scenario centre-island
raygeo inspect /tmp/trace.bin

See CLI Tools for full usage documentation.

License

MIT

Metadata

Release files for raygeo 1.68.0b2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for raygeo 1.68.0b2
File Size Uploaded Provenance Actions
raygeo-1.68.0b2.tar.gz 1.4 MB With provenance Details for raygeo-1.68.0b2.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for raygeo 1.68.0b2
File Actions
raygeo-1.68.0b2-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details for raygeo-1.68.0b2-cp311-abi3-win_amd64.whl
raygeo-1.68.0b2-cp311-abi3-manylinux_2_38_x86_64.whl CPython 3.11 abi3 Linux glibc 2.38+ x86-64 Details for raygeo-1.68.0b2-cp311-abi3-manylinux_2_38_x86_64.whl
raygeo-1.68.0b2-cp311-abi3-manylinux_2_35_aarch64.whl CPython 3.11 abi3 Linux glibc 2.35+ ARM64 Details for raygeo-1.68.0b2-cp311-abi3-manylinux_2_35_aarch64.whl
raygeo-1.68.0b2-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details for raygeo-1.68.0b2-cp311-abi3-macosx_11_0_arm64.whl
raygeo-1.68.0b2-cp311-abi3-macosx_10_12_x86_64.whl CPython 3.11 abi3 macOS 10.12+ x86-64 Details for raygeo-1.68.0b2-cp311-abi3-macosx_10_12_x86_64.whl

Total release size: 24.4 MB

Release files / raygeo-1.68.0b2.tar.gz

Download URL raygeo-1.68.0b2.tar.gz
Size 1.4 MB
Tags Source
SHA-256 checksum
How to use checksums
5153a05bff01ec4bda8fb1473ca54f1b7e04e0560b48fc42b24fc3b464933cb3
BLAKE2b-256 checksum
How to use checksums
5c8bea527a03a18014ff5a22bd7ce2233e0545c55bb62f7c9a5a2045e26d87c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Release files / raygeo-1.68.0b2-cp311-abi3-win_amd64.whl

Download URL raygeo-1.68.0b2-cp311-abi3-win_amd64.whl
Size 4.3 MB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
ac189dfc2b8ba2b877a9be3f5beb2da1474fdd60a1ae093015a41822d589e949
BLAKE2b-256 checksum
How to use checksums
fbc82f092ee5b8ba13ce58d473c3cb59b0932ddbd60801a2fdd9162f6b575198
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Release files / raygeo-1.68.0b2-cp311-abi3-manylinux_2_38_x86_64.whl

Download URL raygeo-1.68.0b2-cp311-abi3-manylinux_2_38_x86_64.whl
Size 5.0 MB
Tags CPython 3.11 Linux glibc 2.38+ x86-64 abi3
SHA-256 checksum
How to use checksums
8579c4344e2b02ac672a03a55278566d5e43ef77e8460e702721025e894080cd
BLAKE2b-256 checksum
How to use checksums
f166bebc2f7471ff7cac2345e963542dc558ad2b9774f21b563413ffb6960dda
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Release files / raygeo-1.68.0b2-cp311-abi3-manylinux_2_35_aarch64.whl

Download URL raygeo-1.68.0b2-cp311-abi3-manylinux_2_35_aarch64.whl
Size 4.9 MB
Tags CPython 3.11 Linux glibc 2.35+ ARM64 abi3
SHA-256 checksum
How to use checksums
f3d8e83b6a76beb2ebec66f52b039867d877fbcdaea0c505512a1f7510ca4705
BLAKE2b-256 checksum
How to use checksums
e89f69cf65c9d7c0b997d4d24f19a5407ce905cac550522ed7fb811aadd0f866
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Release files / raygeo-1.68.0b2-cp311-abi3-macosx_11_0_arm64.whl

Download URL raygeo-1.68.0b2-cp311-abi3-macosx_11_0_arm64.whl
Size 4.3 MB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
57cab491eefbce329fdf1372c1df11f9bbf6c0d41d4780004a259e977b918afa
BLAKE2b-256 checksum
How to use checksums
73fe53489180849240400f4c80abb29a38793081edd8cfcbe215f8b6df2b25b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Release files / raygeo-1.68.0b2-cp311-abi3-macosx_10_12_x86_64.whl

Download URL raygeo-1.68.0b2-cp311-abi3-macosx_10_12_x86_64.whl
Size 4.5 MB
Tags CPython 3.11 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
a61ea0c1022956fdf576d41820e00341155c1c6b3e1975cc056d6b479d8d1db5
BLAKE2b-256 checksum
How to use checksums
4572e1fb68845680906a7e94c6395a870d395284e0d2cae81efad91ff451b55e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Security for raygeo 1.68.0b2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for raygeo-1.68.0b2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page