1use core::cmp::Ordering;
4use core::fmt;
5use core::ops::Add;
6use core::ops::AddAssign;
7use core::ops::Bound;
8use core::ops::Range;
9use core::ops::RangeBounds;
10use core::ops::RangeInclusive;
11use core::ops::Sub;
12use core::ops::SubAssign;
13
14#[cfg(feature = "random")]
15use rand::distributions::uniform::SampleUniform;
16#[cfg(feature = "random")]
17use rand::Rng;
18
19use crate::layout::Points;
20use crate::p2d;
21use crate::p3d;
22use crate::p4d;
23use crate::Integer;
24use crate::Layout;
25use crate::Layout2d;
26use crate::Layout3d;
27use crate::Layout4d;
28use crate::Point;
29use crate::Point2d;
30use crate::Point3d;
31use crate::Point4d;
32use crate::Vec2d;
33use crate::Vec3d;
34use crate::Vec4d;
35use crate::Vector;
36
37#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
41pub struct BBox<S: Integer, V: Vector<S>> {
42 min: Point<S, V>,
44 max: Point<S, V>,
46}
47
48pub type BBox2d<S = i64> = BBox<S, Vec2d<S>>;
50pub type BBox3d<S = i64> = BBox<S, Vec3d<S>>;
52pub type BBox4d<S = i64> = BBox<S, Vec4d<S>>;
54
55impl<S, V> BBox<S, V>
56where
57 S: Integer,
58 V: Vector<S>,
59{
60 pub fn new(origin: Point<S, V>, size: V) -> BBox<S, V> {
64 let min = origin;
65 let max = Point::with(|i| origin[i] + size[i] - S::one());
66 assert!(size.as_slice().iter().all(|&c| c > S::zero()));
67 BBox { min, max }
68 }
69 #[deprecated = "Use `from` instead."]
80 pub fn from_point(p: Point<S, V>) -> BBox<S, V> {
81 BBox { min: p, max: p }
82 }
83 #[deprecated = "Use `from_corners` instead."]
85 pub fn from_points(p0: Point<S, V>, p1: Point<S, V>) -> BBox<S, V> {
86 let min = p0.min(p1);
87 let max = p0.max(p1);
88 BBox { min, max }
89 }
90 pub fn from_corners(p0: Point<S, V>, p1: Point<S, V>) -> BBox<S, V> {
102 let min = p0.min(p1);
103 let max = p0.max(p1);
104 BBox { min, max }
105 }
106 pub fn enclosing<'a, II>(ii: II) -> Option<BBox<S, V>>
118 where
119 S: 'a,
120 V: 'a,
121 II: IntoIterator<Item = &'a Point<S, V>>,
122 {
123 let mut iter = ii.into_iter();
124 if let Some(p0) = iter.next() {
125 let mut bbox = BBox::from(*p0);
126 for p in iter {
127 bbox.extend_to(*p);
128 }
129 Some(bbox)
130 } else {
131 None
132 }
133 }
134 pub fn min(&self) -> Point<S, V> {
145 self.min
146 }
147 pub fn max(&self) -> Point<S, V> {
158 self.max
159 }
160
161 pub fn lengths(&self) -> V {
172 self.max - self.min + V::ones()
173 }
174
175 pub fn volume(&self) -> usize
186 where
187 usize: TryFrom<S>,
188 <usize as TryFrom<S>>::Error: fmt::Debug,
189 {
190 self.lengths()
191 .as_slice()
192 .iter()
193 .map(|&len| len.to_usize())
194 .product()
195 }
196
197 pub fn center(&self) -> Point<S, V> {
212 Point::<S, V>::from((self.min.to_vec() + self.max.to_vec()) / S::two())
213 }
214
215 pub fn lub(&self, other: &BBox<S, V>) -> BBox<S, V> {
229 let min = self.min().min(other.min());
230 let max = self.max().max(other.max());
231 BBox { min, max }
232 }
233
234 pub fn intersection(&self, other: &BBox<S, V>) -> Option<BBox<S, V>> {
246 let min = self.min().max(other.min());
247 let max = self.max().min(other.max());
248 match min.componentwise_cmp(&max) {
249 Some(Ordering::Less) | Some(Ordering::Equal) => Some(BBox { min, max }),
250 _ => None,
251 }
252 }
253
254 pub fn extended_to(&self, p: Point<S, V>) -> BBox<S, V> {
266 let min = self.min().min(p);
267 let max = self.max().max(p);
268 BBox { min, max }
269 }
270
271 pub fn extend_to(&mut self, p: Point<S, V>) {
284 self.min = self.min().min(p);
285 self.max = self.max().max(p);
286 }
287
288 pub fn clamp(&self, p: Point<S, V>) -> Point<S, V> {
303 p.max(self.min).min(self.max)
304 }
305
306 pub fn contains(&self, p: &Point<S, V>) -> bool {
318 self.clamp(*p) == *p
319 }
320}
321
322impl<S> BBox2d<S>
323where
324 S: Integer,
325{
326 #[deprecated = "Use `bb2d` instead."]
330 pub fn from_bounds(x_start: S, x_end: S, y_start: S, y_end: S) -> BBox2d<S> {
331 assert!(x_start <= x_end && y_start <= y_end);
332 let min = p2d(x_start, y_start);
333 let max = p2d(x_end - S::one(), y_end - S::one());
334 BBox { min, max }
335 }
336
337 pub fn x_start(&self) -> S {
339 self.min.x()
340 }
341 pub fn x_end(&self) -> S {
343 self.max.x() + S::one()
344 }
345 pub fn x_min(&self) -> S {
347 self.min.x()
348 }
349 pub fn x_max(&self) -> S {
351 self.max.x()
352 }
353
354 pub fn y_start(&self) -> S {
356 self.min.y()
357 }
358 pub fn y_end(&self) -> S {
360 self.max.y() + S::one()
361 }
362 pub fn y_min(&self) -> S {
364 self.min.y()
365 }
366 pub fn y_max(&self) -> S {
368 self.max.y()
369 }
370
371 pub fn x_len(&self) -> S {
373 self.max.x() - self.min.x() + S::one()
374 }
375
376 pub fn y_len(&self) -> S {
378 self.max.y() - self.min.y() + S::one()
379 }
380
381 pub fn area(&self) -> usize
383 where
384 usize: TryFrom<S>,
385 <usize as TryFrom<S>>::Error: fmt::Debug,
386 {
387 self.volume()
388 }
389
390 pub fn x_range(&self) -> Range<S> {
392 self.x_start()..self.x_end()
393 }
394 pub fn y_range(&self) -> Range<S> {
396 self.y_start()..self.y_end()
397 }
398
399 pub fn iter(&self) -> Points<S, Vec2d<S>, Layout2d<S>>
403 where
404 usize: TryFrom<S>,
405 <usize as TryFrom<S>>::Error: fmt::Debug,
406 {
407 Layout2d::new(*self).points()
408 }
409
410 #[cfg(feature = "random")]
414 pub fn random_point<R>(&self, rng: &mut R) -> Point2d<S>
415 where
416 R: Rng,
417 S: SampleUniform,
418 {
419 let x = rng.gen_range(self.x_range());
420 let y = rng.gen_range(self.y_range());
421 p2d(x, y)
422 }
423}
424
425impl<S> BBox3d<S>
426where
427 S: Integer,
428{
429 pub fn x_start(&self) -> S {
431 self.min.x()
432 }
433 pub fn x_end(&self) -> S {
435 self.max.x() + S::one()
436 }
437 pub fn x_min(&self) -> S {
439 self.min.x()
440 }
441 pub fn x_max(&self) -> S {
443 self.max.x()
444 }
445
446 pub fn y_start(&self) -> S {
448 self.min.y()
449 }
450 pub fn y_end(&self) -> S {
452 self.max.y() + S::one()
453 }
454 pub fn y_min(&self) -> S {
456 self.min.y()
457 }
458 pub fn y_max(&self) -> S {
460 self.max.y()
461 }
462
463 pub fn z_start(&self) -> S {
465 self.min.z()
466 }
467 pub fn z_end(&self) -> S {
469 self.max.z() + S::one()
470 }
471 pub fn z_min(&self) -> S {
473 self.min.z()
474 }
475 pub fn z_max(&self) -> S {
477 self.max.z()
478 }
479
480 pub fn x_len(&self) -> S {
482 self.max.x() - self.min.x() + S::one()
483 }
484 pub fn y_len(&self) -> S {
486 self.max.y() - self.min.y() + S::one()
487 }
488 pub fn z_len(&self) -> S {
490 self.max.z() - self.min.z() + S::one()
491 }
492
493 pub fn x_range(&self) -> Range<S> {
495 self.x_start()..self.x_end()
496 }
497 pub fn y_range(&self) -> Range<S> {
499 self.y_start()..self.y_end()
500 }
501 pub fn z_range(&self) -> Range<S> {
503 self.z_start()..self.z_end()
504 }
505
506 pub fn iter(&self) -> Points<S, Vec3d<S>, Layout3d<S>>
510 where
511 usize: TryFrom<S>,
512 <usize as TryFrom<S>>::Error: fmt::Debug,
513 {
514 Layout3d::new(*self).points()
515 }
516
517 #[cfg(feature = "random")]
521 pub fn random_point<R>(&self, rng: &mut R) -> Point3d<S>
522 where
523 R: Rng,
524 S: SampleUniform,
525 {
526 let x = rng.gen_range(self.x_range());
527 let y = rng.gen_range(self.y_range());
528 let z = rng.gen_range(self.z_range());
529 p3d(x, y, z)
530 }
531}
532
533impl<S> BBox4d<S>
534where
535 S: Integer,
536{
537 pub fn x_start(&self) -> S {
539 self.min.x()
540 }
541 pub fn x_end(&self) -> S {
543 self.max.x() + S::one()
544 }
545 pub fn x_min(&self) -> S {
547 self.min.x()
548 }
549 pub fn x_max(&self) -> S {
551 self.max.x()
552 }
553
554 pub fn y_start(&self) -> S {
556 self.min.y()
557 }
558 pub fn y_end(&self) -> S {
560 self.max.y() + S::one()
561 }
562 pub fn y_min(&self) -> S {
564 self.min.y()
565 }
566 pub fn y_max(&self) -> S {
568 self.max.y()
569 }
570
571 pub fn z_start(&self) -> S {
573 self.min.z()
574 }
575 pub fn z_end(&self) -> S {
577 self.max.z() + S::one()
578 }
579 pub fn z_min(&self) -> S {
581 self.min.z()
582 }
583 pub fn z_max(&self) -> S {
585 self.max.z()
586 }
587
588 pub fn w_start(&self) -> S {
590 self.min.w()
591 }
592 pub fn w_end(&self) -> S {
594 self.max.w() + S::one()
595 }
596 pub fn w_min(&self) -> S {
598 self.min.w()
599 }
600 pub fn w_max(&self) -> S {
602 self.max.w()
603 }
604
605 pub fn x_len(&self) -> S {
607 self.max.x() - self.min.x() + S::one()
608 }
609 pub fn y_len(&self) -> S {
611 self.max.y() - self.min.y() + S::one()
612 }
613 pub fn z_len(&self) -> S {
615 self.max.z() - self.min.z() + S::one()
616 }
617 pub fn w_len(&self) -> S {
619 self.max.w() - self.min.w() + S::one()
620 }
621
622 pub fn x_range(&self) -> Range<S> {
624 self.x_start()..self.x_end()
625 }
626 pub fn y_range(&self) -> Range<S> {
628 self.y_start()..self.y_end()
629 }
630 pub fn z_range(&self) -> Range<S> {
632 self.z_start()..self.z_end()
633 }
634 pub fn w_range(&self) -> Range<S> {
636 self.w_start()..self.w_end()
637 }
638
639 pub fn iter(&self) -> Points<S, Vec4d<S>, Layout4d<S>>
643 where
644 usize: TryFrom<S>,
645 <usize as TryFrom<S>>::Error: fmt::Debug,
646 {
647 Layout4d::new(*self).points()
648 }
649
650 #[cfg(feature = "random")]
654 pub fn random_point<R>(&self, rng: &mut R) -> Point4d<S>
655 where
656 R: Rng,
657 S: SampleUniform,
658 {
659 let x = rng.gen_range(self.x_range());
660 let y = rng.gen_range(self.y_range());
661 let z = rng.gen_range(self.z_range());
662 let w = rng.gen_range(self.w_range());
663 p4d(x, y, z, w)
664 }
665}
666
667fn to_range_inclusive<S, R>(r: R) -> RangeInclusive<S>
668where
669 S: Integer,
670 R: RangeBounds<S>,
671{
672 let start = match r.start_bound() {
673 Bound::Included(s) => *s,
674 Bound::Excluded(s) => *s + S::one(),
675 Bound::Unbounded => panic!("unbounded ranges are not allowed"),
676 };
677 let end = match r.end_bound() {
678 Bound::Included(s) => *s,
679 Bound::Excluded(s) => *s - S::one(),
680 Bound::Unbounded => panic!("unbounded ranges are not allowed"),
681 };
682 assert!(start <= end);
683 start..=end
684}
685
686pub fn bb2d<S, RX, RY>(rx: RX, ry: RY) -> BBox2d<S>
688where
689 S: Integer,
690 RX: RangeBounds<S>,
691 RY: RangeBounds<S>,
692{
693 let rx = to_range_inclusive(rx);
694 let ry = to_range_inclusive(ry);
695 let min = p2d(*rx.start(), *ry.start());
696 let max = p2d(*rx.end(), *ry.end());
697 BBox { min, max }
698}
699pub fn bb3d<S, RX, RY, RZ>(rx: RX, ry: RY, rz: RZ) -> BBox3d<S>
701where
702 S: Integer,
703 RX: RangeBounds<S>,
704 RY: RangeBounds<S>,
705 RZ: RangeBounds<S>,
706{
707 let rx = to_range_inclusive(rx);
708 let ry = to_range_inclusive(ry);
709 let rz = to_range_inclusive(rz);
710 let min = p3d(*rx.start(), *ry.start(), *rz.start());
711 let max = p3d(*rx.end(), *ry.end(), *rz.end());
712 BBox { min, max }
713}
714pub fn bb4d<S, RX, RY, RZ, RW>(rx: RX, ry: RY, rz: RZ, rw: RW) -> BBox4d<S>
716where
717 S: Integer,
718 RX: RangeBounds<S>,
719 RY: RangeBounds<S>,
720 RZ: RangeBounds<S>,
721 RW: RangeBounds<S>,
722{
723 let rx = to_range_inclusive(rx);
724 let ry = to_range_inclusive(ry);
725 let rz = to_range_inclusive(rz);
726 let rw = to_range_inclusive(rw);
727 let min = p4d(*rx.start(), *ry.start(), *rz.start(), *rw.start());
728 let max = p4d(*rx.end(), *ry.end(), *rz.end(), *rw.end());
729 BBox { min, max }
730}
731
732impl<S, V> From<Point<S, V>> for BBox<S, V>
733where
734 S: Integer,
735 V: Vector<S>,
736{
737 fn from(p: Point<S, V>) -> BBox<S, V> {
739 BBox { min: p, max: p }
740 }
741}
742
743impl<S> IntoIterator for BBox<S, Vec2d<S>>
744where
745 S: Integer,
746 usize: TryFrom<S>,
747 <usize as TryFrom<S>>::Error: fmt::Debug,
748{
749 type Item = Point2d<S>;
750
751 type IntoIter = Points<S, Vec2d<S>, Layout2d<S>>;
752
753 fn into_iter(self) -> Self::IntoIter {
754 Layout2d::new(self).into_points()
755 }
756}
757impl<'a, S> IntoIterator for &'a BBox<S, Vec2d<S>>
758where
759 S: Integer,
760 usize: TryFrom<S>,
761 <usize as TryFrom<S>>::Error: fmt::Debug,
762{
763 type Item = Point2d<S>;
764
765 type IntoIter = Points<S, Vec2d<S>, Layout2d<S>>;
766
767 fn into_iter(self) -> Self::IntoIter {
768 Layout2d::new(*self).into_points()
769 }
770}
771
772impl<S> IntoIterator for BBox<S, Vec3d<S>>
773where
774 S: Integer,
775 usize: TryFrom<S>,
776 <usize as TryFrom<S>>::Error: fmt::Debug,
777{
778 type Item = Point3d<S>;
779
780 type IntoIter = Points<S, Vec3d<S>, Layout3d<S>>;
781
782 fn into_iter(self) -> Self::IntoIter {
783 Layout3d::new(self).into_points()
784 }
785}
786impl<'a, S> IntoIterator for &'a BBox<S, Vec3d<S>>
787where
788 S: Integer,
789 usize: TryFrom<S>,
790 <usize as TryFrom<S>>::Error: fmt::Debug,
791{
792 type Item = Point3d<S>;
793
794 type IntoIter = Points<S, Vec3d<S>, Layout3d<S>>;
795
796 fn into_iter(self) -> Self::IntoIter {
797 Layout3d::new(*self).into_points()
798 }
799}
800
801impl<S> IntoIterator for BBox<S, Vec4d<S>>
802where
803 S: Integer,
804 usize: TryFrom<S>,
805 <usize as TryFrom<S>>::Error: fmt::Debug,
806{
807 type Item = Point4d<S>;
808
809 type IntoIter = Points<S, Vec4d<S>, Layout4d<S>>;
810
811 fn into_iter(self) -> Self::IntoIter {
812 Layout4d::new(self).into_points()
813 }
814}
815impl<'a, S> IntoIterator for &'a BBox<S, Vec4d<S>>
816where
817 S: Integer,
818 usize: TryFrom<S>,
819 <usize as TryFrom<S>>::Error: fmt::Debug,
820{
821 type Item = Point4d<S>;
822
823 type IntoIter = Points<S, Vec4d<S>, Layout4d<S>>;
824
825 fn into_iter(self) -> Self::IntoIter {
826 Layout4d::new(*self).into_points()
827 }
828}
829
830impl<S, V> Add<V> for BBox<S, V>
831where
832 S: Integer,
833 V: Vector<S>,
834{
835 type Output = BBox<S, V>;
836
837 fn add(self, v: V) -> BBox<S, V> {
838 BBox::new(self.min() + v, self.lengths())
839 }
840}
841impl<'a, S, V> Add<&'a V> for BBox<S, V>
842where
843 S: Integer,
844 V: Vector<S>,
845{
846 type Output = BBox<S, V>;
847
848 fn add(self, v: &'a V) -> BBox<S, V> {
849 BBox::new(self.min() + v, self.lengths())
850 }
851}
852impl<'a, S, V> Add<V> for &'a BBox<S, V>
853where
854 S: Integer,
855 V: Vector<S>,
856{
857 type Output = BBox<S, V>;
858
859 fn add(self, v: V) -> BBox<S, V> {
860 BBox::new(self.min() + v, self.lengths())
861 }
862}
863impl<'a, S, V> Add<&'a V> for &'a BBox<S, V>
864where
865 S: Integer,
866 V: Vector<S>,
867{
868 type Output = BBox<S, V>;
869
870 fn add(self, v: &'a V) -> BBox<S, V> {
871 BBox::new(self.min() + v, self.lengths())
872 }
873}
874impl<S, V> Sub<V> for BBox<S, V>
875where
876 S: Integer,
877 V: Vector<S>,
878{
879 type Output = BBox<S, V>;
880
881 fn sub(self, v: V) -> BBox<S, V> {
882 BBox::new(self.min() - v, self.lengths())
883 }
884}
885impl<'a, S, V> Sub<&'a V> for BBox<S, V>
886where
887 S: Integer,
888 V: Vector<S>,
889{
890 type Output = BBox<S, V>;
891
892 fn sub(self, v: &'a V) -> BBox<S, V> {
893 BBox::new(self.min() - v, self.lengths())
894 }
895}
896impl<'a, S, V> Sub<V> for &'a BBox<S, V>
897where
898 S: Integer,
899 V: Vector<S>,
900{
901 type Output = BBox<S, V>;
902
903 fn sub(self, v: V) -> BBox<S, V> {
904 BBox::new(self.min() - v, self.lengths())
905 }
906}
907impl<'a, S, V> Sub<&'a V> for &'a BBox<S, V>
908where
909 S: Integer,
910 V: Vector<S>,
911{
912 type Output = BBox<S, V>;
913
914 fn sub(self, v: &'a V) -> BBox<S, V> {
915 BBox::new(self.min() - v, self.lengths())
916 }
917}
918
919impl<S, V> AddAssign<V> for BBox<S, V>
920where
921 S: Integer,
922 V: Vector<S>,
923{
924 fn add_assign(&mut self, other: V) {
925 self.min += other;
926 self.max += other;
927 }
928}
929impl<'a, S, V> AddAssign<&'a V> for BBox<S, V>
930where
931 S: Integer,
932 V: Vector<S>,
933{
934 fn add_assign(&mut self, other: &'a V) {
935 self.min += other;
936 self.max += other;
937 }
938}
939
940impl<S, V> SubAssign<V> for BBox<S, V>
941where
942 S: Integer,
943 V: Vector<S>,
944{
945 fn sub_assign(&mut self, other: V) {
946 self.min -= other;
947 self.max -= other;
948 }
949}
950impl<'a, S, V> SubAssign<&'a V> for BBox<S, V>
951where
952 S: Integer,
953 V: Vector<S>,
954{
955 fn sub_assign(&mut self, other: &'a V) {
956 self.min -= other;
957 self.max -= other;
958 }
959}
960
961#[cfg(test)]
962mod tests {
963 use core::ops::Bound::Excluded;
964
965 use crate::bb2d;
966 use crate::bb3d;
967 use crate::bb4d;
968 use crate::p2d;
969 use crate::p3d;
970 use crate::p4d;
971 use crate::v2d;
972 use crate::v3d;
973 use crate::v4d;
974 use crate::BBox2d;
975
976 #[cfg(feature = "random")]
977 use rand::rngs::StdRng;
978 #[cfg(feature = "random")]
979 use rand::SeedableRng;
980
981 #[test]
982 fn test_new() {
983 let bb = BBox2d::new(p2d(-2, 3), v2d(1, 2));
984 assert_eq!(bb2d(-2..-1, 3..5), bb);
985 }
986
987 #[test]
988 #[allow(deprecated)]
989 fn test_from_point() {
990 let bb = BBox2d::from_point(p2d(-2, 3));
991 assert_eq!(bb2d(-2..=-2, 3..=3), bb);
992 }
993
994 #[test]
995 #[allow(deprecated)]
996 fn test_from_points() {
997 let bb = BBox2d::from_points(p2d(-2, 3), p2d(4, 7));
998 assert_eq!(bb2d(-2..=4, 3..=7), bb);
999 }
1000
1001 #[test]
1002 fn test_from_corners() {
1003 let bb = BBox2d::from_corners(p2d(-2, 3), p2d(4, 7));
1004 assert_eq!(bb2d(-2..=4, 3..=7), bb);
1005 }
1006
1007 #[test]
1008 fn test_enclosing() {
1009 let bb = BBox2d::enclosing(&vec![p2d(-2, 3), p2d(4, 7)]);
1010 assert_eq!(Some(bb2d(-2..=4, 3..=7)), bb);
1011 }
1012 #[test]
1013 fn test_enclosing_empty() {
1014 let bb = <BBox2d<i64>>::enclosing(&vec![]);
1015 assert_eq!(None, bb);
1016 }
1017
1018 #[test]
1019 fn test_min_2d() {
1020 let bb = bb2d(-2..=2, -1..=1);
1021 assert_eq!(p2d(-2, -1), bb.min());
1022 }
1023 #[test]
1024 fn test_min_3d() {
1025 let bb = bb3d(-2..=2, -1..=1, 1..=3);
1026 assert_eq!(p3d(-2, -1, 1), bb.min());
1027 }
1028 #[test]
1029 fn test_min_4d() {
1030 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1031 assert_eq!(p4d(-2, -1, 1, -5), bb.min());
1032 }
1033
1034 #[test]
1035 fn test_max_2d() {
1036 let bb = bb2d(-2..=2, -1..=1);
1037 assert_eq!(p2d(2, 1), bb.max());
1038 }
1039 #[test]
1040 fn test_max_3d() {
1041 let bb = bb3d(-2..=2, -1..=1, 1..=3);
1042 assert_eq!(p3d(2, 1, 3), bb.max());
1043 }
1044 #[test]
1045 fn test_max_4d() {
1046 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1047 assert_eq!(p4d(2, 1, 3, -3), bb.max());
1048 }
1049
1050 #[test]
1051 fn test_lengths_2d() {
1052 let bb = bb2d(-2..3, -1..2);
1053 assert_eq!(v2d(5, 3), bb.lengths());
1054 }
1055 #[test]
1056 fn test_lengths_3d() {
1057 let bb = bb3d(-2..3, -1..2, 1..4);
1058 assert_eq!(v3d(5, 3, 3), bb.lengths());
1059 }
1060 #[test]
1061 fn test_lengths_4d() {
1062 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1063 assert_eq!(v4d(5, 3, 3, 3), bb.lengths());
1064 }
1065
1066 #[test]
1067 fn test_volume_2d() {
1068 let bb = bb2d(-2..3, -1..2);
1069 assert_eq!(15, bb.volume());
1070 }
1071 #[test]
1072 fn test_volume_3d() {
1073 let bb = bb3d(-2..3, -1..2, 1..4);
1074 assert_eq!(45, bb.volume());
1075 }
1076 #[test]
1077 fn test_volume_4d() {
1078 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1079 assert_eq!(135, bb.volume());
1080 }
1081
1082 #[test]
1083 fn test_lub() {
1084 let bb0 = bb2d(-2..3, -1..2);
1085 let bb1 = bb2d(-5..4, 2..5);
1086 assert_eq!(bb2d(-5..4, -1..5), bb0.lub(&bb1));
1087 }
1088
1089 #[test]
1090 fn test_intersection_nonempty() {
1091 let bb0 = bb2d(-2..=3, -1..=2);
1092 let bb1 = bb2d(-5..=4, 0..=5);
1093 assert_eq!(Some(bb2d(-2..=3, 0..=2)), bb0.intersection(&bb1));
1094 }
1095 #[test]
1096 fn test_intersection_empty() {
1097 let bb0 = bb2d(-2..3, -1..2);
1098 let bb1 = bb2d(-5..4, 2..5);
1099 assert_eq!(None, bb0.intersection(&bb1));
1100 }
1101
1102 #[test]
1103 fn test_extend_to() {
1104 let mut bb = bb2d(-2..3, -1..2);
1105 let p = p2d(3, 4);
1106 bb.extend_to(p);
1107 assert_eq!(bb2d(-2..4, -1..5), bb);
1108 }
1109
1110 #[test]
1111 fn test_extended_to() {
1112 let bb = bb2d(-2..3, -1..2);
1113 let p = p2d(3, 4);
1114 assert_eq!(bb2d(-2..4, -1..5), bb.extended_to(p));
1115 }
1116
1117 #[test]
1118 fn test_x_start_2d() {
1119 let bb = bb2d(-2..3, -1..2);
1120 assert_eq!(-2, bb.x_start());
1121 }
1122 #[test]
1123 fn test_x_start_3d() {
1124 let bb = bb3d(-2..3, -1..2, 1..4);
1125 assert_eq!(-2, bb.x_start());
1126 }
1127 #[test]
1128 fn test_x_start_4d() {
1129 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1130 assert_eq!(-2, bb.x_start());
1131 }
1132
1133 #[test]
1134 fn test_x_end_2d() {
1135 let bb = bb2d(-2..3, -1..2);
1136 assert_eq!(3, bb.x_end());
1137 }
1138 #[test]
1139 fn test_x_end_3d() {
1140 let bb = bb3d(-2..3, -1..2, 1..4);
1141 assert_eq!(3, bb.x_end());
1142 }
1143 #[test]
1144 fn test_x_end_4d() {
1145 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1146 assert_eq!(3, bb.x_end());
1147 }
1148
1149 #[test]
1150 fn test_x_min_2d() {
1151 let bb = bb2d(-2..=2, -1..=1);
1152 assert_eq!(-2, bb.x_min());
1153 }
1154 #[test]
1155 fn test_x_min_3d() {
1156 let bb = bb3d(-2..=2, -1..=1, 1..=3);
1157 assert_eq!(-2, bb.x_min());
1158 }
1159 #[test]
1160 fn test_x_min_4d() {
1161 let bb = bb4d(-2..=2, -1..=1, 1..=3, -5..=-3);
1162 assert_eq!(-2, bb.x_min());
1163 }
1164
1165 #[test]
1166 fn test_x_max_2d() {
1167 let bb = bb2d(-2..=2, -1..=1);
1168 assert_eq!(2, bb.x_max());
1169 }
1170 #[test]
1171 fn test_x_max_3d() {
1172 let bb = bb3d(-2..=2, -1..=1, 1..=3);
1173 assert_eq!(2, bb.x_max());
1174 }
1175 #[test]
1176 fn test_x_max_4d() {
1177 let bb = bb4d(-2..=2, -1..=1, 1..=3, -5..=-3);
1178 assert_eq!(2, bb.x_max());
1179 }
1180
1181 #[test]
1182 fn test_y_start_2d() {
1183 let bb = bb2d(-2..3, -1..2);
1184 assert_eq!(-1, bb.y_start());
1185 }
1186 #[test]
1187 fn test_y_start_3d() {
1188 let bb = bb3d(-2..3, -1..2, 1..4);
1189 assert_eq!(-1, bb.y_start());
1190 }
1191 #[test]
1192 fn test_y_start_4d() {
1193 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1194 assert_eq!(-1, bb.y_start());
1195 }
1196
1197 #[test]
1198 fn test_y_end_2d() {
1199 let bb = bb2d(-2..3, -1..2);
1200 assert_eq!(2, bb.y_end());
1201 }
1202 #[test]
1203 fn test_y_end_3d() {
1204 let bb = bb3d(-2..3, -1..2, 1..4);
1205 assert_eq!(2, bb.y_end());
1206 }
1207 #[test]
1208 fn test_y_end_4d() {
1209 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1210 assert_eq!(2, bb.y_end());
1211 }
1212
1213 #[test]
1214 fn test_y_min_2d() {
1215 let bb = bb2d(-2..=2, -1..=1);
1216 assert_eq!(-1, bb.y_min());
1217 }
1218 #[test]
1219 fn test_y_min_3d() {
1220 let bb = bb3d(-2..=2, -1..=1, 1..=3);
1221 assert_eq!(-1, bb.y_min());
1222 }
1223 #[test]
1224 fn test_y_min_4d() {
1225 let bb = bb4d(-2..=2, -1..=1, 1..=3, -5..=-3);
1226 assert_eq!(-1, bb.y_min());
1227 }
1228
1229 #[test]
1230 fn test_y_max_2d() {
1231 let bb = bb2d(-2..=2, -1..=1);
1232 assert_eq!(1, bb.y_max());
1233 }
1234 #[test]
1235 fn test_y_max_3d() {
1236 let bb = bb3d(-2..=2, -1..=1, 1..=3);
1237 assert_eq!(1, bb.y_max());
1238 }
1239 #[test]
1240 fn test_y_max_4d() {
1241 let bb = bb4d(-2..=2, -1..=1, 1..=3, -5..=-3);
1242 assert_eq!(1, bb.y_max());
1243 }
1244
1245 #[test]
1246 fn test_z_start_3d() {
1247 let bb = bb3d(-2..3, -1..2, 1..4);
1248 assert_eq!(1, bb.z_start());
1249 }
1250 #[test]
1251 fn test_z_start_4d() {
1252 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1253 assert_eq!(1, bb.z_start());
1254 }
1255
1256 #[test]
1257 fn test_z_end_3d() {
1258 let bb = bb3d(-2..3, -1..2, 1..4);
1259 assert_eq!(4, bb.z_end());
1260 }
1261 #[test]
1262 fn test_z_end_4d() {
1263 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1264 assert_eq!(4, bb.z_end());
1265 }
1266
1267 #[test]
1268 fn test_z_min_3d() {
1269 let bb = bb3d(-2..=2, -1..=1, 1..=3);
1270 assert_eq!(1, bb.z_min());
1271 }
1272 #[test]
1273 fn test_z_min_4d() {
1274 let bb = bb4d(-2..=2, -1..=1, 1..=3, -5..=-3);
1275 assert_eq!(1, bb.z_min());
1276 }
1277
1278 #[test]
1279 fn test_z_max_3d() {
1280 let bb = bb3d(-2..=2, -1..=1, 1..=3);
1281 assert_eq!(3, bb.z_max());
1282 }
1283 #[test]
1284 fn test_z_max_4d() {
1285 let bb = bb4d(-2..=2, -1..=1, 1..=3, -5..=-3);
1286 assert_eq!(3, bb.z_max());
1287 }
1288
1289 #[test]
1290 fn test_w_start_4d() {
1291 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1292 assert_eq!(-5, bb.w_start());
1293 }
1294
1295 #[test]
1296 fn test_w_end_4d() {
1297 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1298 assert_eq!(-2, bb.w_end());
1299 }
1300
1301 #[test]
1302 fn test_w_min_4d() {
1303 let bb = bb4d(-2..=2, -1..=1, 1..=3, -5..=-3);
1304 assert_eq!(-5, bb.w_min());
1305 }
1306
1307 #[test]
1308 fn test_w_max_4d() {
1309 let bb = bb4d(-2..=2, -1..=1, 1..=3, -5..=-3);
1310 assert_eq!(-3, bb.w_max());
1311 }
1312
1313 #[test]
1314 fn test_x_len_2d() {
1315 let bb = bb2d(-2..3, -1..2);
1316 assert_eq!(5, bb.x_len());
1317 }
1318 #[test]
1319 fn test_x_len_3d() {
1320 let bb = bb3d(-2..3, -1..2, 1..4);
1321 assert_eq!(5, bb.x_len());
1322 }
1323 #[test]
1324 fn test_x_len_4d() {
1325 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1326 assert_eq!(5, bb.x_len());
1327 }
1328
1329 #[test]
1330 fn test_y_len_2d() {
1331 let bb = bb2d(-2..3, -1..2);
1332 assert_eq!(3, bb.y_len());
1333 }
1334 #[test]
1335 fn test_y_len_3d() {
1336 let bb = bb3d(-2..3, -1..2, 1..4);
1337 assert_eq!(3, bb.y_len());
1338 }
1339 #[test]
1340 fn test_y_len_4d() {
1341 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1342 assert_eq!(3, bb.y_len());
1343 }
1344
1345 #[test]
1346 fn test_z_len_3d() {
1347 let bb = bb3d(-2..3, -1..2, 1..4);
1348 assert_eq!(3, bb.z_len());
1349 }
1350 #[test]
1351 fn test_z_len_4d() {
1352 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1353 assert_eq!(3, bb.z_len());
1354 }
1355
1356 #[test]
1357 fn test_w_len_4d() {
1358 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1359 assert_eq!(3, bb.w_len());
1360 }
1361
1362 #[test]
1363 fn test_area() {
1364 let bb = bb2d(-2..3, -1..2);
1365 assert_eq!(15, bb.area());
1366 }
1367
1368 #[test]
1369 fn test_contains() {
1370 let bb = bb2d(-2..3, -1..2);
1371 assert_eq!(bb.contains(&p2d(0, 0)), true);
1372 assert_eq!(bb.contains(&p2d(-2, 0)), true);
1373 assert_eq!(bb.contains(&p2d(-3, 0)), false);
1374 assert_eq!(bb.contains(&p2d(2, 0)), true);
1375 assert_eq!(bb.contains(&p2d(3, 0)), false);
1376 assert_eq!(bb.contains(&p2d(0, -1)), true);
1377 assert_eq!(bb.contains(&p2d(0, -2)), false);
1378 assert_eq!(bb.contains(&p2d(0, 1)), true);
1379 assert_eq!(bb.contains(&p2d(0, 2)), false);
1380 }
1381
1382 #[test]
1383 fn test_x_range_2d() {
1384 let bb = bb2d(-2..3, -1..2);
1385 assert_eq!(-2..3, bb.x_range());
1386 }
1387 #[test]
1388 fn test_x_range_3d() {
1389 let bb = bb3d(-2..3, -1..2, 1..4);
1390 assert_eq!(-2..3, bb.x_range());
1391 }
1392 #[test]
1393 fn test_x_range_4d() {
1394 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1395 assert_eq!(-2..3, bb.x_range());
1396 }
1397
1398 #[test]
1399 fn test_y_range_2d() {
1400 let bb = bb2d(-2..3, -1..2);
1401 assert_eq!(-1..2, bb.y_range());
1402 }
1403 #[test]
1404 fn test_y_range_3d() {
1405 let bb = bb3d(-2..3, -1..2, 1..4);
1406 assert_eq!(-1..2, bb.y_range());
1407 }
1408 #[test]
1409 fn test_y_range_4d() {
1410 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1411 assert_eq!(-1..2, bb.y_range());
1412 }
1413
1414 #[test]
1415 fn test_z_range_3d() {
1416 let bb = bb3d(-2..3, -1..2, 1..4);
1417 assert_eq!(1..4, bb.z_range());
1418 }
1419 #[test]
1420 fn test_z_range_4d() {
1421 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1422 assert_eq!(1..4, bb.z_range());
1423 }
1424
1425 #[test]
1426 fn test_w_range_4d() {
1427 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1428 assert_eq!(-5..-2, bb.w_range());
1429 }
1430
1431 #[test]
1432 fn test_center() {
1433 let bb = bb2d(-2..3, -1..2);
1434 assert_eq!(p2d(0, 0), bb.center());
1435 }
1436
1437 #[cfg(feature = "random")]
1438 #[test]
1439 fn test_random_point_2d() {
1440 let mut rng = StdRng::seed_from_u64(42);
1441 let bb = bb2d(-2..3, -1..2);
1442 assert_eq!(p2d(-1, 0), bb.random_point(&mut rng));
1443 }
1444 #[cfg(feature = "random")]
1445 #[test]
1446 fn test_random_point_3d() {
1447 let mut rng = StdRng::seed_from_u64(42);
1448 let bb = bb3d(-2..3, -1..2, 1..4);
1449 assert_eq!(p3d(-1, 0, 3), bb.random_point(&mut rng));
1450 }
1451 #[cfg(feature = "random")]
1452 #[test]
1453 fn test_random_point_4d() {
1454 let mut rng = StdRng::seed_from_u64(42);
1455 let bb = bb4d(-2..3, -1..2, 1..4, -5..-2);
1456 assert_eq!(p4d(-1, 0, 3, -4), bb.random_point(&mut rng));
1457 }
1458
1459 #[test]
1460 fn test_bb2d_incl() {
1461 let bb = bb2d(0..=2, 1..=4);
1462 assert_eq!(bb2d(0..3, 1..5), bb)
1463 }
1464 #[test]
1465 fn test_bb2d_excl() {
1466 let bb = bb2d((Excluded(-1), Excluded(3)), (Excluded(0), Excluded(5)));
1467 assert_eq!(bb2d(0..3, 1..5), bb)
1468 }
1469 #[test]
1470 fn test_bb3d_incl() {
1471 let bb = bb3d(0..=2, 1..=4, 2..=6);
1472 assert_eq!(bb3d(0..3, 1..5, 2..7), bb)
1473 }
1474 #[test]
1475 fn test_bb3d_excl() {
1476 let bb = bb3d(
1477 (Excluded(-1), Excluded(3)),
1478 (Excluded(0), Excluded(5)),
1479 (Excluded(1), Excluded(7)),
1480 );
1481 assert_eq!(bb3d(0..3, 1..5, 2..7), bb)
1482 }
1483 #[test]
1484 fn test_bb4d_incl() {
1485 let bb = bb4d(0..=2, 1..=4, 2..=6, 3..=8);
1486 assert_eq!(bb4d(0..3, 1..5, 2..7, 3..9), bb)
1487 }
1488 #[test]
1489 fn test_bb4d_excl() {
1490 let bb = bb4d(
1491 (Excluded(-1), Excluded(3)),
1492 (Excluded(0), Excluded(5)),
1493 (Excluded(1), Excluded(7)),
1494 (Excluded(2), Excluded(9)),
1495 );
1496 assert_eq!(bb4d(0..3, 1..5, 2..7, 3..9), bb)
1497 }
1498
1499 #[test]
1500 fn test_from() {
1501 let bb = BBox2d::from(p2d(-2, 3));
1502 assert_eq!(bb2d(-2..=-2, 3..=3), bb);
1503 }
1504
1505 #[test]
1506 fn test_iter_2d() {
1507 let bb = bb2d(1..=2, -1..=0);
1508 let v = bb.iter().collect::<Vec<_>>();
1509 assert_eq!(vec![p2d(1, -1), p2d(2, -1), p2d(1, 0), p2d(2, 0)], v);
1510 }
1511 #[test]
1512 fn test_iter_3d() {
1513 let bb = bb3d(1..=2, -1..=0, -2..=-1);
1514 let v = bb.iter().collect::<Vec<_>>();
1515 assert_eq!(
1516 vec![
1517 p3d(1, -1, -2),
1518 p3d(2, -1, -2),
1519 p3d(1, 0, -2),
1520 p3d(2, 0, -2),
1521 p3d(1, -1, -1),
1522 p3d(2, -1, -1),
1523 p3d(1, 0, -1),
1524 p3d(2, 0, -1),
1525 ],
1526 v
1527 );
1528 }
1529 #[test]
1530 fn test_iter_4d() {
1531 let bb = bb4d(1..=2, -1..=0, -2..=-1, 3..=4);
1532 let v = bb.iter().collect::<Vec<_>>();
1533 assert_eq!(
1534 vec![
1535 p4d(1, -1, -2, 3),
1536 p4d(2, -1, -2, 3),
1537 p4d(1, 0, -2, 3),
1538 p4d(2, 0, -2, 3),
1539 p4d(1, -1, -1, 3),
1540 p4d(2, -1, -1, 3),
1541 p4d(1, 0, -1, 3),
1542 p4d(2, 0, -1, 3),
1543 p4d(1, -1, -2, 4),
1544 p4d(2, -1, -2, 4),
1545 p4d(1, 0, -2, 4),
1546 p4d(2, 0, -2, 4),
1547 p4d(1, -1, -1, 4),
1548 p4d(2, -1, -1, 4),
1549 p4d(1, 0, -1, 4),
1550 p4d(2, 0, -1, 4),
1551 ],
1552 v
1553 );
1554 }
1555
1556 #[test]
1557 fn test_exact_size_iterator_2d_owned() {
1558 let bb = bb2d(1..=2, -1..=0);
1559 let mut it = bb.into_iter();
1560 assert_eq!((4, Some(4)), it.size_hint());
1561 assert_eq!(4, it.len());
1562 let p = it.next();
1563 assert_eq!(Some(p2d(1, -1)), p);
1564 assert_eq!((3, Some(3)), it.size_hint());
1565 assert_eq!(3, it.len());
1566 }
1567 #[test]
1568 fn test_exact_size_iterator_2d_ref() {
1569 let bb = &bb2d(1..=2, -1..=0);
1570 let mut it = bb.into_iter();
1571 assert_eq!((4, Some(4)), it.size_hint());
1572 assert_eq!(4, it.len());
1573 let p = it.next();
1574 assert_eq!(Some(p2d(1, -1)), p);
1575 assert_eq!((3, Some(3)), it.size_hint());
1576 assert_eq!(3, it.len());
1577 }
1578 #[test]
1579 fn test_exact_size_iterator_3d_owned() {
1580 let bb = bb3d(1..=2, -1..=0, -2..=-1);
1581 let mut it = bb.into_iter();
1582 assert_eq!((8, Some(8)), it.size_hint());
1583 assert_eq!(8, it.len());
1584 let p = it.next();
1585 assert_eq!(Some(p3d(1, -1, -2)), p);
1586 assert_eq!((7, Some(7)), it.size_hint());
1587 assert_eq!(7, it.len());
1588 }
1589 #[test]
1590 fn test_exact_size_iterator_3d_ref() {
1591 let bb = &bb3d(1..=2, -1..=0, -2..=-1);
1592 let mut it = bb.into_iter();
1593 assert_eq!((8, Some(8)), it.size_hint());
1594 assert_eq!(8, it.len());
1595 let p = it.next();
1596 assert_eq!(Some(p3d(1, -1, -2)), p);
1597 assert_eq!((7, Some(7)), it.size_hint());
1598 assert_eq!(7, it.len());
1599 }
1600 #[test]
1601 fn test_exact_size_iterator_4d_owned() {
1602 let bb = bb4d(1..=2, -1..=0, -2..=-1, 3..=4);
1603 let mut it = bb.into_iter();
1604 assert_eq!((16, Some(16)), it.size_hint());
1605 assert_eq!(16, it.len());
1606 let p = it.next();
1607 assert_eq!(Some(p4d(1, -1, -2, 3)), p);
1608 assert_eq!((15, Some(15)), it.size_hint());
1609 assert_eq!(15, it.len());
1610 }
1611 #[test]
1612 fn test_exact_size_iterator_4d_ref() {
1613 let bb = &bb4d(1..=2, -1..=0, -2..=-1, 3..=4);
1614 let mut it = bb.into_iter();
1615 assert_eq!((16, Some(16)), it.size_hint());
1616 assert_eq!(16, it.len());
1617 let p = it.next();
1618 assert_eq!(Some(p4d(1, -1, -2, 3)), p);
1619 assert_eq!((15, Some(15)), it.size_hint());
1620 assert_eq!(15, it.len());
1621 }
1622
1623 #[test]
1624 fn test_add_2d() {
1625 let bb = bb2d(-2..3, -1..2);
1626 let v = v2d(3, 7);
1627 assert_eq!(bb2d(1..6, 6..9), bb + v);
1628 assert_eq!(bb2d(1..6, 6..9), bb + &v);
1629 assert_eq!(bb2d(1..6, 6..9), &bb + v);
1630 assert_eq!(bb2d(1..6, 6..9), &bb + &v);
1631 }
1632
1633 #[test]
1634 fn test_sub_2d() {
1635 let bb = bb2d(-2..3, -1..2);
1636 let v = v2d(-3, -7);
1637 assert_eq!(bb2d(1..6, 6..9), bb - v);
1638 assert_eq!(bb2d(1..6, 6..9), bb - &v);
1639 assert_eq!(bb2d(1..6, 6..9), &bb - v);
1640 assert_eq!(bb2d(1..6, 6..9), &bb - &v);
1641 }
1642
1643 #[test]
1644 fn test_add_assign_2d() {
1645 let mut bb = bb2d(-2..3, -1..2);
1646 let v = v2d(3, 7);
1647 bb += v;
1648 assert_eq!(bb2d(1..6, 6..9), bb);
1649 bb += &v;
1650 assert_eq!(bb2d(4..9, 13..16), bb);
1651 }
1652
1653 #[test]
1654 fn test_sub_assign_2d() {
1655 let mut bb = bb2d(-2..3, -1..2);
1656 let v = v2d(-3, -7);
1657 bb -= v;
1658 assert_eq!(bb2d(1..6, 6..9), bb);
1659 bb -= &v;
1660 assert_eq!(bb2d(4..9, 13..16), bb);
1661 }
1662}