diff --git a/crates/engine/src/cmd/draw.rs b/crates/engine/src/cmd/draw.rs index 953ad4c..9b90f8c 100644 --- a/crates/engine/src/cmd/draw.rs +++ b/crates/engine/src/cmd/draw.rs @@ -822,7 +822,10 @@ impl Interactive for EllipseM { ge.param_of(p) } Input::Text(t) => { - crate::units::parse_angle(&t).ok_or_else(|| crate::EngineError::Other("Requires an angle.".into()))? + e.major.angle() + // A typed angle is a true angle from the major axis; convert it to an ellipse parameter like a picked point. + let a = crate::units::parse_angle(&t).ok_or_else(|| crate::EngineError::Other("Requires an angle.".into()))?; + let ge = Ellipse { start: 0.0, end: cadcraft_geom::TAU, ..e }; + ge.param_of(e.center + Vec2::from_angle(a + e.major.angle())) } _ => return Ok(Step::Continue), }; diff --git a/crates/engine/src/cmd/draw2_tests.rs b/crates/engine/src/cmd/draw2_tests.rs index 75c6fd9..723dd64 100644 --- a/crates/engine/src/cmd/draw2_tests.rs +++ b/crates/engine/src/cmd/draw2_tests.rs @@ -237,6 +237,17 @@ fn ellipse_axis_and_arc() { assert!(matches!(last(&s), EntityKind::Ellipse(e) if (e.end - e.start).abs() > 0.1 && (e.end - e.start).abs() < 6.0)); } +#[test] +fn ellipse_arc_typed_angles_are_true_angles() { + let want = 2f64.atan2(1.0); + // Horizontal and rotated major axis, ratio 0.5: typed 0 and 45 degrees match the JSON form. + for line in ["ellipse.arc 0,0 10,0 2.5 0 45", "ellipse.arc 5,-5 5,5 2.5 0 45"] { + let mut s = Session::new(); + s.cmdline(line).unwrap(); + assert!(matches!(last(&s), EntityKind::Ellipse(e) if e.start.abs() < 1e-9 && (e.end - want).abs() < 1e-9), "{line}"); + } +} + // ---------------- DIVIDE / MEASURE ---------------- #[test]