Skip to content

Commit

Permalink
Add CurveGeom2::line_segment_at
Browse files Browse the repository at this point in the history
  • Loading branch information
hannobraun committed Sep 12, 2024
1 parent 78854f6 commit be1b621
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 17 deletions.
53 changes: 52 additions & 1 deletion crates/fj-core/src/geometry/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ use std::collections::BTreeMap;

use fj_math::{Circle, Line, Point};

use crate::{storage::Handle, topology::Surface};
use crate::{
algorithms::approx::{PathApproxParams, Tolerance},
storage::Handle,
topology::Surface,
};

use super::Path;

Expand Down Expand Up @@ -68,18 +72,54 @@ pub struct LocalCurveGeom {
pub trait CurveGeom2<const D: usize> {
/// # Access the origin of the curve
fn origin(&self) -> Point<D>;

/// # Compute a line segment to approximate the curve at this point
///
/// If the curve requires no approximation (meaning it is a line), then per
/// convention, a degenerate line segment is returned, that collapses to the
/// provided point.
fn line_segment_at(
&self,
point: impl Into<Point<1>>,
tolerance: impl Into<Tolerance>,
) -> [Point<D>; 2];
}

impl<const D: usize> CurveGeom2<D> for Circle<D> {
fn origin(&self) -> Point<D> {
self.center() + self.a()
}

fn line_segment_at(
&self,
point: impl Into<Point<1>>,
tolerance: impl Into<Tolerance>,
) -> [Point<D>; 2] {
let point = point.into();
let params = PathApproxParams::for_circle(self, tolerance);

[point.t - params.increment(), point.t + params.increment()]
.map(|point_circle| self.point_from_circle_coords([point_circle]))
}
}

impl<const D: usize> CurveGeom2<D> for Line<D> {
fn origin(&self) -> Point<D> {
self.origin()
}

fn line_segment_at(
&self,
point: impl Into<Point<1>>,
_: impl Into<Tolerance>,
) -> [Point<D>; 2] {
let point = point.into();

// Collapse line segment into a point, as per documentation.
let point = self.origin() + self.direction() * point.t;

[point, point]
}
}

// This implementation is temporary, to ease the transition towards a curve
Expand All @@ -91,4 +131,15 @@ impl<const D: usize> CurveGeom2<D> for Path<D> {
Self::Line(line) => line.origin(),
}
}

fn line_segment_at(
&self,
point: impl Into<Point<1>>,
tolerance: impl Into<Tolerance>,
) -> [Point<D>; 2] {
match self {
Self::Circle(circle) => circle.line_segment_at(point, tolerance),
Self::Line(line) => line.line_segment_at(point, tolerance),
}
}
}
19 changes: 3 additions & 16 deletions crates/fj-core/src/geometry/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use fj_math::{Point, Scalar, Transform, Triangle, Vector};

use crate::algorithms::approx::{PathApproxParams, Tolerance};
use crate::algorithms::approx::Tolerance;

use super::{CurveGeom2, Path};

Expand Down Expand Up @@ -67,23 +67,10 @@ impl SurfaceGeom {

let line_segment = match &self.u {
Path::Circle(circle) => {
let params = PathApproxParams::for_circle(circle, tolerance);

[
point_surface.u - params.increment(),
point_surface.u + params.increment(),
]
.map(|point_circle| {
circle.point_from_circle_coords([point_circle])
})
circle.line_segment_at([point_surface.u], tolerance)
}
Path::Line(line) => {
// We don't need to approximate a line. So instead of creating a
// line segment to represent the line at this point, we just
// need this single point.
let point = line.origin() + line.direction() * point_surface.u;

[point, point]
line.line_segment_at([point_surface.u], tolerance)
}
};

Expand Down

0 comments on commit be1b621

Please sign in to comment.