#arc #distance #intersection #geometry

togo

A library for 2D geometry, providing geometric algorithms for intersection/distance between circular arcs/line segments

20 unstable releases (3 breaking)

Uses new Rust 2024

0.7.2 Nov 20, 2025
0.7.1 Nov 16, 2025
0.6.12 Nov 13, 2025
0.6.8 Oct 31, 2025
0.4.1 Sep 24, 2025

#248 in Algorithms


Used in 2 crates

MIT license

635KB
11K SLoC

TOGO - Basic 2D geometric operations

Crates.io Documentation License: MIT

This library provides 2D geometric operations for arcs and line segments. It is used in my other projects and may not implement all possible geometric operations.

Adding the library to Cargo.toml

[dependencies]
togo = "0.7"

Documentation

https://docs.rs/togo

Core Capabilities

2D Geometric Primitives: Points, Line Segments, Circles, Circle Arcs, Polylines, Intervals

Distance Calculations: point-arc, point-circle, point-segment, segment-arc, segment-circle, segment-segment, line-circle, arc-arc

Intersection Detection: line-line, line-circle, line-arc, circle-circle, segment-segment, segment-circle, segment-arc, arc-arc, interval-interval

Geometric Algorithms: Convex Hull, Convexity Detection, Area Calculations (point/arc-based), Bounding Circle/Rectangle

Numerical Operations: Vector arithmetic (add, sub, mul, div), dot/cross product, normalization, point equality (ULP & epsilon-based)

Examples

[!IMPORTANT] Arcs are always CCW (counter-clockwise) in this library.

Working with geometric primitives and distances

use togo::prelude::*;

// Create primitives: points, circle, segment, arc
let p1 = point(0.0, 0.0);
let p2 = point(10.0, 0.0);
let c = circle(p1, 5.0);
let seg = segment(p1, p2);
let arc = arc(point(1.0, 0.0), point(0.0, 1.0), point(0.0, 0.0), 1.0);

// Compute distances
let (dist, _) = dist_point_circle(&point(10.0, 0.0), &c);
assert_eq!(dist, 5.0);

let (dist, _) = dist_point_segment(&point(5.0, 5.0), &seg);
assert_eq!(dist, 5.0);

// Distance between arcs
let a2 = arc(point(4.0, 0.0), point(2.0, 0.0), point(3.0, 0.0), 1.0);
let dist = dist_arc_arc(&arc, &a2);
assert!(dist > 0.0);

Intersection computations

use togo::prelude::*;

// Segment-segment intersection
let seg1 = segment(point(0.0, 0.0), point(2.0, 2.0));
let seg2 = segment(point(0.0, 2.0), point(2.0, 0.0));
match int_segment_segment(&seg1, &seg2) {
    SegmentSegmentConfig::OnePoint(pt, ..) => {
        assert!(point(1.0, 1.0).close_enough(pt, 1e-10));
    },
    _ => assert!(false, "Expected intersection"),
}

// Circle-circle intersection
let c1 = circle(point(0.0, 0.0), 3.0);
let c2 = circle(point(4.0, 0.0), 3.0);
match int_circle_circle(c1, c2) {
    CircleCircleConfig::NoncocircularTwoPoints(_, _) => {
        assert!(true); // Two intersection points found
    },
    _ => assert!(false, "Expected two intersection points"),
}

// Arc-arc intersection
let a1 = arc(point(1.0, 0.0), point(0.0, 1.0), point(0.0, 0.0), 1.0);
let a2 = arc(point(1.0, 1.0), point(0.0, 0.0), point(1.0, 0.0), 1.0);
match int_arc_arc(&a1, &a2) {
    ArcArcConfig::NonCocircularOnePoint(pt) => {
        assert_eq!(point(0.5, 0.8660254037844386), pt);
    },
    _ => assert!(false, "Expected one intersection point"),
}

Algorithms: Area, Convex Hull, Bounding

use togo::prelude::*;

// Calculate area of a polygon
let triangle = vec![point(0.0, 0.0), point(4.0, 0.0), point(2.0, 3.0), point(0.0, 0.0)];
let area = pointline_area(&triangle);
assert_eq!(area, 6.0);

// Find convex hull
let points = vec![
    point(0.0, 0.0),
    point(2.0, 1.0),
    point(1.0, 2.0),    // Interior (excluded)
    point(3.0, 0.0),
    point(2.0, 3.0),
    point(0.0, 2.0),
];
let hull = points_convex_hull(&points);
assert_eq!(hull.len(), 4);  // 4 points on convex hull

// Bounding circle for an arc
let quarter_arc = arc(point(1.0, 0.0), point(0.0, 1.0), point(0.0, 0.0), 1.0);
let bounding = arc_bounding_circle(&quarter_arc);
assert_eq!(bounding.r, 0.7071067811865476); // sqrt(2)/2

Togo is part of the open-sourced Nest2D projects collection.

Dependencies

~740KB