mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-25 03:16:50 -06:00
"Specify the reference angle <0>" takes a typed angle or two points; "Specify the new angle or [Points] <0>" takes a typed angle, a point measured from the base point, or two points after `P`. The objects turn by the new angle minus the reference angle. Previously Reference only said "not available yet" and the values that followed were misread or run as commands. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
46 lines
1.7 KiB
Rust
46 lines
1.7 KiB
Rust
//! ROTATE Reference: the reference angle (typed, or two points), then the new angle (typed, a
|
|
//! point measured from the base point, or two points after `P`).
|
|
|
|
use cadcraft_engine::Session;
|
|
use cadcraft_engine::doc::EntityKind;
|
|
|
|
fn session_with_line(l: &str) -> Session {
|
|
let mut s = Session::new();
|
|
s.cmdline(&format!("LINE {l}")).unwrap();
|
|
s.cmdline("").unwrap();
|
|
s
|
|
}
|
|
|
|
/// The end point of the only line.
|
|
fn end(s: &Session) -> (f64, f64) {
|
|
let e = s.doc().unwrap().model.iter().find_map(|e| if let EntityKind::Line(l) = &e.kind { Some((l.b.x, l.b.y)) } else { None });
|
|
e.unwrap()
|
|
}
|
|
|
|
fn near(a: (f64, f64), b: (f64, f64)) -> bool {
|
|
(a.0 - b.0).abs() < 1e-9 && (a.1 - b.1).abs() < 1e-9
|
|
}
|
|
|
|
#[test]
|
|
fn rotate_reference_typed_angles() {
|
|
// Reference 30, new angle 120: rotates by 90 degrees.
|
|
let mut s = session_with_line("0,0 10,0");
|
|
s.script("ROTATE ALL 0,0 R 30 120\nCIRCLE 0,0 1\n").unwrap();
|
|
assert!(near(end(&s), (0.0, 10.0)), "{:?} {:?}", end(&s), s.log);
|
|
assert_eq!(s.doc().unwrap().model.len(), 2, "the tokens after ROTATE are not run as commands");
|
|
}
|
|
|
|
#[test]
|
|
fn rotate_reference_by_points() {
|
|
// Reference from the line itself (0 degrees), new angle towards 0,10: 90 degrees.
|
|
let mut s = session_with_line("0,0 10,0");
|
|
s.script("ROTATE ALL 0,0 R 0,0 10,0 0,10\n").unwrap();
|
|
assert!(s.running.is_none(), "{}", s.prompt_text());
|
|
assert!(near(end(&s), (0.0, 10.0)), "{:?}", end(&s));
|
|
// New angle by two points (`P`): from 5,5 to 5,-5 is -90 degrees.
|
|
let mut s = session_with_line("0,0 10,0");
|
|
s.script("ROTATE ALL 0,0 R 0 P 5,5 5,-5\n").unwrap();
|
|
assert!(s.running.is_none(), "{}", s.prompt_text());
|
|
assert!(near(end(&s), (0.0, -10.0)), "{:?}", end(&s));
|
|
}
|