Add some tests for the MHCurve material
One is failing. Maybe I should use R64 internally, again.
This commit is contained in:
16
src/geom.rs
16
src/geom.rs
@@ -75,6 +75,22 @@ impl Line {
|
|||||||
self.from.x + t * (self.to.x - self.from.x)
|
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 {
|
pub fn is_ascending(&self) -> bool {
|
||||||
self.to.y > self.from.y
|
self.to.y > self.from.y
|
||||||
}
|
}
|
||||||
|
43
src/mat.rs
43
src/mat.rs
@@ -112,7 +112,8 @@ impl MHCurve {
|
|||||||
panic!("failed to find segment for h:{}, m:{}, {:?}", h, m, self.geom.segments().collect::<Vec<_>>());
|
panic!("failed to find segment for h:{}, m:{}, {:?}", h, m, self.geom.segments().collect::<Vec<_>>());
|
||||||
});
|
});
|
||||||
if line.contains_y(m) && line.is_ascending() == is_ascending {
|
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;
|
break line;
|
||||||
} else {
|
} else {
|
||||||
// need to move the point toward this line
|
// need to move the point toward this line
|
||||||
@@ -198,3 +199,43 @@ impl Default for GenericMaterial {
|
|||||||
Conductor::default().into()
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user