mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-26 11:56:50 -06:00
Keep line and arc elevation when lengthening with LENGTHEN (#1313)
Found while testing crates/engine/src/cmd/modify2.rs:764 Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
a3b3e1281f
commit
1ac2ebaad2
@@ -761,7 +761,13 @@ pub(crate) fn lengthen_kind(k: &EntityKind, pick: Option<Vec2>, mode: LenMode) -
|
||||
return Err(too_short());
|
||||
}
|
||||
let ne = fixed + dir * nl;
|
||||
Ok(if at_b { line(a, ne) } else { line(ne, b) })
|
||||
let mut out = l.clone();
|
||||
if at_b {
|
||||
out.b = ne.to3(l.b.z);
|
||||
} else {
|
||||
out.a = ne.to3(l.a.z);
|
||||
}
|
||||
Ok(EntityKind::Line(out))
|
||||
}
|
||||
EntityKind::Arc(ar) => {
|
||||
let g = Arc::new(ar.center.xy(), ar.radius, ar.start, ar.end);
|
||||
@@ -782,7 +788,8 @@ pub(crate) fn lengthen_kind(k: &EntityKind, pick: Option<Vec2>, mode: LenMode) -
|
||||
if !(ns > 1e-12 && ns < TAU - 1e-9) {
|
||||
return Err(other("The new arc would be zero length or a full circle."));
|
||||
}
|
||||
Ok(if at_end { arc(&Arc::new(g.center, g.radius, g.start, g.start + ns)) } else { arc(&Arc::new(g.center, g.radius, g.end - ns, g.end)) })
|
||||
let na = if at_end { Arc::new(g.center, g.radius, g.start, g.start + ns) } else { Arc::new(g.center, g.radius, g.end - ns, g.end) };
|
||||
Ok(EntityKind::Arc(cadcraft_doc::Arc { radius: na.radius, start: na.start, end: na.end, ..ar.clone() }))
|
||||
}
|
||||
EntityKind::LwPolyline(p) if !p.closed && p.vertices.len() >= 2 => {
|
||||
let total = Polyline { vertices: p.vertices.clone(), closed: false }.len();
|
||||
|
||||
@@ -214,6 +214,39 @@ fn lengthen_json() {
|
||||
assert!(near(poly(&kind(&s, &p)).vertices[0].p, -5.0, 10.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lengthen_keeps_elevation() {
|
||||
let mut s = Session::new();
|
||||
let l = h(&s.execute("line", &json!({"points": [[0, 0], [10, 0]]})).unwrap());
|
||||
let a = h(&s.execute("arc", &json!({"center": [0, 0], "radius": 1, "start": 0, "end": 90})).unwrap());
|
||||
let doc = s.doc_mut().unwrap();
|
||||
doc.modify_entity(Handle::parse_hex(&l).unwrap(), |e| {
|
||||
if let EntityKind::Line(x) = &mut e.kind {
|
||||
x.a.z = 5.0;
|
||||
x.b.z = 5.0;
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
doc.modify_entity(Handle::parse_hex(&a).unwrap(), |e| {
|
||||
if let EntityKind::Arc(x) = &mut e.kind {
|
||||
x.center.z = 3.0;
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
s.execute("lengthen", &json!({"handle": l, "delta": 2})).unwrap();
|
||||
let EntityKind::Line(x) = kind(&s, &l) else { panic!("not a line") };
|
||||
assert_eq!((x.a.x, x.a.y, x.a.z), (0.0, 0.0, 5.0));
|
||||
assert_eq!((x.b.x, x.b.y, x.b.z), (12.0, 0.0, 5.0));
|
||||
s.execute("lengthen", &json!({"handle": l, "delta": 1, "pick": [0, 0]})).unwrap();
|
||||
let EntityKind::Line(x) = kind(&s, &l) else { panic!("not a line") };
|
||||
assert_eq!((x.a.x, x.a.y, x.a.z), (-1.0, 0.0, 5.0));
|
||||
assert_eq!((x.b.x, x.b.y, x.b.z), (12.0, 0.0, 5.0));
|
||||
s.execute("lengthen", &json!({"handle": a, "deltaAngle": 10})).unwrap();
|
||||
let EntityKind::Arc(x) = kind(&s, &a) else { panic!("not an arc") };
|
||||
assert_eq!(x.center.z, 3.0);
|
||||
assert!((arc_of(&kind(&s, &a)).sweep() - 100f64.to_radians()).abs() < 1e-9);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lengthen_command_line() {
|
||||
let mut s = Session::new();
|
||||
|
||||
Reference in New Issue
Block a user