Skip to content

Commit 1b49afa

Browse files
committed
release: v0.2.2
1 parent c288c54 commit 1b49afa

2 files changed

Lines changed: 187 additions & 1 deletion

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ codegen-units = 1
2727
panic = "abort"
2828
opt-level = 3
2929
# for samply
30-
debug = 1
30+
#debug = 1
3131

3232
[[bench]]
3333
name = "nfp_bench100"

src/nfp_points.rs

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,4 +535,190 @@ mod tests {
535535
assert!(point.x != 0.0 || point.y != 0.0 || nfp.len() > 1);
536536
}
537537
}
538+
539+
#[test]
540+
fn test_nfp_collinear_points() {
541+
// Collinear points should still form a valid polygon (degenerate triangle)
542+
let triangle_a = vec![
543+
Point::new(0.0, 0.0),
544+
Point::new(1.0, 0.0),
545+
Point::new(0.5, 0.0), // Collinear with others
546+
];
547+
548+
let triangle_b = vec![
549+
Point::new(0.0, 0.0),
550+
Point::new(1.0, 1.0),
551+
Point::new(0.0, 1.0),
552+
];
553+
554+
let result = NFP::nfp(&triangle_a, &triangle_b);
555+
// Should complete without panicking (even if degenerate)
556+
assert!(result.is_ok());
557+
}
558+
559+
#[test]
560+
fn test_nfp_very_small_polygon() {
561+
// Minimal triangles (smallest valid polygon)
562+
let tiny_a = vec![
563+
Point::new(0.0, 0.0),
564+
Point::new(0.001, 0.0),
565+
Point::new(0.0005, 0.001),
566+
];
567+
568+
let tiny_b = vec![
569+
Point::new(0.0, 0.0),
570+
Point::new(0.002, 0.0),
571+
Point::new(0.001, 0.002),
572+
];
573+
574+
let result = NFP::nfp(&tiny_a, &tiny_b);
575+
assert!(result.is_ok());
576+
let nfp = result.unwrap();
577+
assert!(!nfp.is_empty());
578+
}
579+
580+
#[test]
581+
fn test_nfp_negative_coordinates() {
582+
// Polygons in negative coordinate space
583+
let triangle_a = vec![
584+
Point::new(-2.0, -2.0),
585+
Point::new(-1.0, -2.0),
586+
Point::new(-1.5, -1.0),
587+
];
588+
589+
let triangle_b = vec![
590+
Point::new(-3.0, -3.0),
591+
Point::new(-1.0, -3.0),
592+
Point::new(-2.0, -1.0),
593+
];
594+
595+
let result = NFP::nfp(&triangle_a, &triangle_b);
596+
assert!(result.is_ok());
597+
let nfp = result.unwrap();
598+
assert!(!nfp.is_empty());
599+
}
600+
601+
#[test]
602+
fn test_nfp_mixed_coordinate_signs() {
603+
// Polygons spanning multiple quadrants
604+
let triangle_a = vec![
605+
Point::new(-1.0, -1.0),
606+
Point::new(1.0, -1.0),
607+
Point::new(0.0, 1.0),
608+
];
609+
610+
let triangle_b = vec![
611+
Point::new(-0.5, -0.5),
612+
Point::new(0.5, -0.5),
613+
Point::new(0.0, 0.5),
614+
];
615+
616+
let result = NFP::nfp(&triangle_a, &triangle_b);
617+
assert!(result.is_ok());
618+
let nfp = result.unwrap();
619+
assert!(!nfp.is_empty());
620+
assert!(polygon::is_ccw(&nfp));
621+
}
622+
623+
#[test]
624+
fn test_nfp_identical_polygons() {
625+
// Two identical triangles
626+
let triangle = vec![
627+
Point::new(0.0, 0.0),
628+
Point::new(1.0, 0.0),
629+
Point::new(0.5, 1.0),
630+
];
631+
632+
let result = NFP::nfp(&triangle, &triangle);
633+
assert!(result.is_ok());
634+
let nfp = result.unwrap();
635+
assert!(!nfp.is_empty());
636+
}
637+
638+
#[test]
639+
fn test_nfp_very_thin_rectangle() {
640+
// Very thin elongated rectangle
641+
let thin_rect_a = vec![
642+
Point::new(0.0, 0.0),
643+
Point::new(10.0, 0.0),
644+
Point::new(10.0, 0.01),
645+
Point::new(0.0, 0.01),
646+
];
647+
648+
let square = vec![
649+
Point::new(0.0, 0.0),
650+
Point::new(1.0, 0.0),
651+
Point::new(1.0, 1.0),
652+
Point::new(0.0, 1.0),
653+
];
654+
655+
let result = NFP::nfp(&thin_rect_a, &square);
656+
assert!(result.is_ok());
657+
let nfp = result.unwrap();
658+
assert!(!nfp.is_empty());
659+
}
660+
661+
#[test]
662+
fn test_nfp_large_scale_coordinates() {
663+
// Polygons with very large coordinates
664+
let large_a = vec![
665+
Point::new(1000.0, 1000.0),
666+
Point::new(1100.0, 1000.0),
667+
Point::new(1050.0, 1100.0),
668+
];
669+
670+
let large_b = vec![
671+
Point::new(2000.0, 2000.0),
672+
Point::new(2050.0, 2000.0),
673+
Point::new(2025.0, 2050.0),
674+
];
675+
676+
let result = NFP::nfp(&large_a, &large_b);
677+
assert!(result.is_ok());
678+
let nfp = result.unwrap();
679+
assert!(!nfp.is_empty());
680+
}
681+
682+
#[test]
683+
fn test_nfp_right_angle_triangle() {
684+
// Right-angled triangle (standard form)
685+
let right_a = vec![
686+
Point::new(0.0, 0.0),
687+
Point::new(3.0, 0.0),
688+
Point::new(0.0, 4.0),
689+
];
690+
691+
let right_b = vec![
692+
Point::new(0.0, 0.0),
693+
Point::new(1.0, 0.0),
694+
Point::new(0.0, 1.0),
695+
];
696+
697+
let result = NFP::nfp(&right_a, &right_b);
698+
assert!(result.is_ok());
699+
let nfp = result.unwrap();
700+
assert!(!nfp.is_empty());
701+
assert!(polygon::is_ccw(&nfp));
702+
}
703+
704+
#[test]
705+
fn test_nfp_polygon_with_zero_area() {
706+
// Three points where area rounds to near-zero (but technically valid)
707+
// This tests robustness - should handle near-degenerate cases
708+
let point_a = vec![
709+
Point::new(0.0, 0.0),
710+
Point::new(1.0, 0.0),
711+
Point::new(1.0 + 1e-15, 1e-15), // Extremely close to collinear
712+
];
713+
714+
let point_b = vec![
715+
Point::new(0.0, 0.0),
716+
Point::new(0.5, 0.0),
717+
Point::new(0.25, 0.5),
718+
];
719+
720+
let result = NFP::nfp(&point_a, &point_b);
721+
// Should complete without panicking
722+
assert!(result.is_ok());
723+
}
538724
}

0 commit comments

Comments
 (0)