diff --git a/src/drawing/drawing.rs b/src/drawing/drawing.rs index 4fdc4d0..cb9ed63 100644 --- a/src/drawing/drawing.rs +++ b/src/drawing/drawing.rs @@ -10,8 +10,6 @@ use core::fmt; use rstar::{RTree, AABB}; use thiserror::Error; -use crate::graph::{GenericIndex, GetPetgraphIndex}; -use crate::math::NoTangents; use crate::{ drawing::{ band::BandTermsegIndex, @@ -32,17 +30,18 @@ use crate::{ SegWeight, SeqLooseSegIndex, SeqLooseSegWeight, }, }, - graph::MakeRef, -}; -use crate::{ geometry::{ edit::{ApplyGeometryEdit, GeometryEdit}, primitive::{AccessPrimitiveShape, PrimitiveShape}, recording_with_rtree::RecordingGeometryWithRtree, + shape::MeasureLength, with_rtree::BboxedIndex, AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel, GetLayer, GetOffset, GetSetPos, GetWidth, }, + graph::MakeRef, + graph::{GenericIndex, GetPetgraphIndex}, + math::NoTangents, math::RotationSense, }; @@ -814,6 +813,9 @@ impl Drawing { predicate: &impl Fn(&Self, PrimitiveIndex, PrimitiveIndex) -> bool, ) -> Result { let seg_to = self.add_dot_with_infringement_filtering(recorder, dot_weight, predicate)?; + // we just checked that we can insert a dot there + let to = self.add_dot_infringably(recorder, dot_weight); + let seg = self .add_seg_with_infringement_filtering( recorder, @@ -824,14 +826,7 @@ impl Drawing { ) .inspect_err(|_| { self.recording_geometry_with_rtree - .remove_dot(recorder, seg_to.into()); - })?; - - let to = self - .add_dot_with_infringement_filtering(recorder, dot_weight, predicate) - .inspect_err(|_| { - self.recording_geometry_with_rtree - .remove_seg(recorder, seg.into()); + .remove_dot(recorder, to.into()); self.recording_geometry_with_rtree .remove_dot(recorder, seg_to.into()); })?; @@ -859,6 +854,9 @@ impl Drawing { .remove_dot(recorder, seg_to.into()); })?; + #[cfg(debug_assertions)] + approx::assert_abs_diff_eq!(bend.primitive(self).shape().length(), 0.0); + Ok(Cane { seg, dot: seg_to, diff --git a/src/math/mod.rs b/src/math/mod.rs index 368022f..6cf54aa 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -251,5 +251,10 @@ pub fn dot_product(v1: Point, v2: Point) -> f64 { /// and its magnitude, since the resulting vector is always perpendicular to /// the plane anyway. pub fn perp_dot_product(v1: Point, v2: Point) -> f64 { + // catch numerical rounding errors + if approx::relative_eq!(v1.x(), v2.x()) && approx::relative_eq!(v1.y(), v2.y()) { + return 0.0; + } + v1.x() * v2.y() - v1.y() * v2.x() }