Thanks @DuBearte.
This commit is contained in:
1 parent
26bf1af93b
commit
25c89a706e
2 files changed
+46
-8
No files matched your search
@@ -659,15 +659,26 @@ fn arc_tangent(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let end = req_vec2(cmd, p, "end")?;
|
||||
let (out, info) = edit(s, p, cmd, false, |sk, _| {
|
||||
let st = req_parg(sk, p, "start", cmd)?;
|
||||
let pi = st.idx().ok_or_else(|| bad(cmd, "`start` must be the end point of a line or arc"))?;
|
||||
let ci = match str_(p, "curve") {
|
||||
Some(id) => sk.curve_index(id).ok_or_else(|| bad(cmd, format!("unknown curve `{id}`")))?,
|
||||
None => sk
|
||||
.curves
|
||||
let picked = st.idx().ok_or_else(|| bad(cmd, "`start` must be the end point of a line or arc"))?;
|
||||
// The picked point, then any other point at the same place: a trimmed arc's end is its own
|
||||
// point, lying on the end of the curve that trimmed it, which is the one a click picks (#1485).
|
||||
let at = st.pos();
|
||||
let tol = 1e-6 * at.len().max(1.0);
|
||||
let candidates: Vec<usize> =
|
||||
std::iter::once(picked).chain((0..sk.points.len()).filter(|&q| q != picked && sk.point(q).is_some_and(|x| x.dist(at) <= tol))).collect();
|
||||
let (ci, pi) = match str_(p, "curve") {
|
||||
Some(id) => {
|
||||
let ci = sk.curve_index(id).ok_or_else(|| bad(cmd, format!("unknown curve `{id}`")))?;
|
||||
let pi = candidates
|
||||
.iter()
|
||||
.copied()
|
||||
.find(|&q| leaving_dir(sk, ci, q).is_some())
|
||||
.ok_or_else(|| bad(cmd, "`start` is not an end of that curve"))?;
|
||||
(ci, pi)
|
||||
}
|
||||
None => candidates
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(i, c)| !c.construction && leaving_dir(sk, *i, pi).is_some())
|
||||
.map(|(i, _)| i)
|
||||
.find_map(|&q| sk.curves.iter().enumerate().find(|(i, c)| !c.construction && leaving_dir(sk, *i, q).is_some()).map(|(i, _)| (i, q)))
|
||||
.ok_or_else(|| bad(cmd, "no line or arc ends at `start`"))?,
|
||||
};
|
||||
let t = leaving_dir(sk, ci, pi).ok_or_else(|| bad(cmd, "`start` is not an end of that curve"))?;
|
||||
|
||||
@@ -310,6 +310,33 @@ fn offset_chain_mirror_patterns_move_scale() {
|
||||
assert!(sk.center(sk.curve_index(&cp).unwrap()).unwrap().dist(Vec2::new(-110.0, 0.0)) < 1e-7);
|
||||
}
|
||||
|
||||
/// #1485: after a circle is trimmed between two construction lines, clicking the trimmed end
|
||||
/// picks the construction line's end lying there, not the arc's own; the tangent arc still starts
|
||||
/// from the trimmed arc, tangent to it.
|
||||
#[test]
|
||||
fn a_tangent_arc_starts_from_a_trimmed_end() {
|
||||
let mut s = new_sketch();
|
||||
let c = ids(&run(&mut s, "sketch.circle.center", json!({"center": [0, 0], "radius": 10}))["curves"])[0].clone();
|
||||
run(&mut s, "sketch.line", json!({"points": [[0, 0], [10, 0]], "ids": ["guide_a"]}));
|
||||
run(&mut s, "sketch.line", json!({"points": [[0, 0], [0, 10]], "ids": ["guide_b"]}));
|
||||
run(&mut s, "sketch.construction", json!({"curves": ["guide_a", "guide_b"]}));
|
||||
run(&mut s, "sketch.trim", json!({"curve": c, "at": [7.07, 7.07]}));
|
||||
let sk = sketch(&s);
|
||||
let picked = sk.resolve_point("guide_a.end").unwrap();
|
||||
assert!(sk.point(picked).unwrap().dist(Vec2::new(10.0, 0.0)) < 1e-6);
|
||||
let trimmed = sk.curves.iter().position(|cu| !cu.construction && matches!(cu.kind, CurveKind::Arc { .. })).expect("the trimmed arc");
|
||||
let r = run(&mut s, "sketch.arc.tangent", json!({"start": "guide_a.end", "end": [14, 6]}));
|
||||
let sk = sketch(&s);
|
||||
let a = sk.curve_index(&ids(&r["curves"])[0]).unwrap();
|
||||
let a_ends: Vec<usize> = sk.curves[a].kind.point_ids();
|
||||
let t_ends: Vec<usize> = sk.curves[trimmed].kind.point_ids();
|
||||
assert!(a_ends.iter().any(|q| t_ends.contains(q) && *q != picked), "the new arc shares the trimmed arc's own end");
|
||||
assert!(
|
||||
sk.constraints.iter().any(|k| matches!(k.kind, ConstraintKind::Tangent { a: x, b: y } if (x, y) == (trimmed, a) || (x, y) == (a, trimmed))),
|
||||
"and is tangent to it"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_creation_tools() {
|
||||
let mut s = new_sketch();
|
||||
|
||||
Reference in new issue
Block a user