gmath3D 0.2.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ellipse.rb CHANGED
@@ -1,11 +1,11 @@
1
- require 'gmath3D'
2
-
3
- module GMath3D
4
- #
5
- #
6
- class Ellipse < Geom
7
- def initialize(origin = Vector3.new(), axis1 = Vector3.new(1,0,0), axis2 = Vector3.new(0,1,0))
8
-
9
- end
10
- end
11
- end
1
+ require 'gmath3D'
2
+
3
+ module GMath3D
4
+ #
5
+ #
6
+ class Ellipse < Geom
7
+ def initialize(origin = Vector3.new(), axis1 = Vector3.new(1,0,0), axis2 = Vector3.new(0,1,0))
8
+
9
+ end
10
+ end
11
+ end
data/lib/ext.rb CHANGED
@@ -1,82 +1,82 @@
1
- require 'gmath3D'
2
- require 'matrix'
3
-
4
- module GMath3D
5
- class ::Matrix
6
- def self.from_axis(axis, angle)
7
- Util3D::check_arg_type(Vector3, axis)
8
- Util3D::check_arg_type(Numeric, angle)
9
-
10
- return Matrix[
11
- [axis.x*axis.x*(1 - Math.cos(angle)) + Math.cos(angle),
12
- axis.x*axis.y*(1 - Math.cos(angle)) + axis.z*Math.sin(angle),
13
- axis.x*axis.z*(1 - Math.cos(angle)) - axis.y*Math.sin(angle)],
14
- [axis.x*axis.y*(1 - Math.cos(angle)) - axis.z*Math.sin(angle),
15
- axis.y*axis.y*(1 - Math.cos(angle)) + Math.cos(angle),
16
- axis.y*axis.z*(1 - Math.cos(angle)) + axis.x*Math.sin(angle)],
17
- [axis.x*axis.z*(1 - Math.cos(angle)) + axis.y*Math.sin(angle),
18
- axis.y*axis.z*(1 - Math.cos(angle)) - axis.x*Math.sin(angle),
19
- axis.z*axis.z*(1 - Math.cos(angle)) + Math.cos(angle)]]
20
- end
21
-
22
- def self.from_quat(quat)
23
- Util3D::check_arg_type(Quat, quat)
24
- qw = quat.w
25
- qx = quat.x
26
- qy = quat.y
27
- qz = quat.z
28
-
29
- x2 = 2.0 * qx * qx;
30
- y2 = 2.0 * qy * qy;
31
- z2 = 2.0 * qz * qz;
32
- xy = 2.0 * qx * qy;
33
- yz = 2.0 * qy * qz;
34
- zx = 2.0 * qz * qx;
35
- wx = 2.0 * qw * qx;
36
- wy = 2.0 * qw * qy;
37
- wz = 2.0 * qw * qz;
38
-
39
- return Matrix[
40
- [ 1.0 - y2 - z2, xy + wz, zx - wy],
41
- [ xy - wz, 1.0 - z2 - x2, yz + wx],
42
- [ zx + wy, yz - wx, 1.0 - x2 - y2]]
43
- end
44
-
45
- alias_method :multi_inner, :* # hold original multiply processing
46
- def multi_new(rhs)
47
- if(rhs.kind_of?(Vector3))
48
- ans = self.multi_inner(rhs.to_column_vector)
49
- return Vector3.new(ans[0,0], ans[1,0], ans[2,0])
50
- end
51
- multi_inner(rhs)
52
- end
53
- alias_method :*, :multi_new # overwrite new multiply processing
54
- end
55
-
56
- class ::Array
57
- def sum
58
- s, n = self.sum_with_number
59
- return s
60
- end
61
- def avg
62
- s, n = self.sum_with_number
63
- return s / n
64
- end
65
-
66
- def sum_with_number
67
- return nil, 0 if(self.size <= 0)
68
- s = nil
69
- n = 0
70
- self.each do |v|
71
- next if v.nil?
72
- if(s==nil)
73
- s = v
74
- else
75
- s += v
76
- end
77
- n += 1
78
- end
79
- return s, n
80
- end
81
- end
82
- end
1
+ require 'gmath3D'
2
+ require 'matrix'
3
+
4
+ module GMath3D
5
+ class ::Matrix
6
+ def self.from_axis(axis, angle)
7
+ Util3D::check_arg_type(Vector3, axis)
8
+ Util3D::check_arg_type(Numeric, angle)
9
+
10
+ return Matrix[
11
+ [axis.x*axis.x*(1 - Math.cos(angle)) + Math.cos(angle),
12
+ axis.x*axis.y*(1 - Math.cos(angle)) + axis.z*Math.sin(angle),
13
+ axis.x*axis.z*(1 - Math.cos(angle)) - axis.y*Math.sin(angle)],
14
+ [axis.x*axis.y*(1 - Math.cos(angle)) - axis.z*Math.sin(angle),
15
+ axis.y*axis.y*(1 - Math.cos(angle)) + Math.cos(angle),
16
+ axis.y*axis.z*(1 - Math.cos(angle)) + axis.x*Math.sin(angle)],
17
+ [axis.x*axis.z*(1 - Math.cos(angle)) + axis.y*Math.sin(angle),
18
+ axis.y*axis.z*(1 - Math.cos(angle)) - axis.x*Math.sin(angle),
19
+ axis.z*axis.z*(1 - Math.cos(angle)) + Math.cos(angle)]]
20
+ end
21
+
22
+ def self.from_quat(quat)
23
+ Util3D::check_arg_type(Quat, quat)
24
+ qw = quat.w
25
+ qx = quat.x
26
+ qy = quat.y
27
+ qz = quat.z
28
+
29
+ x2 = 2.0 * qx * qx;
30
+ y2 = 2.0 * qy * qy;
31
+ z2 = 2.0 * qz * qz;
32
+ xy = 2.0 * qx * qy;
33
+ yz = 2.0 * qy * qz;
34
+ zx = 2.0 * qz * qx;
35
+ wx = 2.0 * qw * qx;
36
+ wy = 2.0 * qw * qy;
37
+ wz = 2.0 * qw * qz;
38
+
39
+ return Matrix[
40
+ [ 1.0 - y2 - z2, xy + wz, zx - wy],
41
+ [ xy - wz, 1.0 - z2 - x2, yz + wx],
42
+ [ zx + wy, yz - wx, 1.0 - x2 - y2]]
43
+ end
44
+
45
+ alias_method :multi_inner, :* # hold original multiply processing
46
+ def multi_new(rhs)
47
+ if(rhs.kind_of?(Vector3))
48
+ ans = self.multi_inner(rhs.to_column_vector)
49
+ return Vector3.new(ans[0,0], ans[1,0], ans[2,0])
50
+ end
51
+ multi_inner(rhs)
52
+ end
53
+ alias_method :*, :multi_new # overwrite new multiply processing
54
+ end
55
+
56
+ class ::Array
57
+ def sum
58
+ s, n = self.sum_with_number
59
+ return s
60
+ end
61
+ def avg
62
+ s, n = self.sum_with_number
63
+ return s / n
64
+ end
65
+
66
+ def sum_with_number
67
+ return nil, 0 if(self.size <= 0)
68
+ s = nil
69
+ n = 0
70
+ self.each do |v|
71
+ next if v.nil?
72
+ if(s==nil)
73
+ s = v
74
+ else
75
+ s += v
76
+ end
77
+ n += 1
78
+ end
79
+ return s, n
80
+ end
81
+ end
82
+ end
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
+