Reject two-line angular constraints over 180 degrees that can never be satisfied (#73) (#190)

This commit is contained in:
MarekSpodBiedry
2026-10-10 14:36:27 -04:00
committed by GitHub
parent 5a214a0cac
commit da4aa413c6
2 changed files with 17 additions and 1 deletions
+4 -1
View File
@@ -244,7 +244,10 @@ impl Built {
return need("two lines or an arc");
}
b.target = target.to_radians();
if !b.target.is_finite() || b.target.abs() > std::f64::consts::TAU {
// Two lines measure a signed angle in [-180, 180] and the sign is re-read from the geometry, so a larger
// target would flip the sign once solved and never be satisfied; only an arc sweep can reach a full turn.
let max = if b.form == Form::LL { std::f64::consts::PI } else { std::f64::consts::TAU };
if !b.target.is_finite() || b.target.abs() > max {
return Err("angle out of range".into());
}
}
+13
View File
@@ -155,6 +155,19 @@ fn symmetric_fix() {
ok(&mut d, con(ConstraintKind::Symmetric, &[w(p), w(q), w(axis)]));
}
#[test]
fn two_line_angle_over_180_is_rejected() {
let mut d = Drawing::default();
let a = line(&mut d, (0.0, 0.0), (10.0, 0.0));
let b = line(&mut d, (0.0, 0.0), (0.0, 5.0));
let before = (ln(&d, a), ln(&d, b));
assert!(add(&mut d, dim(ConstraintKind::Angular, &[w(a), w(b)], "", "200"), &SolveOptions::default()).is_err());
assert!(d.constraints.is_empty());
assert_eq!((ln(&d, a), ln(&d, b)), before);
ok(&mut d, dim(ConstraintKind::Angular, &[w(a), w(b)], "", "180"));
assert!(all_satisfied(&d));
}
#[test]
fn dimensional_constraints() {
let mut d = Drawing::default();