fix(dist): measure in f64 so snapped endpoints stay precise (#193)

DistCommand stored the first point as Vec3 and ran on_point through
`let pt = pt.as_vec3();`, downcasting the f64 picked point to f32 before
computing distance/deltas. At survey-scale coordinates (eastings ~5e5)
f32's 24-bit mantissa gives ~0.03–0.06 unit resolution, so a snapped
endpoint measured slightly off — matching the report in #193.

Store `first` as DVec3 and keep the math in f64; cast to f32 only for
the visual preview wire vertices.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Kevin GriffinandClaude Opus 4.8 committed 2026-06-26 09:52:36 -07:00
1 parent f40144deac
commit 21192011be
1 file changed
+12 -5
+12 -5
View File
@@ -1,12 +1,15 @@
// DIST command — measure distance and angle between two picked points.
use glam::{DVec3, Vec3};
use glam::DVec3;
use crate::command::{CadCommand, CmdResult};
use crate::scene::model::wire_model::WireModel;
pub struct DistCommand {
first: Option<Vec3>,
// Keep the picked point in full f64 precision. Downcasting to f32 here
// loses ~0.03–0.06 units at survey-scale coordinates (e.g. eastings near
// 5e5), which made snapped-endpoint measurements read off by that much.
first: Option<DVec3>,
}
impl DistCommand {
@@ -28,7 +31,7 @@ impl CadCommand for DistCommand {
}
}
fn on_point(&mut self, pt: DVec3) -> CmdResult { let pt = pt.as_vec3();
fn on_point(&mut self, pt: DVec3) -> CmdResult {
if let Some(p1) = self.first {
let delta = pt - p1;
let dist = delta.length();
@@ -56,11 +59,15 @@ impl CadCommand for DistCommand {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> { let pt = pt.as_vec3();
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> {
let p1 = self.first?;
// The preview wire is purely visual, so f32 vertices are fine here.
Some(WireModel {
name: "dist_preview".into(),
points: vec![[p1.x, p1.y, p1.z], [pt.x, pt.y, pt.z]],
points: vec![
[p1.x as f32, p1.y as f32, p1.z as f32],
[pt.x as f32, pt.y as f32, pt.z as f32],
],
points_low: Vec::new(),
color: WireModel::CYAN,
selected: false,