forked from 1b-agent/opencadstudio-upstream
fix(commands): migrate inquiry + fillet/align/lengthen picks to world XY (#54)
These commands still read the cursor / entity coordinate with the old "Y-up XZ" assumption (world Z = DXF Y), which is wrong now that the drawing plane is world XY: ID/DIST/AREA reported swapped Y↔Z values and zero-area, and fillet/align/lengthen picked against a constant-elevation axis. Read the drawing-plane coordinate from .y (elevation stays on .z), matching the central transform and the entity builders. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
3e493969b6
commit
c04bdcf846
6 files changed
+21
-21
No files matched your search
@@ -41,14 +41,14 @@ impl CadCommand for AreaCommand {
|
||||
if self.points.len() < 3 {
|
||||
return CmdResult::Cancel;
|
||||
}
|
||||
// Shoelace formula in the XZ plane (Y-up world)
|
||||
// Shoelace formula in the world XY plane.
|
||||
let n = self.points.len();
|
||||
let mut area_sum = 0.0f32;
|
||||
let mut perimeter = 0.0f32;
|
||||
for idx in 0..n {
|
||||
let a = self.points[idx];
|
||||
let b = self.points[(idx + 1) % n];
|
||||
area_sum += a.x * b.z - b.x * a.z;
|
||||
area_sum += a.x * b.y - b.x * a.y;
|
||||
perimeter += (b - a).length();
|
||||
}
|
||||
let area = (area_sum * 0.5).abs();
|
||||
|
||||
@@ -33,10 +33,10 @@ impl CadCommand for DistCommand {
|
||||
let delta = pt - p1;
|
||||
let dist = delta.length();
|
||||
let dx = delta.x;
|
||||
let dy = delta.z; // Y-up world: Z is the "drawing Y"
|
||||
let dz = delta.y; // Y-up world: Y is elevation
|
||||
let dy = delta.y; // drawing plane is world XY
|
||||
let dz = delta.z; // elevation
|
||||
|
||||
// Angle in XY plane (XZ in world coords) — degrees from +X
|
||||
// Angle in XY plane — degrees from +X
|
||||
let angle_xy = dy.atan2(dx).to_degrees();
|
||||
// Angle from XY plane toward Z (elevation angle)
|
||||
let dist_xy = dx.hypot(dy);
|
||||
|
||||
@@ -22,10 +22,10 @@ impl CadCommand for IdCommand {
|
||||
}
|
||||
|
||||
fn on_point(&mut self, pt: Vec3) -> CmdResult {
|
||||
// Y-up world: X stays X, Z→drawing Y, Y→elevation Z
|
||||
// Drawing plane is world XY (z = elevation).
|
||||
let x = pt.x;
|
||||
let y = pt.z;
|
||||
let z = pt.y;
|
||||
let y = pt.y;
|
||||
let z = pt.z;
|
||||
let msg = format!("X = {x:.4}, Y = {y:.4}, Z = {z:.4}");
|
||||
CmdResult::Measurement(msg)
|
||||
}
|
||||
|
||||
@@ -167,9 +167,9 @@ impl AlignCommand {
|
||||
);
|
||||
}
|
||||
|
||||
// Angle from src_vec to dst_vec in XZ plane
|
||||
let src_angle = src_vec.z.atan2(src_vec.x);
|
||||
let dst_angle = dst_vec.z.atan2(dst_vec.x);
|
||||
// Angle from src_vec to dst_vec in the world XY plane
|
||||
let src_angle = src_vec.y.atan2(src_vec.x);
|
||||
let dst_angle = dst_vec.y.atan2(dst_vec.x);
|
||||
let angle = dst_angle - src_angle;
|
||||
|
||||
let scale_factor = if with_scale { dst_len / src_len } else { 1.0 };
|
||||
|
||||
@@ -1246,7 +1246,7 @@ impl CadCommand for FilletCommand {
|
||||
if handle.is_null() {
|
||||
return CmdResult::NeedPoint;
|
||||
}
|
||||
let click = [pt.x as f64, pt.z as f64]; // Y-up: world Z = DXF Y
|
||||
let click = [pt.x as f64, pt.y as f64]; // drawing plane is world XY
|
||||
|
||||
match &self.step {
|
||||
FilletStep::WaitingForRadius => return CmdResult::NeedPoint,
|
||||
@@ -1324,7 +1324,7 @@ impl CadCommand for FilletCommand {
|
||||
if handle.is_null() {
|
||||
return vec![];
|
||||
}
|
||||
let click = [pt.x as f64, pt.z as f64];
|
||||
let click = [pt.x as f64, pt.y as f64];
|
||||
|
||||
match &self.step {
|
||||
FilletStep::WaitingForRadius => vec![],
|
||||
|
||||
@@ -150,9 +150,9 @@ pub fn lengthen_entity(entity: &EntityType, pick_pt: Vec3, mode: &LenMode) -> Op
|
||||
}
|
||||
|
||||
fn lengthen_line(line: &LineEnt, pick_pt: Vec3, mode: &LenMode) -> Option<EntityType> {
|
||||
let s = Vec3::new(line.start.x as f32, line.start.z as f32, 0.0);
|
||||
let e = Vec3::new(line.end.x as f32, line.end.z as f32, 0.0);
|
||||
let p = Vec3::new(pick_pt.x, pick_pt.z, 0.0);
|
||||
let s = Vec3::new(line.start.x as f32, line.start.y as f32, 0.0);
|
||||
let e = Vec3::new(line.end.x as f32, line.end.y as f32, 0.0);
|
||||
let p = Vec3::new(pick_pt.x, pick_pt.y, 0.0);
|
||||
|
||||
let current_len = (e - s).length() as f64;
|
||||
if current_len < 1e-10 {
|
||||
@@ -187,7 +187,7 @@ fn lengthen_line(line: &LineEnt, pick_pt: Vec3, mode: &LenMode) -> Option<Entity
|
||||
|
||||
fn lengthen_arc(arc: &ArcEnt, pick_pt: Vec3, mode: &LenMode) -> Option<EntityType> {
|
||||
let cx = arc.center.x as f32;
|
||||
let cy = arc.center.z as f32; // Y-up: DXF Y → world Z
|
||||
let cy = arc.center.y as f32;
|
||||
|
||||
// Current arc span
|
||||
let span = arc_span_rad(arc.start_angle, arc.end_angle);
|
||||
@@ -290,7 +290,7 @@ fn lengthen_ellipse(ell: &EllipseEnt, pick_pt: Vec3, mode: &LenMode) -> Option<E
|
||||
|
||||
// Determine which end is closer to pick_pt (use DXF XY plane).
|
||||
let p_x = pick_pt.x as f64;
|
||||
let p_y = pick_pt.z as f64; // Y-up: world Z → DXF Y
|
||||
let p_y = pick_pt.y as f64; // Y-up: world Z → DXF Y
|
||||
let pt_start_x = ell.center.x + a * t0.cos() * nx - b * t0.sin() * ny;
|
||||
let pt_start_y = ell.center.y + a * t0.cos() * ny + b * t0.sin() * nx;
|
||||
let pt_end_x = ell.center.x + a * t1.cos() * nx - b * t1.sin() * ny;
|
||||
@@ -339,7 +339,7 @@ fn lengthen_lwpoly(poly: &LwPolyline, pick_pt: Vec3, mode: &LenMode) -> Option<E
|
||||
|
||||
// Determine which end is closer to the pick point (DXF XY: pick_pt.x, pick_pt.z).
|
||||
let px = pick_pt.x as f64;
|
||||
let py = pick_pt.z as f64; // Y-up: world Z = DXF Y
|
||||
let py = pick_pt.y as f64; // Y-up: world Z = DXF Y
|
||||
|
||||
let first = &poly.vertices[0];
|
||||
let last = &poly.vertices[n - 1];
|
||||
@@ -428,8 +428,8 @@ fn lengthen_spline(spl: &SplineEnt, pick_pt: Vec3, mode: &LenMode) -> Option<Ent
|
||||
// Determine which end (start or end) is closer to pick_pt.
|
||||
let p_start = bs.subs(t0);
|
||||
let p_end = bs.subs(t1);
|
||||
let dist_start = (p_start.x - pick_pt.x as f64).hypot(p_start.y - pick_pt.z as f64);
|
||||
let dist_end = (p_end.x - pick_pt.x as f64).hypot(p_end.y - pick_pt.z as f64);
|
||||
let dist_start = (p_start.x - pick_pt.x as f64).hypot(p_start.y - pick_pt.y as f64);
|
||||
let dist_end = (p_end.x - pick_pt.x as f64).hypot(p_end.y - pick_pt.y as f64);
|
||||
let extend_end = dist_end <= dist_start;
|
||||
|
||||
// Find the parameter `t_new` such that the arc length from the fixed end to t_new = new_len.
|
||||
|
||||
Reference in new issue
Block a user