ARC: a number typed at the end point is the arc length

After Center and Start, typing a length now draws the arc that long along
the circle, running towards the side of the start point the pointer is on.
A length of a full circle or more keeps the prompt.

Closes #1408

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-10-17 20:03:14 +03:00
1 parent 3a3d2e4a84
commit 6ef399d83b
1 file changed
+33 -5
+33 -5
View File
@@ -1698,6 +1698,9 @@ pub struct ArcCommand {
step: ArcStep,
cw: bool,
plane: WorkingPlane,
/// Last pointer position at the end step: a typed arc length runs from
/// the start point towards it.
cursor: Option<DVec3>,
}
impl ArcCommand {
@@ -1706,6 +1709,7 @@ impl ArcCommand {
step: ArcStep::Start,
cw: false,
plane: WorkingPlane::default(),
cursor: None,
}
}
@@ -1754,6 +1758,24 @@ impl ArcCommand {
})
}
/// Arc about `c` from `s` whose length along the circle is `len`, running
/// towards the side of the start point the pointer is on.
fn sc_arc_length(&self, s: DVec3, c: DVec3, len: f64) -> Option<(DVec3, f64, f64, f64)> {
let r = c.distance(s);
if r < 1e-9 || len <= 0.0 || len >= TAU * r {
return None;
}
let toward = self
.cursor
.map(|cursor| (angle_xy(c, cursor, self.plane) - angle_xy(c, s, self.plane)).rem_euclid(TAU));
let ccw = match toward {
Some(span) if span > 1e-9 => span <= std::f64::consts::PI,
_ => !self.cw,
};
let span = len / r;
self.sc_angle(s, c, if ccw { span } else { -span })
}
/// Sweep from `s` to the cursor about `c`, going the way Ctrl says.
fn cursor_span(&self, s: DVec3, c: DVec3, cursor: DVec3) -> f64 {
let span = (angle_xy(c, cursor, self.plane) - angle_xy(c, s, self.plane)).rem_euclid(TAU);
@@ -1960,7 +1982,11 @@ impl CadCommand for ArcCommand {
self.step = ArcStep::LengthSC { s, c };
Some(CmdResult::NeedPoint)
}
_ => None,
// A bare number is the arc's length along the circle (#1408).
_ => {
let len = Self::typed_number(text)?;
Some(self.commit(self.sc_arc_length(s, c, len)))
}
},
ArcStep::CenterSE { s, e } => match upper.as_str() {
"A" | "ANGLE" => {
@@ -2135,10 +2161,12 @@ impl CadCommand for ArcCommand {
.into_iter()
.collect()
}
ArcStep::EndSC { s, c } => self
.preview(self.sc_end(s, c, pt), line_wire(c, pt))
.into_iter()
.collect(),
ArcStep::EndSC { s, c } => {
self.cursor = Some(pt);
self.preview(self.sc_end(s, c, pt), line_wire(c, pt))
.into_iter()
.collect()
}
ArcStep::AngleSC { s, c } => {
let span = self.cursor_span(s, c, pt);
self.preview(self.sc_angle(s, c, span), line_wire(c, pt))