Skip to main content

A 2D/3D geometry library for CAD/CAM applications.

Project description

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.

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:

from raygeo 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

You can also create paths from point lists:

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

Accessing Raw Data

Internally, geometry data is stored as an (N, 8) NumPy float64 array. Each row represents one command:

import numpy as np
from raygeo import COL_TYPE, COL_X, COL_Y, CMD_TYPE_LINE

data = g.data  # numpy array, shape (N, 8)
print(data[:, COL_X])  # all x coordinates

The 8 columns are:

Column Index Description
COL_TYPE 0 Command type (move/line/arc/bezier)
COL_X 1 X coordinate
COL_Y 2 Y coordinate
COL_Z 3 Z coordinate
COL_I / COL_C1X 4 Arc center offset X / Bezier control 1 X
COL_J / COL_C1Y 5 Arc center offset Y / Bezier control 1 Y
COL_CW / COL_C2X 6 Arc clockwise flag / Bezier control 2 X
— / COL_C2Y 7 (unused for arcs) / Bezier control 2 Y

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, distance, (px, py))

# Point and tangent at parameter t on a segment
pos, tangent = g.get_point_and_tangent_at(segment_index=0, t=0.5)

Transformations

import numpy as np
from raygeo import Geometry

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

# Offset (grow/shrink)
grown = g.grow(2.0)   # offset outward by 2 units
shrunk = g.grow(-1.0)  # offset inward by 1 unit

# Affine transform (4x4 matrix)
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
mapped = 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

Contour Operations

# Split into separate closed contours
contours = g.split_into_contours()

# Split into disconnected components
components = g.split_into_components()

# Separate holes from solids
inner, outer = g.split_inner_and_outer_contours()

# Remove shared edges between sub-paths
outer_only = g.remove_inner_edges()

Polygon Operations

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

from raygeo 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

from raygeo 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
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

# Dump to dict (JSON-safe)
data = g.dump()

# Load from dict
g2 = Geometry.load(data)

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

Documentation

Full API documentation is generated from the source type stubs and published 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 visual Launch Streamlit visual test playground

Visual Testing

The make visual target launches an interactive Streamlit app for exploring geometry operations visually. Install the optional deps first:

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

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

raygeo-0.6.1.tar.gz (304.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

raygeo-0.6.1-cp311-abi3-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.11+Windows x86-64

raygeo-0.6.1-cp311-abi3-manylinux_2_35_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.35+ x86-64

raygeo-0.6.1-cp311-abi3-macosx_11_0_arm64.whl (1.2 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

raygeo-0.6.1-cp311-abi3-macosx_10_12_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file raygeo-0.6.1.tar.gz.

File metadata

  • Download URL: raygeo-0.6.1.tar.gz
  • Upload date:
  • Size: 304.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for raygeo-0.6.1.tar.gz
Algorithm Hash digest
SHA256 bec8c03d7ae6e70c612a7486eb8ea52fdcb0c500467f0761901267ffa96a76ff
MD5 77485defbdb631a4d97f0d5b6cc9e04f
BLAKE2b-256 42f28e79e7b2e090b4a0e2203f803315ad6c1cfa13b24bec1f2b86673b32dfdc

See more details on using hashes here.

Provenance

The following attestation bundles were made for raygeo-0.6.1.tar.gz:

Publisher: release.yml on barebaric/raygeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file raygeo-0.6.1-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: raygeo-0.6.1-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for raygeo-0.6.1-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 949f3a9f1594e4e9b9b1167284313cdf1e86b2da74df8bb26dae865e801fcdfe
MD5 118c5c586099e6e1d7882435d80d2335
BLAKE2b-256 0bf97540d75cab046f01d44c0b2be6634893958db7b09723a6c26299e6e29594

See more details on using hashes here.

Provenance

The following attestation bundles were made for raygeo-0.6.1-cp311-abi3-win_amd64.whl:

Publisher: release.yml on barebaric/raygeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file raygeo-0.6.1-cp311-abi3-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for raygeo-0.6.1-cp311-abi3-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 b0a5934631dfb94e36a74150999b1b99c7413f4ac68f97b14b905f8976ac9219
MD5 05a84f9d300254a2055794c42730b8fb
BLAKE2b-256 eda80f61fb16bdb256237ebbe4eb73f6db9a1edb42d16bbf2cc579b0caa20969

See more details on using hashes here.

Provenance

The following attestation bundles were made for raygeo-0.6.1-cp311-abi3-manylinux_2_35_x86_64.whl:

Publisher: release.yml on barebaric/raygeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file raygeo-0.6.1-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for raygeo-0.6.1-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c1c5ba9ae26807f7abfb5b99672a532414eecedba3928daac8654bd8475baa0d
MD5 2a9649fdcbd45a3e5143a1017ea60f32
BLAKE2b-256 82810e7b2b1090c96e2c467793c319d379dfb703cca7d840667b37f7c9c8d475

See more details on using hashes here.

Provenance

The following attestation bundles were made for raygeo-0.6.1-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on barebaric/raygeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file raygeo-0.6.1-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for raygeo-0.6.1-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 bec8f62bee406c02139d6ef61204e1d7ee4f4c0af36502c8be8c570baa82d09f
MD5 1a95c74463f3d4b62ee4ae479c68e728
BLAKE2b-256 8dcdbf6ba11400622ac9aaecfa0bdf8dca68a67bff586474de54d0fcd59338b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for raygeo-0.6.1-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on barebaric/raygeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page