mirror of
https://github.com/hannobraun/Fornjot
synced 2025-05-05 10:28:27 +00:00
Add CurveGeom2::line_segment_at
This commit is contained in:
parent
78854f69cd
commit
be1b621285
@ -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;
|
||||
|
||||
@ -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
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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};
|
||||
|
||||
@ -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)
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user