1use i_bound::IBound;
2use i_shape::{IShape, ShapeType};
3use i_vicinity::IVicinity;
4
5use bound::AxisAlignedBBox;
6use mat::Mat3x1;
7
8#[derive(Debug, Clone)]
9pub struct RecBox {
10 pub _ori: Mat3x1<f64>,
11 pub _size: f64,
12 pub _bound: AxisAlignedBBox,
13 pub _vicinity: f64,
14}
15
16impl RecBox {
17 pub fn init(origin: &[f64], size: f64) -> RecBox {
18 assert!(origin.len() == 3);
19 RecBox {
20 _ori: Mat3x1 {
21 _val: [origin[0], origin[1], origin[2]],
22 },
23 _size: size, _bound: AxisAlignedBBox::init(ShapeType::Box, &[&origin[0..3], &[size]].concat()),
25 _vicinity: 0.000001f64,
26 }
27 }
28}
29
30impl IShape for RecBox {
31 fn get_shape_data(&self) -> Vec<f64> {
32 vec![self._ori[0], self._ori[1], self._ori[2], self._size]
33 }
34 fn get_type(&self) -> ShapeType {
35 ShapeType::Box
36 }
37 fn get_bound(&self) -> &dyn IBound {
38 &self._bound
39 }
40 fn get_intersect(&self, other: &dyn IShape) -> (bool, Option<Mat3x1<f64>>) {
42 if !self.get_bound().intersect(other.get_bound()) {
43 return (false, None);
44 } else {
45 match other.get_type() {
46 ShapeType::Point => {
47 let other_shape_data = other.get_shape_data();
49 let b_off = Mat3x1 {
50 _val: [
51 other_shape_data[0],
52 other_shape_data[1],
53 other_shape_data[2],
54 ],
55 };
56 return (true, Some(b_off));
57 }
58 _ => {
59 unimplemented!();
60 }
61 }
62 }
63 }
64 fn get_support(&self, v: &Mat3x1<f64>) -> Option<Mat3x1<f64>> {
65 if v.magnitude() != Some(0f64) {
66 let points = [
68 Mat3x1 {
69 _val: [self._size, self._size, self._size],
70 },
71 Mat3x1 {
72 _val: [-self._size, self._size, self._size],
73 },
74 Mat3x1 {
75 _val: [self._size, -self._size, self._size],
76 },
77 Mat3x1 {
78 _val: [-self._size, -self._size, self._size],
79 },
80 Mat3x1 {
81 _val: [self._size, self._size, -self._size],
82 },
83 Mat3x1 {
84 _val: [-self._size, self._size, -self._size],
85 },
86 Mat3x1 {
87 _val: [self._size, -self._size, -self._size],
88 },
89 Mat3x1 {
90 _val: [-self._size, -self._size, -self._size],
91 },
92 ];
93
94 let furthest = points
95 .iter()
96 .map(|x| x.dot(v).unwrap())
97 .enumerate()
98 .max_by(|a, b| a.1.partial_cmp(&b.1).unwrap())
99 .unwrap();
100
101 let o = self
102 ._ori
103 .plus(&points[furthest.0])
104 .expect("support operation unsuccessful.");
105 Some(o)
106 } else {
107 None
108 }
109 }
110}
111
112impl IVicinity<f64> for RecBox {
113 fn set_vicinity(&mut self, epsilon: f64) {
114 self._vicinity = epsilon.abs();
115 }
116 fn within_vicinity(&self, a: f64, b: f64) -> bool {
117 if a + self._vicinity >= b && a - self._vicinity <= b {
118 true
119 } else {
120 false
121 }
122 }
123}