Skip to main content

CurveCurveIntersection

Struct CurveCurveIntersection 

Source
pub struct CurveCurveIntersection { /* private fields */ }
Expand description

The intersection of two 3D curves.

Read it through hits, overlaps, method, completeness, is_complete and is_empty. Intersect::intersect returns it, reading the receiver’s parameters first; an exact result is always complete, so an empty one proves the curves do not meet.

§Examples

use geomcore::{Circle, Intersect, IntersectionMethod, Line, Point, Tolerance, Vector};

// A line through a circle of radius 2 crosses it twice.
let line = Line::new(Point::new(-5.0, 0.0, 0.0), Vector::X).unwrap();
let circle = Circle::new(Point::ORIGIN, Vector::Z, 2.0).unwrap();
let result = line.intersect(&circle, Tolerance::DEFAULT);
assert_eq!(result.method(), IntersectionMethod::Exact);
assert!(result.is_complete());
// The line's parameters come out of the solve; the circle's angles do not.
let on_line: Vec<Option<f64>> = result.hits().iter().map(|h| h.first_parameter).collect();
assert_eq!(on_line, [Some(3.0), Some(7.0)]);
assert_eq!(result.hits()[0].second_parameter, None);

Implementations§

Source§

impl CurveCurveIntersection

Source

pub fn hits(&self) -> &[CurveCurveHit]

The isolated hits. A hit outside a trimmed curve’s range is dropped.

A parameter is stored only where the solver computed it: always on the numeric path, on a line against a conic for the line, and on a trimmed curve, whose range test needs it. A missing one is None; recover it with the curve’s parameter_of(hit.point). The hits are sorted by first parameter when every hit has one, and come in the solver’s order otherwise.

§Examples
use geomcore::curves::TrimmedCurve;
use geomcore::{Circle, Intersect, Line, Point, Tolerance, Vector};

// An arc across the seam at angle 0 keeps only the hit at angle 0.
let line = Line::new(Point::new(-5.0, 0.0, 0.0), Vector::X).unwrap();
let circle = Circle::new(Point::ORIGIN, Vector::Z, 2.0).unwrap();
let arc = TrimmedCurve::new(circle, -1.0, 1.0).unwrap();
let result = arc.intersect(&line, Tolerance::DEFAULT);
let hit = result.hits()[0];
assert_eq!(result.hits().len(), 1);
// The arc's range test computed its angle; the line's comes from the solve.
assert_eq!(hit.first_parameter, Some(0.0));
assert_eq!(hit.second_parameter, Some(7.0));
assert!(hit.point.distance(Point::new(2.0, 0.0, 0.0)) < 1e-12);
Source

pub fn overlaps(&self) -> &[CurveCurveOverlap]

The ranges over which the curves coincide, sorted by the start of the first range. Each range is increasing and lies in its curve’s own range; an overlap crossing a closed curve’s seam comes in two pieces. same_direction says whether the curves run the same way along the overlap; with opposite directions, first_range.0 pairs with second_range.1.

Two pieces of one curve that share at most tol.confusion of length in space, or stand apart by at most that, such as consecutive segments of a line, do not overlap: they meet at a hit, with multiplicity 1.

On the numeric path an overlap is joined from the hits and regions the search left where the curves never separated, and its ends lie within tol.confusion in space of the true ones; the result stays incomplete, with an Unseparated region over it. An overlap whose range on the second curve would cross that curve’s seam is not joined there: its hits and region stay.

§Examples
use geomcore::curves::TrimmedCurve;
use geomcore::{CurveCurveOverlap, Intersect, Line, Point, Tolerance, Vector};

// Two segments of one line share x in [1, 2].
let line = Line::new(Point::ORIGIN, Vector::X).unwrap();
let first = TrimmedCurve::new(line, 0.0, 2.0).unwrap();
let second = TrimmedCurve::new(line, 1.0, 3.0).unwrap();
let result = first.intersect(&second, Tolerance::DEFAULT);
assert!(result.hits().is_empty());
assert_eq!(
    result.overlaps(),
    &[CurveCurveOverlap {
        first_range: (1.0, 2.0),
        second_range: (1.0, 2.0),
        same_direction: true,
    }]
);
Source

pub fn method(&self) -> IntersectionMethod

Whether the result came from a closed form or a numeric search.

§Examples
use geomcore::{Circle, Intersect, IntersectionMethod, Point, Tolerance, Vector};

// A B-spline has no closed form: the numeric search runs.
let circle = Circle::new(Point::ORIGIN, Vector::Z, 2.0).unwrap();
let other = Circle::new(Point::new(2.0, 0.0, 0.0), Vector::Z, 2.0).unwrap();
let result = circle.intersect(&other.to_bspline(), Tolerance::DEFAULT);
assert_eq!(result.method(), IntersectionMethod::Numeric);
assert_eq!(result.hits().len(), 2);
Source

pub fn completeness(&self) -> &Completeness<CurveCurveRegion>

Whether every hit was found, and where hits may be missing if not.

§Examples
use geomcore::{Circle, Completeness, Intersect, Line, Point, Tolerance, Vector};

let line = Line::new(Point::ORIGIN, Vector::X).unwrap();
let circle = Circle::new(Point::ORIGIN, Vector::Z, 1.0).unwrap();
let result = circle.intersect(&line, Tolerance::DEFAULT);
assert_eq!(result.completeness(), &Completeness::Complete);
Source

pub fn is_complete(&self) -> bool

Whether every hit was found.

§Examples
use geomcore::{Ellipse, Frame, Intersect, Line, Point, Tolerance, Vector};

let ellipse = Ellipse::from_frame(Frame::WORLD, 3.0, 1.0).unwrap();
let line = Line::new(Point::ORIGIN, Vector::Y).unwrap();
assert!(ellipse.intersect(&line, Tolerance::DEFAULT).is_complete());
Source

pub fn is_empty(&self) -> bool

Whether no hit and no overlap was found. With an incomplete result this means “found nothing”, not “nothing exists”.

§Examples
use geomcore::{Intersect, Line, Point, Tolerance, Vector};

// An exact empty result proves the skew lines never meet.
let first = Line::new(Point::ORIGIN, Vector::X).unwrap();
let second = Line::new(Point::new(0.0, 0.0, 1.0), Vector::Y).unwrap();
let result = first.intersect(&second, Tolerance::DEFAULT);
assert!(result.is_empty() && result.is_complete());

Trait Implementations§

Source§

impl Clone for CurveCurveIntersection

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CurveCurveIntersection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for CurveCurveIntersection

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for CurveCurveIntersection

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.