Expand description
A pure, standalone geometric kernel for CAD-grade curves and surfaces.
geomcore provides parametric evaluation of elementary curves and
surfaces (lines, circles, ellipses, parabolas, hyperbolas, B-splines;
planes, cylinders, cones, spheres, tori, B-spline surfaces), rigid
transformations, and analytic curve-on-surface parametrization: computing
the exact 2D representation of a 3D curve in a surface’s parameter space
wherever a closed form exists.
§Namespace layout
- The crate root re-exports the placement and value types shared by
everything else:
Point/Point2D,Vector/Vector2D,Axis/Axis2D,Frame/Frame2D, andTransform. curvesholds the 3D and 2D curve types (curves::Line,curves::Circle,curves::Ellipse,curves::Parabola,curves::Hyperbola,curves::BSplineCurve,curves::Line2D,curves::Circle2D), thecurves::Curve/curves::Curve2Denum adaptors, thecurves::TrimmedCurve/curves::TrimmedCurve2Dpieces of a curve over a parameter range (segments, arcs), and thecurves::ParametricCurve/curves::ParametricCurve2Dtraits.surfacesholds the five elementary surfaces (surfaces::Plane,surfaces::Cylinder,surfaces::Cone,surfaces::Sphere,surfaces::Torus) plussurfaces::BSplineSurface, thesurfaces::Surfaceenum adaptor, and thesurfaces::ParametricSurfacetrait.bounding_boxholdsBoundingBoxand theHasBoundingBoxtrait, through which curves and surfaces report the axis-aligned box bounding them.
§Quick start
use geomcore::{Cylinder, Point, Tolerance, Vector};
use geomcore::curves::Circle;
// Evaluate a circle at a single parameter, and over a batch of parameters.
let circle = Circle::new(Point::ORIGIN, Vector::Z, 2.0).unwrap();
let point = circle.eval_point(std::f64::consts::PI / 4.0);
let points = circle.eval_points(&[0.0, 1.0, 2.0]);
assert_eq!(points[0], circle.eval_point(0.0));
// Curve-on-surface parametrization: this circle is coaxial with the
// cylinder, so it has an exact 2D image, a horizontal line in (u, v).
let cylinder = Cylinder::new(Point::ORIGIN, Vector::Z, 2.0).unwrap();
let pcurve = circle.parametrize_on(&cylinder, Tolerance::DEFAULT).unwrap();§Intersections
a.intersect(&b, tol) (Intersect) is the entry point. It works for
every supported pair of curves and surfaces, in either order: it solves
the pair exactly when a closed form exists and runs a numeric search
otherwise, and the result says which method ran and whether it found
every hit.
use geomcore::curves::TrimmedCurve;
use geomcore::{
BSplineCurve, Completeness, Intersect, IntersectionMethod, Line, Point, Sphere,
Tolerance, Vector,
};
let tol = Tolerance::DEFAULT;
let sphere = Sphere::new(Point::ORIGIN, 2.0).unwrap();
// A line through a sphere has a closed form: exact, and so complete.
let line = Line::new(Point::new(0.0, 0.0, -5.0), Vector::Z).unwrap();
let result = line.intersect(&sphere, tol);
assert_eq!(result.method(), IntersectionMethod::Exact);
assert_eq!(result.completeness(), &Completeness::Complete);
let parameters: Vec<Option<f64>> = result.hits().iter().map(|h| h.curve_parameter).collect();
assert_eq!(parameters, [Some(3.0), Some(7.0)]);
// A parameter the solver did not compute is `None`: the caller reads it
// from the point, here the sphere's.
assert_eq!(result.hits()[0].surface_parameters, None);
let (_, latitude) = sphere.parameters_of(result.hits()[0].point);
assert!((latitude + std::f64::consts::FRAC_PI_2).abs() < 1e-12);
// A segment keeps only the hits in its range.
let segment = TrimmedCurve::new(line, 0.0, 5.0).unwrap();
assert_eq!(segment.intersect(&sphere, tol).hits().len(), 1);
// A B-spline has no closed form: the numeric search runs.
let poles = vec![Point::new(0.0, 0.0, -5.0), Point::new(0.0, 0.0, 5.0)];
let spline = BSplineCurve::new(1, poles, vec![0.0, 1.0], vec![2, 2], false).unwrap();
let result = spline.intersect(&sphere, tol);
assert_eq!(result.method(), IntersectionMethod::Numeric);
assert_eq!(result.hits().len(), 2);IntersectExact::intersect_exact is the typed fast path: between two
concrete types it returns the pair’s own exact result. It recovers no
parameters it does not need and never falls back to a numeric search.
use geomcore::{IntersectExact, PlaneSphereIntersection, Point, Vector};
use geomcore::surfaces::{Plane, Sphere};
let plane = Plane::new(Point::ORIGIN, Vector::Z).unwrap();
let sphere = Sphere::new(Point::ORIGIN, 2.0).unwrap();
let tol = geomcore::Tolerance::default();
let PlaneSphereIntersection::Circle(circle) = plane.intersect_exact(&sphere, tol) else {
panic!("expected a circle");
};
assert_eq!(sphere.intersect_exact(&plane, tol), PlaneSphereIntersection::Circle(circle));Between surfaces::Surface or curves::Curve values it returns
a general result such as ExactSurfaceIntersection, which reports
NotAnalytic for a B-spline or a pair without a closed form, where
Intersect::intersect runs the numeric search. Two surfaces without
a closed form are traced numerically by the same call.
§Extending the kernel
New curve or surface types are added by implementing
curves::ParametricCurve (or curves::ParametricCurve2D) and
surfaces::ParametricSurface respectively, without touching the
existing dispatch code in curves::Curve/surfaces::Surface.
Such types are intersected by intersect_curve_curve and
intersect_curve_surface, which run the numeric search on any
curve and surface and return the same result types as
Intersect::intersect, solved numerically.
Re-exports§
pub use bounding_box::BoundingBox;pub use bounding_box::HasBoundingBox;pub use curves::BSplineConstructionError;pub use curves::BSplineConversionError;pub use curves::BSplineCurve;pub use curves::BSplineSplitError;pub use curves::Circle;pub use curves::Circle2D;pub use curves::CircleConstructionError;pub use curves::Continuity;pub use curves::Curve;pub use curves::Curve2D;pub use curves::DegreeElevationError;pub use curves::ElementaryCurve;pub use curves::Ellipse;pub use curves::EllipseConstructionError;pub use curves::Hyperbola;pub use curves::HyperbolaConstructionError;pub use curves::KnotInsertionError;pub use curves::KnotRemovalError;pub use curves::Line;pub use curves::Line2D;pub use curves::LineConstructionError;pub use curves::Parabola;pub use curves::ParabolaConstructionError;pub use curves::ParametricCurve;pub use curves::ParametricCurve2D;pub use curves::ParametrizeError;pub use curves::PointExtrema;pub use curves::PointExtrema2D;pub use curves::PointParametrization;pub use curves::Side;pub use curves::TrimmedCurve;pub use curves::TrimmedCurve2D;pub use curves::TrimmedCurveConstructionError;pub use curves::parametrize_numeric;pub use discretization::Discretization;pub use discretization::Discretization2D;pub use discretization::DiscretizationCriteria;pub use discretization::DiscretizationCriteriaError;pub use discretization::Discretize;pub use discretization::Discretize2D;pub use frame::Axis;pub use frame::Axis2D;pub use frame::Frame;pub use frame::Frame2D;pub use frame::FrameConstructionError;pub use intersect::curve_curve_extrema;pub use intersect::CircleCircle2DIntersection;pub use intersect::CircleCircleIntersection;pub use intersect::CircleSurfaceIntersection;pub use intersect::ConeConeIntersection;pub use intersect::ConeCylinderIntersection;pub use intersect::ConicConicIntersection;pub use intersect::ConicSurfaceHit;pub use intersect::ConicSurfaceIntersection;pub use intersect::CurveCurveExtremum;pub use intersect::CurveCurveHit;pub use intersect::CurveSurfaceHit;pub use intersect::CylinderCylinderIntersection;pub use intersect::LatitudeRing;pub use intersect::LineCircle2DIntersection;pub use intersect::LineCircleIntersection;pub use intersect::LineConicHit;pub use intersect::LineConicIntersection;pub use intersect::LineLine2DIntersection;pub use intersect::LineLineIntersection;pub use intersect::LinePlaneIntersection;pub use intersect::LineQuadricIntersection;pub use intersect::LineTorusHit;pub use intersect::LineTorusIntersection;pub use intersect::PlaneConeIntersection;pub use intersect::PlaneCylinderIntersection;pub use intersect::PlanePlaneIntersection;pub use intersect::PlaneSphereIntersection;pub use intersect::SphereConeIntersection;pub use intersect::SphereCylinderIntersection;pub use intersect::SphereSphereIntersection;pub use intersect::TorusConeIntersection;pub use intersect::TorusCylinderIntersection;pub use intersect::TorusPlaneIntersection;pub use intersect::TorusSphereIntersection;pub use intersect::TorusTorusIntersection;pub use intersect::Completeness;pub use intersect::CurveCurveExtrema;pub use intersect::CurveCurveRegion;pub use intersect::CurveSurfaceRegion;pub use intersect::IncompleteReason;pub use intersect::CurveCurveHit2D;pub use intersect::CurveCurveIntersection;pub use intersect::CurveCurveIntersection2D;pub use intersect::CurveCurveOverlap;pub use intersect::CurveSurfaceIntersection;pub use intersect::IntersectionCurve;pub use intersect::IntersectionMethod;pub use intersect::SurfaceSurfaceIntersection;pub use intersect::SurfaceSurfaceRegion;pub use intersect::ExactCurveCurveIntersection;pub use intersect::ExactCurveSurfaceIntersection;pub use intersect::ExactSurfaceIntersection;pub use intersect::InlineList;pub use intersect::Intersect;pub use intersect::IntersectExact;pub use intersect::intersect_curve_curve;pub use intersect::intersect_curve_surface;pub use point::Point;pub use point::Point2D;pub use projection::CurveProjection;pub use projection::CurveProjection2D;pub use projection::SurfaceProjection;pub use surfaces::BSplineSurface;pub use surfaces::Cone;pub use surfaces::ConeConstructionError;pub use surfaces::Cylinder;pub use surfaces::CylinderConstructionError;pub use surfaces::ElementarySurface;pub use surfaces::ParametricSurface;pub use surfaces::Plane;pub use surfaces::PlaneConstructionError;pub use surfaces::Sphere;pub use surfaces::SphereConstructionError;pub use surfaces::Surface;pub use surfaces::SurfaceCurvatures;pub use surfaces::SurfaceIsoError;pub use surfaces::Torus;pub use surfaces::TorusConstructionError;pub use tolerance::Tolerance;pub use transform::Transform;pub use vector::Vector;pub use vector::Vector2D;
Modules§
- bounding_
box - Axis-aligned bounding boxes of curves and surfaces.
Axis-aligned bounding boxes of curves and surfaces (see
CONTEXT.md). - curves
- Public curve types: lines, conics, and B-spline curves.
Public curve types: parametric curves in 2D and 3D built on top of the
crate’s placement types (
crate::Axis/crate::Axis2D,crate::Frame/crate::Frame2D). - discretization
- Discretization of curves into points joined by straight segments, with
proven chord and angle deviations.
Discretization: points on a bounded curve, in order of parameter,
joined by straight segments, each segment carrying a proven chord
deviation and angle deviation (see
CONTEXT.md). - frame
- Axis and frame placement types. Axis and frame placement types: the coordinate systems that curves and surfaces are positioned in.
- intersect
- Intersections of curves and surfaces: the routed
Intersect, the typed exactIntersectExact, and their results. Intersections of curves and surfaces, and their results. - point
- Points in 2D and 3D space.
- projection
- Point-projection result types. Point-projection result types.
- surfaces
- Public surface types: planes, cylinders, cones, spheres, tori, and
B-spline surfaces.
Public surface types: the five elementary analytic surfaces (plane,
cylinder, cone, sphere, torus) plus B-spline surfaces, built on top of
the crate’s placement type (
crate::Frame). - tolerance
- Distance and angle tolerances shared by all geometric queries.
- transform
- Rigid and affine transformations. Rigid and affine transformations of points and vectors.
- vector
- Vectors in 2D and 3D space.