From c84c37d4c4e60da8bafabef6050649ef3395a1a2 Mon Sep 17 00:00:00 2001 From: Buck McCready Date: Thu, 23 Mar 2023 02:29:15 -0700 Subject: [PATCH] Fixed epsilon comparison in line_circle_intr for better accuracy Test case added which triggers debug assert that found the problem. --- cavalier_contours/src/core/math/base_math.rs | 2 +- .../src/core/math/line_circle_intersect.rs | 5 ++++- cavalier_contours/tests/test_pline_boolean.rs | 16 +++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/cavalier_contours/src/core/math/base_math.rs b/cavalier_contours/src/core/math/base_math.rs index 2f18e90..0281303 100644 --- a/cavalier_contours/src/core/math/base_math.rs +++ b/cavalier_contours/src/core/math/base_math.rs @@ -270,7 +270,7 @@ where let y_diff = p1.y - p0.y; debug_assert!( - (((p1.x - p0.x) * (p0.y - point.y) - (p0.x - point.x) * (p1.y - p0.y)).abs() + ((x_diff * (p0.y - point.y) - (p0.x - point.x) * y_diff) / (x_diff * x_diff + y_diff * y_diff).sqrt()) .fuzzy_eq_zero_eps(epsilon), "point does not lie on the line defined by p0 to p1 (based on distance)" diff --git a/cavalier_contours/src/core/math/line_circle_intersect.rs b/cavalier_contours/src/core/math/line_circle_intersect.rs index 8506cfc..4fcf4b2 100644 --- a/cavalier_contours/src/core/math/line_circle_intersect.rs +++ b/cavalier_contours/src/core/math/line_circle_intersect.rs @@ -97,7 +97,10 @@ where let p0_shifted = p0 - circle_center; let p1_shifted = p1 - circle_center; - let (a, b, c) = if dx.fuzzy_eq_zero_eps(epsilon) { + // note: using Real number's defined epsilon for this check since it's just avoiding division by + // too small a number, using the epsilon passed into this function causes unneeded loss of + // precision (this branch is not directly determining the intersect result case returned) + let (a, b, c) = if dx.fuzzy_eq_zero() { // vertical line, using average of point x values for fuzziness let x_pos = (p1_shifted.x + p0_shifted.x) / T::two(); // x = x_pos diff --git a/cavalier_contours/tests/test_pline_boolean.rs b/cavalier_contours/tests/test_pline_boolean.rs index 1d710a4..5958c94 100644 --- a/cavalier_contours/tests/test_pline_boolean.rs +++ b/cavalier_contours/tests/test_pline_boolean.rs @@ -778,7 +778,7 @@ mod test_specific { (BooleanOp::Xor, &[PlineProperties::new(5, -16.53221047179636, 20.446251608592654, 27.178236249782003, 12.500000000000002, 31.47, 19.710003437554498), PlineProperties::new(4, 25.268891132014584, 26.268806598426877, 20.97207, 18.983318011926176, 30.088663750217997, 25.660000000000025)], &[]) ] } - parametric_from_point_debug_assert_reported { + parametric_from_point_debug_assert_reported1 { // reported case triggered debug assert in parametric_from_point ( pline_closed![(11.664990000000303, 18.442909378846142, 0.0), (11.665000000000305, 8.219999378846142, 1.0), (12.934999999999697, 8.22000062115386, 0.0), (12.934989999999695, 18.44291062115386, 1.0)], @@ -792,5 +792,19 @@ mod test_specific { (BooleanOp::Xor, &[PlineProperties::new(4, -10.357662177038755, 19.289617472302368, 11.66499, 10.54620791786424, 12.934997724508513, 19.077910000000003), PlineProperties::new(8, 0.8351647039718321, 13.743812401748059, 11.538, 7.458, 13.062000000000001, 10.546214778732427)], &[]) ] } + parametric_from_point_debug_assert_reported2 { + // reported case triggered debug assert in parametric_from_point + ( + pline_closed![(15.460744844799105, 20.44135329367296, 0.2839154127006927), (14.548990000000272, 18.965099544964527, 0.9999999999999999), (15.310989999999729, 18.965100455035472, -0.28391541270069265), (15.801935155200894, 19.76000670632704, 0.9999999999999999)], + pline_closed![(14.548990000025455, 18.96509559588487, 0.0), (14.549000000025455, 18.09999559588487, 1.0), (15.310999999974545, 18.100004404115133, 0.0), (15.310989999974545, 18.96510440411513, 1.0)] + ) + => + [ + (BooleanOp::Or, &[PlineProperties::new(6, 2.1860886410435683, 6.934715005959068, 14.548990000020739, 17.719, 16.012340000000002, 20.48168)], &[]), + (BooleanOp::And, &[PlineProperties::new(2, 0.4560367311877418, 2.3938936020354182, 14.54899, 18.5841, 15.31099, 19.3461)], &[]), + (BooleanOp::Not, &[PlineProperties::new(4, -1.0708457098118014, 5.2045150058434775, 14.54899, 18.96509559588487, 16.012340000000002, 20.48168)], &[]), + (BooleanOp::Xor, &[PlineProperties::new(4, -1.0708457098118014, 5.2045150058434775, 14.54899, 18.96509559588487, 16.012340000000002, 20.48168), PlineProperties::new(4, 0.6592062000440251, 4.124093602151008, 14.548990000025455, 17.719, 15.311, 18.96510440411513)], &[]) + ] + } } }