forked from 1b-agent/opencadstudio-upstream
fix(bpt): compare rotation rows across angle wrap
This commit is contained in:
1 parent
f74e1e8bd3
commit
9d2f4e592a
3 files changed
+33
-4
No files matched your search
+15
-1
@@ -221,7 +221,21 @@ impl OpenCADStudio {
|
||||
.then(|| {
|
||||
view.rows
|
||||
.iter()
|
||||
.position(|r| r.iter().zip(&values).all(|(a, b)| (a - b).abs() <= 1e-9))
|
||||
.position(|row| {
|
||||
row.iter().zip(&values).zip(&view.columns).all(
|
||||
|((row_value, value), column)| {
|
||||
let difference = if column
|
||||
.connection_name
|
||||
.eq_ignore_ascii_case("UpdatedAngle")
|
||||
{
|
||||
crate::scene::block_actions::angle_distance(*row_value, *value)
|
||||
} else {
|
||||
(row_value - value).abs()
|
||||
};
|
||||
difference <= 1e-9
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
.flatten();
|
||||
self.tabs[i].selected_grips.push(GripDef {
|
||||
|
||||
@@ -11,6 +11,14 @@ use glam::DVec3;
|
||||
pub(crate) mod instance;
|
||||
mod representation;
|
||||
mod stretch;
|
||||
|
||||
/// Smallest signed distance between two angles in radians, accounting for the
|
||||
/// wrap at ±π. Used for BPT rotation snapping and current-row detection.
|
||||
pub(crate) fn angle_distance(a: f64, b: f64) -> f64 {
|
||||
((a - b + std::f64::consts::PI).rem_euclid(std::f64::consts::TAU)
|
||||
- std::f64::consts::PI)
|
||||
.abs()
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
@@ -1097,9 +1105,8 @@ fn evaluate_impl(
|
||||
.iter()
|
||||
.filter_map(|row| row.get(col).copied())
|
||||
.min_by(|a, b| {
|
||||
(a - angle)
|
||||
.abs()
|
||||
.total_cmp(&(b - angle).abs())
|
||||
angle_distance(*a, angle)
|
||||
.total_cmp(&angle_distance(*b, angle))
|
||||
.then_with(|| a.total_cmp(b))
|
||||
})
|
||||
{
|
||||
|
||||
@@ -3,6 +3,14 @@ use crate::scene::{block_distance_parameter as distance, block_point_parameter a
|
||||
use codec::{DwgReader, DwgWriter, DxfReader, DxfWriter};
|
||||
use std::io::Cursor;
|
||||
|
||||
#[test]
|
||||
fn rotation_table_angles_match_across_pi_wrap() {
|
||||
let near_positive_pi = std::f64::consts::PI - 0.01;
|
||||
let near_negative_pi = -std::f64::consts::PI + 0.01;
|
||||
assert!((super::angle_distance(near_positive_pi, near_negative_pi) - 0.02).abs() < 1e-12);
|
||||
assert!(super::angle_distance(near_positive_pi, 0.0) > 3.0);
|
||||
}
|
||||
|
||||
fn fixture() -> (CadDocument, Handle, Vec<Handle>) {
|
||||
let mut scene = Scene::new();
|
||||
scene.define_block_raw(
|
||||
|
||||
Reference in new issue
Block a user