forked from 1b-agent/opencadstudio-upstream
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:
1 parent
3a3d2e4a84
commit
6ef399d83b
1 file changed
+33
-5
@@ -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))
|
||||
|
||||
Reference in new issue
Block a user