Ellipse dimensions: major radius (type major: centre to axis end) and minor radius (a radius dimension on the ellipse)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-08 03:34:02 +00:00
1 parent 59685a9180
commit 94a0cdef77
4 files changed
+36 -2

No files matched your search

+12
View File
@@ -1060,6 +1060,18 @@ fn dimension(s: &mut Session, p: &Value) -> Result<Value> {
let len = arc_len(sk, c).ok_or_else(|| bad(cmd, "arc length needs an arc"))?;
(ConstraintKind::ArcLength { c, value: len }, len)
}
((None, Some(c)), None) if matches!(sk.curves.get(c).map(|x| &x.kind), Some(CurveKind::Ellipse { .. })) => {
// Ellipse: the major radius is the centre–axis-end distance, the minor its own.
let Some(CurveKind::Ellipse { c: cp, m, r }) = sk.curves.get(c).map(|x| x.kind.clone()) else {
return Err(bad(cmd, "ellipse"));
};
if ty == "major" {
let d = sk.point(cp).zip(sk.point(m)).map(|(a, b)| a.dist(b)).unwrap_or(0.0);
(ConstraintKind::Distance { p: cp, q: m, value: d }, d)
} else {
(ConstraintKind::Radius { c, value: r }, r)
}
}
((None, Some(c)), None) => {
let r = sk.radius(c).ok_or_else(|| bad(cmd, "cannot dimension that curve"))?;
let diameter = ty == "diameter" || (ty != "radius" && is_circle(c));
@@ -382,3 +382,13 @@ fn trim_and_break_free_form_curves_exactly() {
assert!(d < 0.05, "{q:?} {d}");
}
}
#[test]
fn ellipse_radii_dimensions() {
let mut s = new_sketch();
let e = ids(&run(&mut s, "CircleElipse", json!({"center": [0, 0], "major": [10, 0], "minor_radius": 4}))["curves"])[0].clone();
run(&mut s, "SketchDimension", json!({"entities": [e], "type": "major", "value": 12}));
run(&mut s, "SketchDimension", json!({"entities": [e], "value": 5}));
let a = profiles(&s)[0];
assert!((a - std::f64::consts::PI * 60.0).abs() < 1e-6, "{a}");
}
+2
View File
@@ -647,6 +647,8 @@ impl Sketch {
need_line(a)?;
need_line(b)?;
}
// On an ellipse, a radius dimension holds its minor radius.
Radius { c, .. } if matches!(self.curves.get(c).map(|x| &x.kind), Some(CurveKind::Ellipse { .. })) => {}
Radius { c, .. } | Diameter { c, .. } => need_round(c)?,
Concentric { a, b } => {
need_round(a)?;
+12 -2
View File
@@ -157,6 +157,16 @@ impl State<'_> {
_ => Vec::new(),
}
}
/// Radius of a circle or arc; an ellipse's minor radius.
fn radius_of(&self, c: usize) -> f64 {
match self.sk.curves.get(c).map(|x| &x.kind) {
Some(CurveKind::Ellipse { r, .. }) => match self.lay.rvar.get(c).copied().flatten() {
Some(v) => self.x.get(v).copied().unwrap_or(*r),
None => *r,
},
_ => self.round(c).1,
}
}
fn ends(&self, c: usize) -> Option<(usize, usize)> {
self.sk.curves.get(c)?.kind.ends()
}
@@ -358,7 +368,7 @@ fn residuals(s: &State, k: &ConstraintKind, out: &mut Vec<f64>) {
let (a, b) = s.line(l);
out.push(a.dist(b) - value);
}
Radius { c, value } => out.push(s.round(c).1 - value),
Radius { c, value } => out.push(s.radius_of(c) - value),
Diameter { c, value } => out.push(2.0 * s.round(c).1 - value),
Angle { a, b, value, flip } => {
let (a0, a1) = s.line(a);
@@ -408,7 +418,7 @@ fn measure(s: &State, k: &ConstraintKind) -> Option<f64> {
let (a, b) = s.line(l);
a.dist(b)
}
Radius { c, .. } => s.round(c).1,
Radius { c, .. } => s.radius_of(c),
Diameter { c, .. } => 2.0 * s.round(c).1,
Angle { a, b, flip, .. } => {
let (a0, a1) = s.line(a);