From 8d4d23b1c8c04d349ae455de1344f95fd503e389 Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 28 Aug 2020 11:37:18 -0700 Subject: [PATCH] Add some tests for the MHCurve material One is failing. Maybe I should use R64 internally, again. --- src/geom.rs | 16 ++++++++++++++++ src/mat.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/geom.rs b/src/geom.rs index a2a1a60..fa5985a 100644 --- a/src/geom.rs +++ b/src/geom.rs @@ -75,6 +75,22 @@ impl Line { self.from.x + t * (self.to.x - self.from.x) } + pub fn as_vector(&self) -> Point { + self.from + (-self.to) + } + + pub fn length_sq(&self) -> f64 { + let Point { x, y } = self.as_vector(); + x*x + y*y + } + + pub fn distance_sq(&self, pt: Point) -> f64 { + // source: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Line_defined_by_two_points + let d = self.as_vector(); + let twice_area = d.y*pt.x - d.x*pt.y + self.to.x*self.from.y - self.to.y*self.from.x; + twice_area * twice_area / self.length_sq() + } + pub fn is_ascending(&self) -> bool { self.to.y > self.from.y } diff --git a/src/mat.rs b/src/mat.rs index 6260e37..dbc225d 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -112,7 +112,8 @@ impl MHCurve { panic!("failed to find segment for h:{}, m:{}, {:?}", h, m, self.geom.segments().collect::>()); }); if line.contains_y(m) && line.is_ascending() == is_ascending { - if line.contains_x(h) { + if line.contains_x(h) && line.distance_sq(Point::new(h, m)) < 1.0e-6 { + // (h, m) resides on this line break line; } else { // need to move the point toward this line @@ -198,3 +199,43 @@ impl Default for GenericMaterial { Conductor::default().into() } } + + +mod test { + use super::*; + fn mh_curve_for_test() -> MHCurve { + MHCurve::new(&[ + // rising + Point::new( 10.0, 0.0), + Point::new( 20.0, 100.0), + Point::new( 30.0, 150.0), + // falling + Point::new( 0.0, 120.0), + // negative rising + Point::new(-10.0, 0.0), + Point::new(-20.0, -100.0), + Point::new(-30.0, -150.0), + // negative falling + Point::new( 0.0, -120.0), + ]) + } + + #[test] + fn mh_curve_move_from_inner_to_inner() { + let curve = mh_curve_for_test(); + assert_eq!(curve.move_to(0.0, 0.0, 5.0), (5.0, 0.0)); + assert_eq!(curve.move_to(0.0, 5.0, 10.0), (5.0, 5.0)); + + assert_eq!(curve.move_to(-5.0, 5.0, -3.0), (-8.0, 5.0)); + assert_eq!(curve.move_to(-5.0, 5.0, 7.0), (2.0, 5.0)); + + assert_eq!(curve.move_to(5.0, -5.0, -3.0), (2.0, -5.0)); + assert_eq!(curve.move_to(5.0, -5.0, 3.0), (8.0, -5.0)); + } + + #[test] + fn mh_curve_ascend_along_edge() { + let curve = mh_curve_for_test(); + assert_eq!(curve.move_to(10.0, 0.0, 32.0), (12.0, 20.0)); + } +}