95 lines
3.1 KiB
Rust
95 lines
3.1 KiB
Rust
//! The exact output of every Pathfinder operation, pinned so that work on the windings and the
|
|
//! coverage tests can't change it: overlapping ellipses, rectangles and stars (even-odd and
|
|
//! non-zero, repeated keys for Merge) at a few counts.
|
|
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
|
|
|
use vectorcraft_geom::{FillRule, Point, Rect, shapes};
|
|
use vectorcraft_pathops::{PathfinderOp, Shape, pathfinder};
|
|
|
|
fn shapes_of(n: usize, seed: u64) -> Vec<Shape> {
|
|
let mut r = seed | 1;
|
|
let mut next = || {
|
|
r ^= r << 13;
|
|
r ^= r >> 7;
|
|
r ^= r << 17;
|
|
(r % 1_000_000) as f64 / 1_000_000.0
|
|
};
|
|
(0..n)
|
|
.map(|i| {
|
|
let (x, y, s) = (next() * 200.0, next() * 150.0, 15.0 + next() * 40.0);
|
|
let path = match i % 3 {
|
|
0 => shapes::ellipse(Rect::from_center_size(Point::new(x, y), (2.0 * s, 1.4 * s))),
|
|
1 => shapes::rectangle(Rect::new(x, y, x + 1.5 * s, y + s)),
|
|
_ => shapes::star(Point::new(x, y), s, s / 2.0, 5, 0.3),
|
|
};
|
|
let rule = if i % 4 == 3 { FillRule::EvenOdd } else { FillRule::NonZero };
|
|
Shape::new(path, rule, (i % 5) as u64)
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
fn fnv(s: &str) -> u64 {
|
|
s.bytes().fold(0xcbf2_9ce4_8422_2325, |h, b| (h ^ u64::from(b)).wrapping_mul(0x100_0000_01b3))
|
|
}
|
|
|
|
#[test]
|
|
fn every_pathfinder_operation_is_pinned() {
|
|
use PathfinderOp::*;
|
|
let ops = [Unite, MinusFront, MinusBack, Intersect, Exclude, Divide, Trim, Merge, Crop, Outline];
|
|
let mut got = vec![];
|
|
for (n, seed) in [(2, 3), (5, 7), (12, 11), (30, 13)] {
|
|
let input = shapes_of(n, seed);
|
|
for op in ops {
|
|
let out = pathfinder(op, &input);
|
|
let text: String = out.iter().map(|s| format!("{}|{:?}|{:?};", s.key, s.rule, s.path)).collect();
|
|
got.push(fnv(&text));
|
|
}
|
|
}
|
|
assert_eq!(got.len(), PINNED.len());
|
|
assert_eq!(got, PINNED);
|
|
}
|
|
|
|
/// Computed with the dense windings (main at b08482d6).
|
|
const PINNED: [u64; 40] = [
|
|
0x5e62_baae_d8b4_dba5,
|
|
0x2bbc_e138_a97c_5a28,
|
|
0xce78_992e_750b_1092,
|
|
0x30cf_cc0b_861c_48b4,
|
|
0xe6e4_2a29_1e16_5e86,
|
|
0x390b_0633_5066_6292,
|
|
0x06b7_3884_f961_c343,
|
|
0x06b7_3884_f961_c343,
|
|
0x0384_d599_5a03_dafd,
|
|
0x3dcd_029a_dd3f_fa38,
|
|
0x8249_71f8_fda4_2bb6,
|
|
0xe7f2_8633_cef9_a76c,
|
|
0x1a11_084e_721e_ac3b,
|
|
0xcbf2_9ce4_8422_2325,
|
|
0xa786_d973_a0d7_ca2a,
|
|
0x389b_c89a_0ccf_578f,
|
|
0xff9d_cf53_d872_681e,
|
|
0xff9d_cf53_d872_681e,
|
|
0xcbf2_9ce4_8422_2325,
|
|
0x6be3_02a6_d9c9_e80e,
|
|
0x3525_cabe_b235_aaef,
|
|
0xf969_aa07_a44d_1770,
|
|
0xed13_60c7_0aaa_7854,
|
|
0xcbf2_9ce4_8422_2325,
|
|
0x6550_a381_db6b_a35f,
|
|
0x1ba9_6dfb_89ea_ac78,
|
|
0x1344_b467_dd20_5f02,
|
|
0x948f_e2a1_d657_0d4c,
|
|
0x49a4_5c3c_2d96_14af,
|
|
0x16a7_ce9e_4a3c_0974,
|
|
0x0b12_c643_a446_da04,
|
|
0xcbf2_9ce4_8422_2325,
|
|
0xeb6a_6614_cea5_a508,
|
|
0xcbf2_9ce4_8422_2325,
|
|
0xb9c4_2803_7db9_bd4f,
|
|
0x34b6_90d5_e443_b799,
|
|
0xdfaf_ecbd_2d58_3227,
|
|
0x6d5e_6e8d_b05b_8688,
|
|
0x59dc_9268_a73f_e92e,
|
|
0x5a83_5cbd_1f8c_5143,
|
|
];
|