gmath3D 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
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'