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.
[dependencies]
togo = "0.5"
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)
Important
Arcs are always CCW (counter-clockwise) in this library.
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);
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"),
}
use togo::prelude::*;
use togo::algo::{pointline_area, pointline_convex_hull, arc_bounding_circle};
// 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 = pointline_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