gmath3D 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/triangle.rb CHANGED
@@ -1,281 +1,281 @@
1
- require 'gmath3D'
2
-
3
- module GMath3D
4
- #
5
- # Triangle represents a three edged finite plane on 3D space.
6
- #
7
- class Triangle < Geom
8
- public
9
- attr_accessor :vertices
10
-
11
- include BoxAvailable
12
-
13
- # [Input]
14
- # _vertex1_, _vertex2_, _vertex3_ should be Vector3.
15
- # [Output]
16
- # return new instance of Triangle.
17
- def initialize(vertex1 = Vector3.new(), vertex2 = Vector3.new(1,0,0), vertex3 = Vector3.new(0,1,0))
18
- Util3D.check_arg_type(::Vector3, vertex1)
19
- Util3D.check_arg_type(::Vector3, vertex2)
20
- Util3D.check_arg_type(::Vector3, vertex3)
21
- super()
22
- @vertices = Array.new([vertex1, vertex2, vertex3])
23
- end
24
-
25
- def initialize_copy( original_obj )
26
- @vertices = Array.new(original_obj.vertices.size)
27
- for i in 0..@vertices.size-1
28
- @vertices[i] = original_obj.vertices[i].dup
29
- end
30
- end
31
-
32
- # [Input]
33
- # _rhs_ is Line.
34
- # [Output]
35
- # return true if rhs equals myself.
36
- def ==(rhs)
37
- return false if rhs == nil
38
- return false if( !rhs.kind_of?(Triangle) )
39
- return false if(@vertices.size != rhs.vertices.size)
40
- for i in 0..@vertices.size-1
41
- return false if(@vertices[i] != rhs.vertices[i])
42
- end
43
- return true
44
- end
45
-
46
- def to_s
47
- "Triangle[#{@vertices[0].to_element_s}, #{@vertices[1].to_element_s}, #{@vertices[2].to_element_s}]"
48
- end
49
-
50
- # [Input]
51
- # _parameter_ should be three element Array of Numeric.
52
- # [Output]
53
- # return point on triangle at parameter position as Vector3.
54
- def point( parameter )
55
- Util3D.check_arg_type(::Array, parameter )
56
- # TODO Argument check
57
- return self.vertices[0]*parameter[0] + self.vertices[1]*parameter[1] + self.vertices[2]*parameter[2]
58
- end
59
-
60
- # [Output]
61
- # return edges as three element Array of Vector3.
62
- def edges
63
- return_edges = Array.new(3)
64
- return_edges[0] = FiniteLine.new(self.vertices[0], self.vertices[1])
65
- return_edges[1] = FiniteLine.new(self.vertices[1], self.vertices[2])
66
- return_edges[2] = FiniteLine.new(self.vertices[2], self.vertices[0])
67
- return return_edges
68
- end
69
-
70
- # [Output]
71
- # return area as Numeric.
72
- def area
73
- vec1 = vertices[1] - vertices[0]
74
- vec2 = vertices[2] - vertices[0]
75
- outer_product = vec1.cross(vec2)
76
- return outer_product.length / 2.0
77
- end
78
-
79
- # [Output]
80
- # return center point as Vector3.
81
- def center
82
- return vertices.avg
83
- end
84
-
85
- # [Output]
86
- # return normal vector as Vector3.
87
- def normal
88
- vec1 = self.vertices[1] - self.vertices[0]
89
- vec2 = self.vertices[2] - self.vertices[0]
90
- return (vec1.cross(vec2).normalize)
91
- end
92
-
93
- # [Input]
94
- # _vertex_index_ should be 0..2.
95
- # [Output]
96
- # return angle as Numeric(radian).
97
- def angle( vertex_index )
98
- return nil if(vertex_index < 0 || vertex_index > 2)
99
- vert1 = self.vertices[vertex_index]
100
- vert2 = self.vertices[(vertex_index+1)%3]
101
- vert3 = self.vertices[(vertex_index+2)%3]
102
- vec1 = vert2 - vert1
103
- vec2 = vert3 - vert1
104
- vec1.angle(vec2)
105
- end
106
-
107
- # [Output]
108
- # return normal vector reversed triangle
109
- def reverse
110
- return Triangle.new(@vertices[0], @vertices[2], @vertices[1])
111
- end
112
-
113
- # [Input]
114
- # _check_point_ should be Vector3.
115
- # [Output]
116
- # return barycentric_coordinate on check_point as three element Array of Numeric.
117
- def barycentric_coordinate( check_point )
118
- Util3D.check_arg_type(::Vector3, check_point)
119
-
120
- v0 = @vertices[0]
121
- v1 = @vertices[1]
122
- v2 = @vertices[2]
123
-
124
- d1 = v1 - v0
125
- d2 = v2 - v1
126
- n = d1.cross(d2);
127
- if((n.x).abs >= (n.y).abs && (n.x).abs >= (n.z).abs)
128
- uu1 = v0.y - v2.y;
129
- uu2 = v1.y - v2.y;
130
- uu3 = check_point.y - v0.y;
131
- uu4 = check_point.y - v2.y;
132
- vv1 = v0.z - v2.z;
133
- vv2 = v1.z - v2.z;
134
- vv3 = check_point.z - v0.z;
135
- vv4 = check_point.z - v2.z;
136
- elsif((n.y).abs >= (n.z).abs)
137
- uu1 = v0.z - v2.z;
138
- uu2 = v1.z - v2.z;
139
- uu3 = check_point.z - v0.z;
140
- uu4 = check_point.z - v2.z;
141
- vv1 = v0.x - v2.x;
142
- vv2 = v1.x - v2.x;
143
- vv3 = check_point.x - v0.x;
144
- vv4 = check_point.x - v2.x;
145
- else
146
- uu1 = v0.x - v2.x;
147
- uu2 = v1.x - v2.x;
148
- uu3 = check_point.x - v0.x;
149
- uu4 = check_point.x - v2.x;
150
- vv1 = v0.y - v2.y;
151
- vv2 = v1.y - v2.y;
152
- vv3 = check_point.y - v0.y;
153
- vv4 = check_point.y - v2.y;
154
- end
155
-
156
- denom = vv1 * uu2 - vv2* uu1
157
- if(denom == 0.0)
158
- return nil
159
- end
160
- b = Array.new(3)
161
- oneOverDenom = 1.0 / denom ;
162
- b[0] = (vv4*uu2 - vv2*uu4) * oneOverDenom;
163
- b[1] = (vv1*uu3 - vv3*uu1) * oneOverDenom;
164
- b[2] = 1.0 - b[0] - b[1];
165
- return b;
166
- end
167
-
168
- # [Input]
169
- # _target_ shold be Vector3 or Line or Plane.
170
- # [Output]
171
- # [In case _target_ is Vector3]
172
- # return "distance, point on triangle" as [Numeric, Vector3].
173
- # [In case _target_ is Line]
174
- # return "distance, point on tirangle, point on line, parameter on line" as [Numeric, Vector3, Vector3, Numeric].
175
- # [In case _target_ is Plane]
176
- # return "distance, intersect_line(or closet edge), point_on_triangle, point_on_plane" as [Numeric, Vector3, Vector3, Vector3].
177
- def distance(target)
178
- # with Point
179
- if(target.kind_of?(Vector3))
180
- return distance_to_point(target)
181
- elsif(target.kind_of?(Line))
182
- #with Line
183
- return distance_to_line(target)
184
- elsif(target.kind_of?(Plane))
185
- #with Plane
186
- return distance_to_plane(target)
187
- end
188
- Util3D.raise_argurment_error(target)
189
- end
190
-
191
- # [Input]
192
- # _check_point_ shold be Vector3.
193
- # [Output]
194
- # return true if triangle contains _check_point_.
195
- def contains?( check_point )
196
- Util3D.check_arg_type(Vector3, check_point )
197
- plane = Plane.new( vertices[0], self.normal)
198
- distance, projected_point = plane.distance(check_point)
199
- return false if( distance > self.tolerance )
200
- g_coord = self.barycentric_coordinate(check_point)
201
- g_coord.each do |item|
202
- return false if( item < 0 or 1 < item)
203
- end
204
- return true
205
- end
206
-
207
- private
208
- def distance_to_point(target_point)
209
- plane = Plane.new( vertices[0], self.normal)
210
- distance, projected_point = plane.distance(target_point)
211
- if( self.contains?(projected_point))
212
- return distance, projected_point
213
- end
214
- #check distance to FiniteLines
215
- finite_lines = self.edges
216
- return FiniteLine.ary_distanc_to_point(finite_lines, target_point)
217
- end
218
-
219
- def distance_to_line(target_line)
220
- plane = Plane.new( vertices[0], self.normal )
221
- distance, point_on_plane, parameter_on_line = plane.distance( target_line )
222
- if( point_on_plane == nil)
223
- # parallel case
224
- # check distance to FiniteLines
225
- finite_lines = self.edges
226
- distance, point_on_edge, point_on_target, param_on_finiteline, param_on_target =
227
- FiniteLine.ary_distance_to_line(finite_lines, target_line)
228
- return distance, nil, nil, nil
229
- end
230
- if( self.contains?(point_on_plane) )
231
- return distance, point_on_plane, point_on_plane, parameter_on_line
232
- end
233
- # check distance to FiniteLines
234
- finite_lines = self.edges
235
- distance, point_on_edge, point_on_target, param_on_finiteline, param_on_target =
236
- FiniteLine.ary_distance_to_line(finite_lines, target_line)
237
- return distance, point_on_edge, point_on_target, param_on_target
238
- end
239
-
240
- def distance_to_plane(target_plane)
241
- triangle_plane = Plane.new( vertices[0], self.normal )
242
- distance, intersect_line_each_plane = triangle_plane.distance( target_plane )
243
- if( intersect_line_each_plane == nil )
244
- return distance, nil, nil, nil
245
- end
246
-
247
- # check distance from intersection and each edge.
248
- distance_zero_count = 0
249
- distance_info = Array.new(0)
250
- prallel_edge_ary = Array.new(0)
251
- self.edges.each do |edge|
252
- distance, point_on_edge, point_on_line = edge.distance( intersect_line_each_plane)
253
- if point_on_edge != nil && point_on_line != nil
254
- distance_info.push([distance, point_on_edge, point_on_line])
255
- if distance <= self.tolerance
256
- distance_zero_count += 1
257
- end
258
- else
259
- prallel_edge_ary.push( edge )
260
- end
261
- end
262
- distance_info.sort!{|a,b| a[0] <=> b[0]}
263
- # distance, intersect_line(or closet edge), point_on_triangle, point_on_plan
264
- if (distance_zero_count == 2)
265
- point1 = distance_info[0][1]
266
- point2 = distance_info[1][1]
267
- if point1.distance(point2) > self.tolerance
268
- return 0.0, FiniteLine.new(point1, point2), nil, nil
269
- end
270
- return 0.0, nil, point1, point1
271
- elsif (distance_zero_count == 0)
272
- distance, closest_point_on_plane = target_plane.distance(distance_info[0][1])
273
- if(distance_info[0][1] != distance_info[1][1])
274
- return distance, FiniteLine.new(distance_info[0][1], distance_info[1][1]), nil, nil
275
- end
276
- return distance, nil, distance_info[0][1], closest_point_on_plane
277
- end
278
- return 0.0, nil, nil, nil
279
- end
280
- end
281
- end
1
+ require 'gmath3D'
2
+
3
+ module GMath3D
4
+ #
5
+ # Triangle represents a three edged finite plane on 3D space.
6
+ #
7
+ class Triangle < Geom
8
+ public
9
+ attr_accessor :vertices
10
+
11
+ include BoxAvailable
12
+
13
+ # [Input]
14
+ # _vertex1_, _vertex2_, _vertex3_ should be Vector3.
15
+ # [Output]
16
+ # return new instance of Triangle.
17
+ def initialize(vertex1 = Vector3.new(), vertex2 = Vector3.new(1,0,0), vertex3 = Vector3.new(0,1,0))
18
+ Util3D.check_arg_type(::Vector3, vertex1)
19
+ Util3D.check_arg_type(::Vector3, vertex2)
20
+ Util3D.check_arg_type(::Vector3, vertex3)
21
+ super()
22
+ @vertices = Array.new([vertex1, vertex2, vertex3])
23
+ end
24
+
25
+ def initialize_copy( original_obj )
26
+ @vertices = Array.new(original_obj.vertices.size)
27
+ for i in 0..@vertices.size-1
28
+ @vertices[i] = original_obj.vertices[i].dup
29
+ end
30
+ end
31
+
32
+ # [Input]
33
+ # _rhs_ is Line.
34
+ # [Output]
35
+ # return true if rhs equals myself.
36
+ def ==(rhs)
37
+ return false if rhs == nil
38
+ return false if( !rhs.kind_of?(Triangle) )
39
+ return false if(@vertices.size != rhs.vertices.size)
40
+ for i in 0..@vertices.size-1
41
+ return false if(@vertices[i] != rhs.vertices[i])
42
+ end
43
+ return true
44
+ end
45
+
46
+ def to_s
47
+ "Triangle[#{@vertices[0].to_element_s}, #{@vertices[1].to_element_s}, #{@vertices[2].to_element_s}]"
48
+ end
49
+
50
+ # [Input]
51
+ # _parameter_ should be three element Array of Numeric.
52
+ # [Output]
53
+ # return point on triangle at parameter position as Vector3.
54
+ def point( parameter )
55
+ Util3D.check_arg_type(::Array, parameter )
56
+ # TODO Argument check
57
+ return self.vertices[0]*parameter[0] + self.vertices[1]*parameter[1] + self.vertices[2]*parameter[2]
58
+ end
59
+
60
+ # [Output]
61
+ # return edges as three element Array of Vector3.
62
+ def edges
63
+ return_edges = Array.new(3)
64
+ return_edges[0] = FiniteLine.new(self.vertices[0], self.vertices[1])
65
+ return_edges[1] = FiniteLine.new(self.vertices[1], self.vertices[2])
66
+ return_edges[2] = FiniteLine.new(self.vertices[2], self.vertices[0])
67
+ return return_edges
68
+ end
69
+
70
+ # [Output]
71
+ # return area as Numeric.
72
+ def area
73
+ vec1 = vertices[1] - vertices[0]
74
+ vec2 = vertices[2] - vertices[0]
75
+ outer_product = vec1.cross(vec2)
76
+ return outer_product.length / 2.0
77
+ end
78
+
79
+ # [Output]
80
+ # return center point as Vector3.
81
+ def center
82
+ return vertices.avg
83
+ end
84
+
85
+ # [Output]
86
+ # return normal vector as Vector3.
87
+ def normal
88
+ vec1 = self.vertices[1] - self.vertices[0]
89
+ vec2 = self.vertices[2] - self.vertices[0]
90
+ return (vec1.cross(vec2).normalize)
91
+ end
92
+
93
+ # [Input]
94
+ # _vertex_index_ should be 0..2.
95
+ # [Output]
96
+ # return angle as Numeric(radian).
97
+ def angle( vertex_index )
98
+ return nil if(vertex_index < 0 || vertex_index > 2)
99
+ vert1 = self.vertices[vertex_index]
100
+ vert2 = self.vertices[(vertex_index+1)%3]
101
+ vert3 = self.vertices[(vertex_index+2)%3]
102
+ vec1 = vert2 - vert1
103
+ vec2 = vert3 - vert1
104
+ vec1.angle(vec2)
105
+ end
106
+
107
+ # [Output]
108
+ # return normal vector reversed triangle
109
+ def reverse
110
+ return Triangle.new(@vertices[0], @vertices[2], @vertices[1])
111
+ end
112
+
113
+ # [Input]
114
+ # _check_point_ should be Vector3.
115
+ # [Output]
116
+ # return barycentric_coordinate on check_point as three element Array of Numeric.
117
+ def barycentric_coordinate( check_point )
118
+ Util3D.check_arg_type(::Vector3, check_point)
119
+
120
+ v0 = @vertices[0]
121
+ v1 = @vertices[1]
122
+ v2 = @vertices[2]
123
+
124
+ d1 = v1 - v0
125
+ d2 = v2 - v1
126
+ n = d1.cross(d2);
127
+ if((n.x).abs >= (n.y).abs && (n.x).abs >= (n.z).abs)
128
+ uu1 = v0.y - v2.y;
129
+ uu2 = v1.y - v2.y;
130
+ uu3 = check_point.y - v0.y;
131
+ uu4 = check_point.y - v2.y;
132
+ vv1 = v0.z - v2.z;
133
+ vv2 = v1.z - v2.z;
134
+ vv3 = check_point.z - v0.z;
135
+ vv4 = check_point.z - v2.z;
136
+ elsif((n.y).abs >= (n.z).abs)
137
+ uu1 = v0.z - v2.z;
138
+ uu2 = v1.z - v2.z;
139
+ uu3 = check_point.z - v0.z;
140
+ uu4 = check_point.z - v2.z;
141
+ vv1 = v0.x - v2.x;
142
+ vv2 = v1.x - v2.x;
143
+ vv3 = check_point.x - v0.x;
144
+ vv4 = check_point.x - v2.x;
145
+ else
146
+ uu1 = v0.x - v2.x;
147
+ uu2 = v1.x - v2.x;
148
+ uu3 = check_point.x - v0.x;
149
+ uu4 = check_point.x - v2.x;
150
+ vv1 = v0.y - v2.y;
151
+ vv2 = v1.y - v2.y;
152
+ vv3 = check_point.y - v0.y;
153
+ vv4 = check_point.y - v2.y;
154
+ end
155
+
156
+ denom = vv1 * uu2 - vv2* uu1
157
+ if(denom == 0.0)
158
+ return nil
159
+ end
160
+ b = Array.new(3)
161
+ oneOverDenom = 1.0 / denom ;
162
+ b[0] = (vv4*uu2 - vv2*uu4) * oneOverDenom;
163
+ b[1] = (vv1*uu3 - vv3*uu1) * oneOverDenom;
164
+ b[2] = 1.0 - b[0] - b[1];
165
+ return b;
166
+ end
167
+
168
+ # [Input]
169
+ # _target_ shold be Vector3 or Line or Plane.
170
+ # [Output]
171
+ # [In case _target_ is Vector3]
172
+ # return "distance, point on triangle" as [Numeric, Vector3].
173
+ # [In case _target_ is Line]
174
+ # return "distance, point on tirangle, point on line, parameter on line" as [Numeric, Vector3, Vector3, Numeric].
175
+ # [In case _target_ is Plane]
176
+ # return "distance, intersect_line(or closet edge), point_on_triangle, point_on_plane" as [Numeric, Vector3, Vector3, Vector3].
177
+ def distance(target)
178
+ # with Point
179
+ if(target.kind_of?(Vector3))
180
+ return distance_to_point(target)
181
+ elsif(target.kind_of?(Line))
182
+ #with Line
183
+ return distance_to_line(target)
184
+ elsif(target.kind_of?(Plane))
185
+ #with Plane
186
+ return distance_to_plane(target)
187
+ end
188
+ Util3D.raise_argurment_error(target)
189
+ end
190
+
191
+ # [Input]
192
+ # _check_point_ shold be Vector3.
193
+ # [Output]
194
+ # return true if triangle contains _check_point_.
195
+ def contains?( check_point )
196
+ Util3D.check_arg_type(Vector3, check_point )
197
+ plane = Plane.new( vertices[0], self.normal)
198
+ distance, projected_point = plane.distance(check_point)
199
+ return false if( distance > self.tolerance )
200
+ g_coord = self.barycentric_coordinate(check_point)
201
+ g_coord.each do |item|
202
+ return false if( item < 0 or 1 < item)
203
+ end
204
+ return true
205
+ end
206
+
207
+ private
208
+ def distance_to_point(target_point)
209
+ plane = Plane.new( vertices[0], self.normal)
210
+ distance, projected_point = plane.distance(target_point)
211
+ if( self.contains?(projected_point))
212
+ return distance, projected_point
213
+ end
214
+ #check distance to FiniteLines
215
+ finite_lines = self.edges
216
+ return FiniteLine.ary_distanc_to_point(finite_lines, target_point)
217
+ end
218
+
219
+ def distance_to_line(target_line)
220
+ plane = Plane.new( vertices[0], self.normal )
221
+ distance, point_on_plane, parameter_on_line = plane.distance( target_line )
222
+ if( point_on_plane == nil)
223
+ # parallel case
224
+ # check distance to FiniteLines
225
+ finite_lines = self.edges
226
+ distance, point_on_edge, point_on_target, param_on_finiteline, param_on_target =
227
+ FiniteLine.ary_distance_to_line(finite_lines, target_line)
228
+ return distance, nil, nil, nil
229
+ end
230
+ if( self.contains?(point_on_plane) )
231
+ return distance, point_on_plane, point_on_plane, parameter_on_line
232
+ end
233
+ # check distance to FiniteLines
234
+ finite_lines = self.edges
235
+ distance, point_on_edge, point_on_target, param_on_finiteline, param_on_target =
236
+ FiniteLine.ary_distance_to_line(finite_lines, target_line)
237
+ return distance, point_on_edge, point_on_target, param_on_target
238
+ end
239
+
240
+ def distance_to_plane(target_plane)
241
+ triangle_plane = Plane.new( vertices[0], self.normal )
242
+ distance, intersect_line_each_plane = triangle_plane.distance( target_plane )
243
+ if( intersect_line_each_plane == nil )
244
+ return distance, nil, nil, nil
245
+ end
246
+
247
+ # check distance from intersection and each edge.
248
+ distance_zero_count = 0
249
+ distance_info = Array.new(0)
250
+ prallel_edge_ary = Array.new(0)
251
+ self.edges.each do |edge|
252
+ distance, point_on_edge, point_on_line = edge.distance( intersect_line_each_plane)
253
+ if point_on_edge != nil && point_on_line != nil
254
+ distance_info.push([distance, point_on_edge, point_on_line])
255
+ if distance <= self.tolerance
256
+ distance_zero_count += 1
257
+ end
258
+ else
259
+ prallel_edge_ary.push( edge )
260
+ end
261
+ end
262
+ distance_info.sort!{|a,b| a[0] <=> b[0]}
263
+ # distance, intersect_line(or closet edge), point_on_triangle, point_on_plan
264
+ if (distance_zero_count == 2)
265
+ point1 = distance_info[0][1]
266
+ point2 = distance_info[1][1]
267
+ if point1.distance(point2) > self.tolerance
268
+ return 0.0, FiniteLine.new(point1, point2), nil, nil
269
+ end
270
+ return 0.0, nil, point1, point1
271
+ elsif (distance_zero_count == 0)
272
+ distance, closest_point_on_plane = target_plane.distance(distance_info[0][1])
273
+ if(distance_info[0][1] != distance_info[1][1])
274
+ return distance, FiniteLine.new(distance_info[0][1], distance_info[1][1]), nil, nil
275
+ end
276
+ return distance, nil, distance_info[0][1], closest_point_on_plane
277
+ end
278
+ return 0.0, nil, nil, nil
279
+ end
280
+ end
281
+ end
data/lib/util.rb CHANGED
@@ -1,23 +1,36 @@
1
- module Util3D
2
- def self.check_arg_type(type, instance)
3
- unless(instance.kind_of?(type))
4
- raise(ArgumentError::new("type mismatch: #{instance.class} for #{type}"))
5
- end
6
- end
7
-
8
- def self.raise_argurment_error(instance)
9
- raise(ArgumentError::new("type mismatch: #{instance.class}"))
10
- end
11
- end
12
-
13
- module GMath3D
14
- # Including 'vertices' methodshould be implimented that gets geometry vertices as Array of Vector3.
15
- module BoxAvailable
16
- # [Output]
17
- # return axially aligned bounding box as Box.
18
- def box
19
- return Box.from_points( vertices )
20
- end
21
- end
22
- end
23
-
1
+ module Util3D
2
+ def self.check_arg_type(type, instance, nullable = false, array_check = false)
3
+ return if(nullable && instance.nil?)
4
+ if(array_check && instance.kind_of?(Array))
5
+ instance.each do |item|
6
+ check_arg_type(type, item, nullable, array_check)
7
+ end
8
+ else
9
+ unless(instance.kind_of?(type))
10
+ raise(ArgumentError::new("type mismatch: #{instance.class} for #{type}"))
11
+ end
12
+ end
13
+ end
14
+
15
+ def self.raise_argurment_error(instance)
16
+ raise(ArgumentError::new("type mismatch: #{instance.class}"))
17
+ end
18
+
19
+ def self.check_key_arg(arg, key)
20
+ if(!arg.include?(key))
21
+ raise(ArgumentError::new("args should be contains: #{key}"))
22
+ end
23
+ end
24
+ end
25
+
26
+ module GMath3D
27
+ # Including 'vertices' methodshould be implimented that gets geometry vertices as Array of Vector3.
28
+ module BoxAvailable
29
+ # [Output]
30
+ # return axially aligned bounding box as Box.
31
+ def box
32
+ return Box.from_points( vertices )
33
+ end
34
+ end
35
+ end
36
+