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/finite_line.rb CHANGED
@@ -1,244 +1,244 @@
1
- require 'gmath3D'
2
-
3
- module GMath3D
4
- #
5
- # FiniteLine represents a finite line on 3D space.
6
- #
7
- class FiniteLine < Geom
8
- public
9
- attr_accessor :start_point
10
- attr_accessor :end_point
11
-
12
- include BoxAvailable
13
-
14
- # [Input]
15
- # _start_point_ and _end_point_ should be Vector3.
16
- # [Output]
17
- # return new instance as FiniteLine
18
- def initialize(start_point = Vector3.new(0,0,0), end_point = Vector3.new(1,0,0))
19
- Util3D.check_arg_type(Vector3, start_point)
20
- Util3D.check_arg_type(Vector3, end_point)
21
- super()
22
- @start_point = start_point
23
- @end_point = end_point
24
- end
25
-
26
- def initialize_copy( original_obj )
27
- @start_point = original_obj.start_point.dup
28
- @end_point = original_obj.end_point.dup
29
- end
30
-
31
- def to_s
32
- "FiniteLine[from#{start_point.to_element_s}, to#{end_point.to_element_s}]"
33
- end
34
-
35
- # [Input]
36
- # _mat_ should be Matrix which row and col size are 3.
37
- # [Output]
38
- # return rotated FiniteLine.
39
- def rotate(mat)
40
- rot_start_point = mat*start_point
41
- rot_end_point = mat*end_point
42
- return FiniteLine.new(rot_start_point, rot_end_point)
43
- end
44
-
45
- # [Input]
46
- # _rhs_ should be FiniteLine.
47
- # [Output]
48
- # return true if rhs equals myself.
49
- def ==(rhs)
50
- return false if rhs == nil
51
- return false if !rhs.kind_of?(FiniteLine)
52
- return false if( self.start_point != rhs.start_point)
53
- return false if( self.end_point != rhs.end_point)
54
- return true
55
- end
56
-
57
- # [Output]
58
- # return Array of start_point and end_point.
59
- def vertices
60
- return [start_point, end_point]
61
- end
62
-
63
- # [Output]
64
- # return direction as vector from start_point to end_point as Vector3
65
- def direction
66
- @end_point - @start_point
67
- end
68
-
69
- # [Input]
70
- # _parameter_ should be Numeric.
71
- # [Output]
72
- # return a point on line at input parameter position as Vector3
73
- def point(parameter)
74
- if(parameter < 0.0 or 1.0 < parameter)
75
- return nil
76
- else
77
- return @start_point * (1.0 - parameter) + @end_point * parameter
78
- end
79
- end
80
-
81
- # [Output]
82
- # return length as Numeric
83
- def length
84
- @start_point.distance(@end_point)
85
- end
86
-
87
- # This function returns closest distance between FiniteLine and anothor element.
88
- # [Input]
89
- # _target_ should be Vector3 or Line or FiniteLine
90
- #
91
- # [Output]
92
- # [in case _target_ is Vector3]
93
- # return "distance, closest point on myself, parameter on myself" as [Numeric, Vector3, Numeric]
94
- # [in case _target_ is Line or FiniteLine]
95
- # return "distance, point on myself, point on target, parameter on myself, parameter on tatget"
96
- # as [Numeric, Vector3, Vector3, Numeric, Numeric]
97
- def distance(target)
98
- # with Point
99
- if(target.kind_of?(Vector3))
100
- return distance_to_point(target)
101
- #with Line
102
- elsif(target.kind_of?(Line))
103
- return distance_to_line(target)
104
- #widh Finite Line
105
- elsif(target.kind_of?(FiniteLine))
106
- return distance_to_finite_line(target)
107
- end
108
- Util3D.raise_argurment_error(target)
109
- end
110
-
111
- def self.ary_distanc_to_point(finite_lines, target_point)
112
- Util3D.check_arg_type(::Array, finite_lines)
113
- Util3D.check_arg_type(Vector3, target_point)
114
- distance_ary = Array.new(0)
115
- points_ary = Array.new(0)
116
- finite_lines.each do | item |
117
- distance, point = item.distance(target_point)
118
- distance_ary.push(distance);
119
- points_ary.push(point)
120
- end
121
- distance = distance_ary.min
122
- closest_point = points_ary[distance_ary.index(distance)]
123
- return distance, closest_point
124
- end
125
-
126
- def self.ary_distance_to_line(finite_lines, target_line)
127
- Util3D.check_arg_type(::Array, finite_lines)
128
- Util3D.check_arg_type(Line, target_line)
129
- distance_ary = Array.new(0)
130
- point_on_target_ary = Array.new(0)
131
- point_on_finite_line_ary = Array.new(0)
132
- param_on_target_ary = Array.new(0)
133
- param_on_finite_line_ary = Array.new(0)
134
- finite_lines.each do | item |
135
- distance, point_on_myself, point_on_target, parameter_on_myself, parameter_on_tatget = item.distance(target_line)
136
- distance_ary.push(distance)
137
- point_on_target_ary.push(point_on_target)
138
- point_on_finite_line_ary.push(point_on_myself)
139
- param_on_target_ary.push(parameter_on_tatget)
140
- param_on_finite_line_ary.push(parameter_on_myself)
141
- end
142
- distance = distance_ary.min
143
- point_on_finiteline = point_on_finite_line_ary[distance_ary.index(distance)]
144
- point_on_target = point_on_target_ary[distance_ary.index(distance)]
145
- param_on_finiteline = param_on_finite_line_ary[distance_ary.index(distance)]
146
- param_on_target = param_on_target_ary[distance_ary.index(distance)]
147
- return distance, point_on_finiteline, point_on_target, param_on_finiteline, param_on_target
148
- end
149
- private
150
- def distance_to_point(target)
151
- # get distance using infinite line
152
- infinite_line = Line.new(self.start_point, self.direction)
153
- distance, closest_point, parameter = infinite_line.distance(target)
154
- if(0.0 <= parameter and parameter <= 1.0)
155
- return distance, closest_point, parameter
156
- end
157
-
158
- distance_to_start_point = @start_point.distance(target)
159
- distance_to_end_point = @end_point.distance(target)
160
- if(distance_to_start_point < distance_to_end_point)
161
- distance = distance_to_start_point
162
- closest_point = @start_point
163
- parameter = 0.0
164
- else
165
- distance = distance_to_end_point
166
- closest_point = @end_point
167
- parameter = 1.0
168
- end
169
- return distance, closest_point, parameter
170
- end
171
-
172
- def distance_to_line(target_infinite_line)
173
- self_infinite_line = Line.new(self.start_point, self.direction)
174
- distance, point1, point2, parameter1, parameter2 = self_infinite_line.distance(target_infinite_line)
175
- #parallel
176
- return distance, nil, nil, nil, nil if( point1 == nil and point2 == nil)
177
- #parameter is in range
178
- return distance, point1, point2, parameter1, parameter2 if(0 < parameter1 and parameter1 < 1)
179
- distance_to_start_point, closest_point_to_start_point, parameter_to_start_point =
180
- target_infinite_line.distance(self.start_point)
181
- distance_to_end_point, closest_point_to_end_point, parameter_to_end_point =
182
- target_infinite_line.distance(self.end_point)
183
- if(distance_to_start_point < distance_to_end_point)
184
- return distance_to_start_point, self.start_point, closest_point_to_start_point, 0.0, parameter_to_start_point
185
- else
186
- return distance_to_end_point, self.end_point, closest_point_to_end_point, 1.0, parameter_to_end_point
187
- end
188
- end
189
-
190
- def distance_to_finite_line(target_finite_line)
191
- line1 = Line.new(self.start_point, self.direction)
192
- line2 = Line.new(target_finite_line.start_point, target_finite_line.direction)
193
- distance, point_myself, point_target, parameter_myself, parameter_target = line1.distance( line2 )
194
- if(point_myself == nil and point_target == nil)
195
- #prallel or including case
196
- point_pair = Array.new(4)
197
- point_pair[0] = Array.new([self.start_point, target_finite_line.start_point, 0, 0])
198
- point_pair[1] = Array.new([self.start_point, target_finite_line.end_point, 0,1])
199
- point_pair[2] = Array.new([self.end_point, target_finite_line.start_point, 1,0])
200
- point_pair[3] = Array.new([self.end_point, target_finite_line.end_point,1,1])
201
-
202
- distance_ary = Array.new(0)
203
- point_pair.each do |points|
204
- distance_ary << points[0].distance(points[1])
205
- end
206
- distance_min = distance_ary.min
207
- distance_min_ary = Array.new(0)
208
- distance_min_index = nil
209
- distance_ary.each do |item|
210
- if( item - tolerance < distance_min )
211
- distance_min_ary << item
212
- distance_min_index = distance_ary.index(item)
213
- end
214
- end
215
- if( distance_min_ary.size == 1)
216
- target_point_pair = point_pair[distance_min_index]
217
- distance = target_point_pair[0].distance(target_point_pair[1])
218
- return distance, target_point_pair[0], target_point_pair[1], target_point_pair[2], target_point_pair[3]
219
- else
220
- return distance, nil, nil, nil, nil
221
- end
222
- #out of range
223
- elsif( parameter_myself < 0 or 1 < parameter_myself or parameter_target < 0 or 1 < parameter_target )
224
- parameter_myself = [1, parameter_myself].min
225
- parameter_myself = [0, parameter_myself].max
226
- distance1, point_target, paramter_target_tmp = target_finite_line.distance(point_myself)
227
-
228
- parameter_target = [1, parameter_target].min
229
- parameter_target = [0, parameter_target].max
230
- distance2, point_myself, parameter_myself_tmp = self.distance(point_target)
231
- if(distance1 < distance2)
232
- parameter_target = paramter_target_tmp
233
- else
234
- parameter_myself = parameter_myself_tmp
235
- end
236
- end
237
- point_myself = line1.point(parameter_myself);
238
- point_target = line2.point(parameter_target);
239
- distance = point_myself.distance(point_target)
240
- return distance, point_myself, point_target, parameter_myself, parameter_target
241
- end
242
- end
243
- end
244
-
1
+ require 'gmath3D'
2
+
3
+ module GMath3D
4
+ #
5
+ # FiniteLine represents a finite line on 3D space.
6
+ #
7
+ class FiniteLine < Geom
8
+ public
9
+ attr_accessor :start_point
10
+ attr_accessor :end_point
11
+
12
+ include BoxAvailable
13
+
14
+ # [Input]
15
+ # _start_point_ and _end_point_ should be Vector3.
16
+ # [Output]
17
+ # return new instance as FiniteLine
18
+ def initialize(start_point = Vector3.new(0,0,0), end_point = Vector3.new(1,0,0))
19
+ Util3D.check_arg_type(Vector3, start_point)
20
+ Util3D.check_arg_type(Vector3, end_point)
21
+ super()
22
+ @start_point = start_point
23
+ @end_point = end_point
24
+ end
25
+
26
+ def initialize_copy( original_obj )
27
+ @start_point = original_obj.start_point.dup
28
+ @end_point = original_obj.end_point.dup
29
+ end
30
+
31
+ def to_s
32
+ "FiniteLine[from#{start_point.to_element_s}, to#{end_point.to_element_s}]"
33
+ end
34
+
35
+ # [Input]
36
+ # _mat_ should be Matrix which row and col size are 3.
37
+ # [Output]
38
+ # return rotated FiniteLine.
39
+ def rotate(mat)
40
+ rot_start_point = mat*start_point
41
+ rot_end_point = mat*end_point
42
+ return FiniteLine.new(rot_start_point, rot_end_point)
43
+ end
44
+
45
+ # [Input]
46
+ # _rhs_ should be FiniteLine.
47
+ # [Output]
48
+ # return true if rhs equals myself.
49
+ def ==(rhs)
50
+ return false if rhs == nil
51
+ return false if !rhs.kind_of?(FiniteLine)
52
+ return false if( self.start_point != rhs.start_point)
53
+ return false if( self.end_point != rhs.end_point)
54
+ return true
55
+ end
56
+
57
+ # [Output]
58
+ # return Array of start_point and end_point.
59
+ def vertices
60
+ return [start_point, end_point]
61
+ end
62
+
63
+ # [Output]
64
+ # return direction as vector from start_point to end_point as Vector3
65
+ def direction
66
+ @end_point - @start_point
67
+ end
68
+
69
+ # [Input]
70
+ # _parameter_ should be Numeric.
71
+ # [Output]
72
+ # return a point on line at input parameter position as Vector3
73
+ def point(parameter)
74
+ if(parameter < 0.0 or 1.0 < parameter)
75
+ return nil
76
+ else
77
+ return @start_point * (1.0 - parameter) + @end_point * parameter
78
+ end
79
+ end
80
+
81
+ # [Output]
82
+ # return length as Numeric
83
+ def length
84
+ @start_point.distance(@end_point)
85
+ end
86
+
87
+ # This function returns closest distance between FiniteLine and anothor element.
88
+ # [Input]
89
+ # _target_ should be Vector3 or Line or FiniteLine
90
+ #
91
+ # [Output]
92
+ # [in case _target_ is Vector3]
93
+ # return "distance, closest point on myself, parameter on myself" as [Numeric, Vector3, Numeric]
94
+ # [in case _target_ is Line or FiniteLine]
95
+ # return "distance, point on myself, point on target, parameter on myself, parameter on tatget"
96
+ # as [Numeric, Vector3, Vector3, Numeric, Numeric]
97
+ def distance(target)
98
+ # with Point
99
+ if(target.kind_of?(Vector3))
100
+ return distance_to_point(target)
101
+ #with Line
102
+ elsif(target.kind_of?(Line))
103
+ return distance_to_line(target)
104
+ #widh Finite Line
105
+ elsif(target.kind_of?(FiniteLine))
106
+ return distance_to_finite_line(target)
107
+ end
108
+ Util3D.raise_argurment_error(target)
109
+ end
110
+
111
+ def self.ary_distanc_to_point(finite_lines, target_point)
112
+ Util3D.check_arg_type(::Array, finite_lines)
113
+ Util3D.check_arg_type(Vector3, target_point)
114
+ distance_ary = Array.new(0)
115
+ points_ary = Array.new(0)
116
+ finite_lines.each do | item |
117
+ distance, point = item.distance(target_point)
118
+ distance_ary.push(distance);
119
+ points_ary.push(point)
120
+ end
121
+ distance = distance_ary.min
122
+ closest_point = points_ary[distance_ary.index(distance)]
123
+ return distance, closest_point
124
+ end
125
+
126
+ def self.ary_distance_to_line(finite_lines, target_line)
127
+ Util3D.check_arg_type(::Array, finite_lines)
128
+ Util3D.check_arg_type(Line, target_line)
129
+ distance_ary = Array.new(0)
130
+ point_on_target_ary = Array.new(0)
131
+ point_on_finite_line_ary = Array.new(0)
132
+ param_on_target_ary = Array.new(0)
133
+ param_on_finite_line_ary = Array.new(0)
134
+ finite_lines.each do | item |
135
+ distance, point_on_myself, point_on_target, parameter_on_myself, parameter_on_tatget = item.distance(target_line)
136
+ distance_ary.push(distance)
137
+ point_on_target_ary.push(point_on_target)
138
+ point_on_finite_line_ary.push(point_on_myself)
139
+ param_on_target_ary.push(parameter_on_tatget)
140
+ param_on_finite_line_ary.push(parameter_on_myself)
141
+ end
142
+ distance = distance_ary.min
143
+ point_on_finiteline = point_on_finite_line_ary[distance_ary.index(distance)]
144
+ point_on_target = point_on_target_ary[distance_ary.index(distance)]
145
+ param_on_finiteline = param_on_finite_line_ary[distance_ary.index(distance)]
146
+ param_on_target = param_on_target_ary[distance_ary.index(distance)]
147
+ return distance, point_on_finiteline, point_on_target, param_on_finiteline, param_on_target
148
+ end
149
+ private
150
+ def distance_to_point(target)
151
+ # get distance using infinite line
152
+ infinite_line = Line.new(self.start_point, self.direction)
153
+ distance, closest_point, parameter = infinite_line.distance(target)
154
+ if(0.0 <= parameter and parameter <= 1.0)
155
+ return distance, closest_point, parameter
156
+ end
157
+
158
+ distance_to_start_point = @start_point.distance(target)
159
+ distance_to_end_point = @end_point.distance(target)
160
+ if(distance_to_start_point < distance_to_end_point)
161
+ distance = distance_to_start_point
162
+ closest_point = @start_point
163
+ parameter = 0.0
164
+ else
165
+ distance = distance_to_end_point
166
+ closest_point = @end_point
167
+ parameter = 1.0
168
+ end
169
+ return distance, closest_point, parameter
170
+ end
171
+
172
+ def distance_to_line(target_infinite_line)
173
+ self_infinite_line = Line.new(self.start_point, self.direction)
174
+ distance, point1, point2, parameter1, parameter2 = self_infinite_line.distance(target_infinite_line)
175
+ #parallel
176
+ return distance, nil, nil, nil, nil if( point1 == nil and point2 == nil)
177
+ #parameter is in range
178
+ return distance, point1, point2, parameter1, parameter2 if(0 < parameter1 and parameter1 < 1)
179
+ distance_to_start_point, closest_point_to_start_point, parameter_to_start_point =
180
+ target_infinite_line.distance(self.start_point)
181
+ distance_to_end_point, closest_point_to_end_point, parameter_to_end_point =
182
+ target_infinite_line.distance(self.end_point)
183
+ if(distance_to_start_point < distance_to_end_point)
184
+ return distance_to_start_point, self.start_point, closest_point_to_start_point, 0.0, parameter_to_start_point
185
+ else
186
+ return distance_to_end_point, self.end_point, closest_point_to_end_point, 1.0, parameter_to_end_point
187
+ end
188
+ end
189
+
190
+ def distance_to_finite_line(target_finite_line)
191
+ line1 = Line.new(self.start_point, self.direction)
192
+ line2 = Line.new(target_finite_line.start_point, target_finite_line.direction)
193
+ distance, point_myself, point_target, parameter_myself, parameter_target = line1.distance( line2 )
194
+ if(point_myself == nil and point_target == nil)
195
+ #prallel or including case
196
+ point_pair = Array.new(4)
197
+ point_pair[0] = Array.new([self.start_point, target_finite_line.start_point, 0, 0])
198
+ point_pair[1] = Array.new([self.start_point, target_finite_line.end_point, 0,1])
199
+ point_pair[2] = Array.new([self.end_point, target_finite_line.start_point, 1,0])
200
+ point_pair[3] = Array.new([self.end_point, target_finite_line.end_point,1,1])
201
+
202
+ distance_ary = Array.new(0)
203
+ point_pair.each do |points|
204
+ distance_ary << points[0].distance(points[1])
205
+ end
206
+ distance_min = distance_ary.min
207
+ distance_min_ary = Array.new(0)
208
+ distance_min_index = nil
209
+ distance_ary.each do |item|
210
+ if( item - tolerance < distance_min )
211
+ distance_min_ary << item
212
+ distance_min_index = distance_ary.index(item)
213
+ end
214
+ end
215
+ if( distance_min_ary.size == 1)
216
+ target_point_pair = point_pair[distance_min_index]
217
+ distance = target_point_pair[0].distance(target_point_pair[1])
218
+ return distance, target_point_pair[0], target_point_pair[1], target_point_pair[2], target_point_pair[3]
219
+ else
220
+ return distance, nil, nil, nil, nil
221
+ end
222
+ #out of range
223
+ elsif( parameter_myself < 0 or 1 < parameter_myself or parameter_target < 0 or 1 < parameter_target )
224
+ parameter_myself = [1, parameter_myself].min
225
+ parameter_myself = [0, parameter_myself].max
226
+ distance1, point_target, paramter_target_tmp = target_finite_line.distance(point_myself)
227
+
228
+ parameter_target = [1, parameter_target].min
229
+ parameter_target = [0, parameter_target].max
230
+ distance2, point_myself, parameter_myself_tmp = self.distance(point_target)
231
+ if(distance1 < distance2)
232
+ parameter_target = paramter_target_tmp
233
+ else
234
+ parameter_myself = parameter_myself_tmp
235
+ end
236
+ end
237
+ point_myself = line1.point(parameter_myself);
238
+ point_target = line2.point(parameter_target);
239
+ distance = point_myself.distance(point_target)
240
+ return distance, point_myself, point_target, parameter_myself, parameter_target
241
+ end
242
+ end
243
+ end
244
+
data/lib/geom.rb CHANGED
@@ -1,20 +1,20 @@
1
- module GMath3D
2
-
3
- class Geom
4
- private
5
- @@default_tolerance = 1e-6
6
- @tolerance
7
-
8
- public
9
- attr_accessor :tolerance
10
-
11
- def initialize
12
- @tolerance = @@default_tolerance
13
- end
14
-
15
- def self.default_tolerance
16
- @@default_tolerance
17
- end
18
- end
19
-
20
- end
1
+ module GMath3D
2
+
3
+ class Geom
4
+ private
5
+ @@default_tolerance = 1e-6
6
+ @tolerance
7
+
8
+ public
9
+ attr_accessor :tolerance
10
+
11
+ def initialize
12
+ @tolerance = @@default_tolerance
13
+ end
14
+
15
+ def self.default_tolerance
16
+ @@default_tolerance
17
+ end
18
+ end
19
+
20
+ end
data/lib/gmath3D.rb CHANGED
@@ -1,22 +1,22 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
-
3
- require 'util'
4
- require 'ext'
5
-
6
- require 'geom'
7
- require 'quat'
8
-
9
- require 'vector3'
10
-
11
- require 'line'
12
- require 'finite_line'
13
- require 'ellipse'
14
-
15
- require 'plane'
16
- require 'rectangle'
17
- require 'triangle'
18
- require 'box'
19
-
20
- require 'polyline'
21
-
22
- require 'tri_mesh'
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ require 'util'
4
+ require 'ext'
5
+
6
+ require 'geom'
7
+ require 'quat'
8
+
9
+ require 'vector3'
10
+
11
+ require 'line'
12
+ require 'finite_line'
13
+ require 'ellipse'
14
+
15
+ require 'plane'
16
+ require 'rectangle'
17
+ require 'triangle'
18
+ require 'box'
19
+
20
+ require 'polyline'
21
+
22
+ require 'tri_mesh'