Imported from rgeometry/rgeometry (
AGENTS.md). Install upstream withnpx skills add rgeometry/rgeometry. Copyright stays with the author.
AGENTS.md - Guide for Agentic Coding
This file provides comprehensive guidance for AI agents (like Claude Code) when working with code in this repository.
Project Overview
RGeometry is a computational geometry library in Rust providing data types (points, polygons, lines, segments) and algorithms for manipulating them. The library emphasizes correctness through exact arithmetic and supports multiple numeric types from fixed-precision integers to arbitrary-precision rationals.
Build, Test & Lint
Pre-commit Hook (Primary Workflow)
CRITICAL: The repository uses a Nix-based pre-commit hook that automatically runs ALL validation checks on commit. This is the primary workflow - all other manual commands are optional.
# All validation happens automatically when you commit
git add . && git commit -m "feat: your message"
IMPORTANT: You MUST run validation before committing:
- ALWAYS let the pre-commit hook run
nix flake checkautomatically - NEVER use
git commit --no-verifyor--no-verifyflag - DO NOT bypass the pre-commit hook under any circumstances
- If checks fail, fix the issues and commit again - the hook ensures all commits pass CI
The pre-commit hook runs:
nix flake check- Runs tests, clippy, formatting checks, and builds all demosnix run .#pre-commit- Validates Nix, TOML, and Rust formatting
Manual Commands (for development/debugging)
These are useful during development but are not required - the pre-commit hook handles validation:
# Run all Nix checks (same as pre-commit hook)
nix flake check
# Run tests manually
cargo test
# Run tests for a specific module
cargo test <module_name>
# Run a specific test
cargo test <test_name>
# Run single module with one thread
cargo test <module_name> -- --test-threads=1
# Format code manually
cargo fmt --all
# Lint code manually
cargo clippy -- -D warnings
# Check WASM compatibility
cargo check --target wasm32-unknown-unknown
Benchmarks
# Run all benchmarks
cargo bench
# Run specific benchmark
cargo bench --bench convex_polygon
cargo bench --bench graham_scan
cargo bench --bench two_opt
Code Architecture
Core Type System
The library uses a trait-based approach to support multiple numeric types:
-
PolygonScalartrait (src/lib.rs:91-114): The foundational trait that enables the library to work with different numeric types (i8, i16, i32, i64, f32, f64, BigInt, BigRational, etc.). All geometric computations are generic over this trait. -
Numeric precision categories: The library implements
PolygonScalarvia macros for three precision categories:fixed_precision!for integer types (i8, i16, i32, i64, isize)arbitrary_precision!for BigInt and BigRationalfloating_precision!andwrapped_floating_precision!for floating-point types
-
TotalOrdtrait (src/lib.rs:51-67): Provides total ordering for types, including special handling for floating-point types.
Module Structure
-
src/data/: Core geometric data typespoint.rs: Point type with dimension-generic supportvector.rs: Vector type with arithmetic operationspolygon.rs: Polygon representation with support for simple and multi-ring polygonsline.rs,line_segment.rs: Line primitivestriangle.rs: Triangle type and operationspolygon/convex.rs: Specialized convex polygon type with additional invariants
-
src/algorithms/: Computational geometry algorithmsconvex_hull/: Graham scan, gift wrapping, and Melkman's algorithmstriangulation/: Ear clipping triangulationpolygonization/: Converting point sets to polygons (monotone, star, two-opt)intersection/: Line segment intersection algorithmsvisibility/: Visibility polygon computationzhash.rs: Z-order curve hashing for spatial indexing
-
src/orientation.rs: Robust orientation predicates (left/right/collinear tests) -
src/intersection.rs:Intersectstrait for testing geometric intersections
Key Design Patterns
-
Indexed geometry: Polygons store points in a flat
Vecand reference them viaPointIdindices. This enables efficient storage and manipulation. -
Zero-cost abstractions: The library uses iterators and views (e.g.,
VectorView) to avoid unnecessary allocations. -
Exact predicates: For floating-point types, the library uses the
geometry_predicatescrate for robust orientation tests (seecmp_slopeimplementations in src/lib.rs). -
Error handling: The
Errorenum (src/lib.rs:25-33) represents validation failures like insufficient vertices, self-intersections, or convexity violations.
Code Style Guidelines
Formatting & Imports
- 2-space indentation (rustfmt.toml:
tab_spaces = 2) - Use
usestatements at top; organize standard library, dependencies, then relative imports - Imports from
stdandnum_traitstypically come first - All code must pass
cargo fmt --all --check
Types & Generics
- Leverage generic
PolygonScalartrait for numeric types (i8, i16, i32, i64, f32, f64, BigInt, BigRational) - Use
TotalOrdtrait for total ordering (handles floating-point edge cases) - Type parameters constrained by trait bounds (e.g.,
T: PolygonScalar + TotalOrd)
Naming Conventions
- Types:
PascalCase(Point, Vector, Polygon, ConvexPolygon) - Functions/methods:
snake_case(calculate_area, is_convex, get_intersection) - Module names:
snake_case(data, algorithms, orientation) - Constants:
SCREAMING_SNAKE_CASE
Error Handling
- Return
Result<T, Error>whereErrorenum is defined in src/lib.rs (InsufficientVertices, SelfIntersections, DuplicatePoints, ConvexViolation, ClockWiseViolation, CoLinearViolation) - Use
?operator for propagating errors in Result chains - Validate geometry invariants (convexity, self-intersections) at construction boundaries
Testing & Documentation
- Write doctests in doc comments (format:
/// # Examplefollowed by/// ```rustblocks) - Property-based tests use
proptestcrate; regressions stored inproptest-regressions/ - All public items require documentation
- Use
#[cfg(test)]for test-only code; add#[tarpaulin_include]to cover test helpers
Clippy & Strict Checks
- Zero clippy warnings allowed:
cargo clippy -- -D warnings - Deny lossy float literals:
#![deny(clippy::lossy_float_literal)] - Deny float precision loss:
#![deny(clippy::cast_precision_loss)] - WASM compatibility:
cargo check --target wasm32-unknown-unknownmust pass
MSRV
Minimum Supported Rust Version: 1.90
Development Workflow
For New Features
-
Create a feature branch: Branch from upstream main (
origin/main)git checkout -b feat/your-feature-name origin/main -
Open a draft PR: Create a draft PR with a Conventional Commits title and an extremely short description
gh pr create --draft --title "feat: your feature" --body "Brief description" -
Implement changes: Make your code changes
IMPORTANT: Keep
CHANGELOG.mdup-to-date as you work. The CHANGELOG refers to PR numbers, so it can only be updated after a PR has been opened. Add entries under the "Unreleased" section documenting any user-visible changes. -
Commit changes: Commit your work - the pre-commit hook automatically validates everything
git add . && git commit -m "feat: your commit message"- The pre-commit hook runs
nix flake checkwhich executes tests, clippy, formatting, and all CI checks - If checks fail, the commit will be rejected - fix the issues and try again
- Do not manually run
cargo test,cargo fmt, orcargo clippy- the hook handles this - NEVER use
--no-verify- the hook must always run - Iterate until the commit succeeds (all checks pass)
- The pre-commit hook runs
-
Push to remote when ready:
git push -u origin feat/your-feature-name -
Finalize PR: Write the final PR description and mark as ready for review
gh pr ready
GitHub CLI Commands
gh pr create --draft --title "feat: description" --body "PR description" # Create draft PR
gh pr ready # Mark PR ready for review
gh pr view # View current PR
Commit and PR Conventions
Commit Messages
- Follow the Conventional Commits standard with type prefixes:
feat:for new featuresfix:for bug fixestest:for test-related changesci:for CI/CD changeschore:for maintenance tasksdocs:for documentationrefactor:for code refactoring
- Example:
feat: add visibility polygon algorithm - Do NOT add "Co-Authored-By" trailers or "Generated with Claude Code" footers
Pull Requests
- PR titles must also use Conventional Commits tags (e.g., "feat: add visibility polygon algorithm")
- PR descriptions should be short and to-the-point
- Do NOT add "Co-Authored-By" trailers or "Generated with Claude Code" footers to commits or PRs
Testing Conventions
- Property-based tests use
proptestandtest-strategycrates - Proptest regressions are stored in
proptest-regressions/ - The
testingmodule (src/testing.rs) provides utilities for tests
CI Requirements
The pre-commit hook ensures all commits automatically pass the same checks as CI. All PRs must pass:
cargo test- All tests including doc testscargo clippy -- -D warnings- No clippy warnings allowedcargo fmt --all -- --check- Code must be formatted- TOML and Nix formatting checks
- WASM compatibility check
- All demos must build successfully