///|
fn require_solved(s : @sketch.Sketch) -> @sketch.Solution {
match s.solve_and_apply() {
Ok(r) => {
if !r.report.is_satisfied() || r.report.local_dof != 0 {
abort("Mirror example did not reach a fully constrained solution")
}
r
}
Err(e) => abort(e.message())
}
}
///|
fn require_near(value : Double, expected : Double) -> Unit {
if (value - expected).abs() > 1.0e-5 {
abort("Unexpected geometry: \{value}; expected \{expected}")
}
}
///|
fn main {
let s = @sketch.Sketch::new()
let bottom = s.add_point(10.0, 0.0)
let top = s.add_point(10.0, 10.0)
let left = s.add_point(6.0, 3.0)
let right = s.add_point(13.0, 2.5)
let axis = s.add_line(bottom, top)
let left_hole = s.add_circle(left, 2.0)
let right_hole = s.add_circle(right, 1.5)
let bottom_fix = s.constrain(Fix(bottom, 10.0, 0.0))
let top_fix = s.constrain(Fix(top, 10.0, 10.0))
s.constrain(Fix(left, 6.0, 3.0)) |> ignore
s.constrain(Mirror(left, right, axis)) |> ignore
s.constrain(Radius(left_hole, 2.0)) |> ignore
s.constrain(EqualRadius(left_hole, right_hole)) |> ignore
let first = require_solved(s)
require_near(first.point(right).unwrap().x, 14.0)
require_near(first.point(right).unwrap().y, 3.0)
require_near(first.radius(right_hole).unwrap(), 2.0)
println("Mirrored holes: centers=(6,3),(14,3); radii=2")
s.set_constraint(bottom_fix, Fix(bottom, 12.0, 0.0)) |> ignore
s.set_constraint(top_fix, Fix(top, 12.0, 10.0)) |> ignore
let shifted = require_solved(s)
require_near(shifted.point(right).unwrap().x, 18.0)
require_near(shifted.point(right).unwrap().y, 3.0)
println("Axis moved to x=12: reflected center=(18,3)")
let previous = s.point(right).unwrap()
let conflict = s.constrain(Fix(right, 0.0, 0.0))
match s.solve_and_apply() {
Ok(r) =>
if r.report.is_satisfied() {
abort("Expected conflicting edit to fail")
}
Err(e) => abort(e.message())
}
let retained = s.point(right).unwrap()
if retained.x != previous.x || retained.y != previous.y {
abort("Failed mirror edit changed geometry")
}
s.set_constraint_enabled(conflict, false) |> ignore
require_solved(s) |> ignore
println("Conflicting edit rejected; geometry retained and relation recovered")
}