diff --git a/crates/fj-core/src/algorithms/approx/curve.rs b/crates/fj-core/src/algorithms/approx/curve.rs index 71d01d6ff..bf22f66bd 100644 --- a/crates/fj-core/src/algorithms/approx/curve.rs +++ b/crates/fj-core/src/algorithms/approx/curve.rs @@ -169,3 +169,117 @@ impl CurveApproxCache { .unwrap_or(approx) } } + +#[cfg(test)] +mod tests { + use std::{f64::consts::TAU, ops::Deref}; + + use pretty_assertions::assert_eq; + + use crate::{ + algorithms::approx::{Approx, ApproxPoint}, + geometry::{CurveBoundary, GlobalPath, SurfaceGeometry, SurfacePath}, + objects::{Curve, Surface}, + operations::Insert, + services::Services, + }; + + #[test] + fn approx_line_on_flat_surface() { + let mut services = Services::new(); + + let curve = Curve::new().insert(&mut services); + let (surface_path, boundary) = + SurfacePath::line_from_points([[1., 1.], [2., 1.]]); + let boundary = CurveBoundary::from(boundary); + let surface = services.objects.surfaces.xz_plane(); + + let tolerance = 1.; + let approx = + (&curve, surface_path, surface.deref(), boundary).approx(tolerance); + + assert_eq!(approx.points, vec![]); + } + + #[test] + fn approx_line_on_curved_surface_but_not_along_curve() { + let mut services = Services::new(); + + let curve = Curve::new().insert(&mut services); + let (surface_path, boundary) = + SurfacePath::line_from_points([[1., 1.], [2., 1.]]); + let boundary = CurveBoundary::from(boundary); + let surface = Surface::new(SurfaceGeometry { + u: GlobalPath::circle_from_radius(1.), + v: [0., 0., 1.].into(), + }); + + let tolerance = 1.; + let approx = + (&curve, surface_path, &surface, boundary).approx(tolerance); + + assert_eq!(approx.points, vec![]); + } + + #[test] + fn approx_line_on_curved_surface_along_curve() { + let mut services = Services::new(); + + let global_path = GlobalPath::circle_from_radius(1.); + let curve = Curve::new().insert(&mut services); + let surface_path = SurfacePath::line_from_points_with_coords([ + ([0.], [0., 1.]), + ([TAU], [TAU, 1.]), + ]); + let boundary = CurveBoundary::from([[0.], [TAU]]); + let surface = Surface::new(SurfaceGeometry { + u: global_path, + v: [0., 0., 1.].into(), + }); + + let tolerance = 1.; + let approx = + (&curve, surface_path, &surface, boundary).approx(tolerance); + + let expected_approx = (global_path, boundary) + .approx(tolerance) + .into_iter() + .map(|(point_local, _)| { + let point_surface = + surface_path.point_from_path_coords(point_local); + let point_global = + surface.geometry().point_from_surface_coords(point_surface); + ApproxPoint::new(point_local, point_global) + }) + .collect::>(); + assert_eq!(approx.points, expected_approx); + } + + #[test] + fn approx_circle_on_flat_surface() { + let mut services = Services::new(); + + let curve = Curve::new().insert(&mut services); + let surface_path = + SurfacePath::circle_from_center_and_radius([0., 0.], 1.); + let boundary = CurveBoundary::from([[0.], [TAU]]); + let surface = services.objects.surfaces.xz_plane(); + + let tolerance = 1.; + let approx = + (&curve, surface_path, surface.deref(), boundary).approx(tolerance); + + let expected_approx = (&surface_path, boundary) + .approx(tolerance) + .into_iter() + .map(|(point_local, _)| { + let point_surface = + surface_path.point_from_path_coords(point_local); + let point_global = + surface.geometry().point_from_surface_coords(point_surface); + ApproxPoint::new(point_local, point_global) + }) + .collect::>(); + assert_eq!(approx.points, expected_approx); + } +} diff --git a/crates/fj-core/src/algorithms/approx/edge.rs b/crates/fj-core/src/algorithms/approx/edge.rs index a36433637..c9303b25d 100644 --- a/crates/fj-core/src/algorithms/approx/edge.rs +++ b/crates/fj-core/src/algorithms/approx/edge.rs @@ -72,118 +72,3 @@ pub struct HalfEdgeApproxCache { start_position: VertexApproxCache, curve: CurveApproxCache, } - -#[cfg(test)] -mod tests { - use std::{f64::consts::TAU, ops::Deref}; - - use pretty_assertions::assert_eq; - - use crate::{ - algorithms::approx::{Approx, ApproxPoint}, - geometry::{CurveBoundary, GlobalPath, SurfaceGeometry}, - objects::{HalfEdge, Surface}, - operations::BuildHalfEdge, - services::Services, - }; - - #[test] - fn approx_line_on_flat_surface() { - let mut services = Services::new(); - - let surface = services.objects.surfaces.xz_plane(); - let edge = - HalfEdge::line_segment([[1., 1.], [2., 1.]], None, &mut services); - - let tolerance = 1.; - let approx = (&edge, surface.deref()).approx(tolerance); - - let expected_approx = vec![{ - let point_surface = edge.start_position(); - ApproxPoint::from_surface_point(point_surface, &surface) - }]; - assert_eq!(approx.points, expected_approx); - } - - #[test] - fn approx_line_on_curved_surface_but_not_along_curve() { - let mut services = Services::new(); - - let surface = Surface::new(SurfaceGeometry { - u: GlobalPath::circle_from_radius(1.), - v: [0., 0., 1.].into(), - }); - let edge = - HalfEdge::line_segment([[1., 1.], [2., 1.]], None, &mut services); - - let tolerance = 1.; - let approx = (&edge, &surface).approx(tolerance); - - let expected_approx = vec![{ - let point_surface = edge.start_position(); - ApproxPoint::from_surface_point(point_surface, &surface) - }]; - assert_eq!(approx.points, expected_approx); - } - - #[test] - fn approx_line_on_curved_surface_along_curve() { - let mut services = Services::new(); - - let path = GlobalPath::circle_from_radius(1.); - let boundary = CurveBoundary::from([[0.], [TAU]]); - - let surface = Surface::new(SurfaceGeometry { - u: path, - v: [0., 0., 1.].into(), - }); - let edge = HalfEdge::line_segment( - [[0., 1.], [TAU, 1.]], - Some(boundary.inner), - &mut services, - ); - - let tolerance = 1.; - let approx = (&edge, &surface).approx(tolerance); - - let mut expected_approx = vec![{ - let point_surface = edge.start_position(); - ApproxPoint::from_surface_point(point_surface, &surface) - }]; - expected_approx.extend( - (path, boundary).approx(tolerance).into_iter().map( - |(point_local, _)| { - let point_surface = - edge.path().point_from_path_coords(point_local); - ApproxPoint::from_surface_point(point_surface, &surface) - }, - ), - ); - assert_eq!(approx.points, expected_approx); - } - - #[test] - fn approx_circle_on_flat_surface() { - let mut services = Services::new(); - - let surface = services.objects.surfaces.xz_plane(); - let edge = HalfEdge::circle([0., 0.], 1., &mut services); - - let tolerance = 1.; - let approx = (&edge, surface.deref()).approx(tolerance); - - let mut expected_approx = vec![{ - let point_surface = edge.start_position(); - ApproxPoint::from_surface_point(point_surface, &surface) - }]; - expected_approx.extend( - (&edge.path(), CurveBoundary::from([[0.], [TAU]])) - .approx(tolerance) - .into_iter() - .map(|(_, point_surface)| { - ApproxPoint::from_surface_point(point_surface, &surface) - }), - ); - assert_eq!(approx.points, expected_approx); - } -}