mirror of https://codeberg.org/topola/topola.git
fix(drawing/bend): Improve handling of almost equal points in perp_dot_product
This commit is contained in:
parent
d553fd6ba7
commit
ee19ae934f
|
|
@ -10,8 +10,6 @@ use core::fmt;
|
||||||
use rstar::{RTree, AABB};
|
use rstar::{RTree, AABB};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::graph::{GenericIndex, GetPetgraphIndex};
|
|
||||||
use crate::math::NoTangents;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
band::BandTermsegIndex,
|
band::BandTermsegIndex,
|
||||||
|
|
@ -32,17 +30,18 @@ use crate::{
|
||||||
SegWeight, SeqLooseSegIndex, SeqLooseSegWeight,
|
SegWeight, SeqLooseSegIndex, SeqLooseSegWeight,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
graph::MakeRef,
|
|
||||||
};
|
|
||||||
use crate::{
|
|
||||||
geometry::{
|
geometry::{
|
||||||
edit::{ApplyGeometryEdit, GeometryEdit},
|
edit::{ApplyGeometryEdit, GeometryEdit},
|
||||||
primitive::{AccessPrimitiveShape, PrimitiveShape},
|
primitive::{AccessPrimitiveShape, PrimitiveShape},
|
||||||
recording_with_rtree::RecordingGeometryWithRtree,
|
recording_with_rtree::RecordingGeometryWithRtree,
|
||||||
|
shape::MeasureLength,
|
||||||
with_rtree::BboxedIndex,
|
with_rtree::BboxedIndex,
|
||||||
AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel,
|
AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel,
|
||||||
GetLayer, GetOffset, GetSetPos, GetWidth,
|
GetLayer, GetOffset, GetSetPos, GetWidth,
|
||||||
},
|
},
|
||||||
|
graph::MakeRef,
|
||||||
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
|
math::NoTangents,
|
||||||
math::RotationSense,
|
math::RotationSense,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -814,6 +813,9 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
||||||
predicate: &impl Fn(&Self, PrimitiveIndex, PrimitiveIndex) -> bool,
|
predicate: &impl Fn(&Self, PrimitiveIndex, PrimitiveIndex) -> bool,
|
||||||
) -> Result<Cane, DrawingException> {
|
) -> Result<Cane, DrawingException> {
|
||||||
let seg_to = self.add_dot_with_infringement_filtering(recorder, dot_weight, predicate)?;
|
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
|
let seg = self
|
||||||
.add_seg_with_infringement_filtering(
|
.add_seg_with_infringement_filtering(
|
||||||
recorder,
|
recorder,
|
||||||
|
|
@ -824,14 +826,7 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
||||||
)
|
)
|
||||||
.inspect_err(|_| {
|
.inspect_err(|_| {
|
||||||
self.recording_geometry_with_rtree
|
self.recording_geometry_with_rtree
|
||||||
.remove_dot(recorder, seg_to.into());
|
.remove_dot(recorder, 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());
|
|
||||||
self.recording_geometry_with_rtree
|
self.recording_geometry_with_rtree
|
||||||
.remove_dot(recorder, seg_to.into());
|
.remove_dot(recorder, seg_to.into());
|
||||||
})?;
|
})?;
|
||||||
|
|
@ -859,6 +854,9 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
||||||
.remove_dot(recorder, seg_to.into());
|
.remove_dot(recorder, seg_to.into());
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
approx::assert_abs_diff_eq!(bend.primitive(self).shape().length(), 0.0);
|
||||||
|
|
||||||
Ok(Cane {
|
Ok(Cane {
|
||||||
seg,
|
seg,
|
||||||
dot: seg_to,
|
dot: seg_to,
|
||||||
|
|
|
||||||
|
|
@ -251,5 +251,10 @@ pub fn dot_product(v1: Point, v2: Point) -> f64 {
|
||||||
/// and its magnitude, since the resulting vector is always perpendicular to
|
/// and its magnitude, since the resulting vector is always perpendicular to
|
||||||
/// the plane anyway.
|
/// the plane anyway.
|
||||||
pub fn perp_dot_product(v1: Point, v2: Point) -> f64 {
|
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()
|
v1.x() * v2.y() - v1.y() * v2.x()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue