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/.document +5 -5
- data/Gemfile +5 -5
- data/LICENSE.txt +20 -20
- data/README.rdoc +19 -19
- data/Rakefile +45 -45
- data/VERSION +1 -1
- data/gmath3D.gemspec +79 -79
- data/lib/box.rb +146 -145
- data/lib/ellipse.rb +11 -11
- data/lib/ext.rb +82 -82
- data/lib/finite_line.rb +244 -244
- data/lib/geom.rb +20 -20
- data/lib/gmath3D.rb +22 -22
- data/lib/line.rb +122 -122
- data/lib/plane.rb +131 -131
- data/lib/polyline.rb +73 -73
- data/lib/quat.rb +170 -170
- data/lib/rectangle.rb +155 -155
- data/lib/tri_mesh.rb +258 -258
- data/lib/triangle.rb +281 -281
- data/lib/util.rb +36 -36
- data/lib/vector3.rb +231 -227
- data/test/helper.rb +15 -15
- data/test/test_box.rb +172 -167
- data/test/test_ellipse.rb +55 -55
- data/test/test_finite_line.rb +306 -306
- data/test/test_geom.rb +17 -17
- data/test/test_line.rb +146 -146
- data/test/test_matrix_util.rb +84 -84
- data/test/test_plane.rb +200 -200
- data/test/test_polyline.rb +93 -93
- data/test/test_quat.rb +144 -144
- data/test/test_rectangle.rb +184 -184
- data/test/test_tri_mesh.rb +186 -186
- data/test/test_triangle.rb +318 -318
- data/test/test_util.rb +88 -88
- data/test/test_vector3.rb +453 -439
- metadata +8 -8
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'
|
data/lib/line.rb
CHANGED
@@ -1,122 +1,122 @@
|
|
1
|
-
require 'gmath3D'
|
2
|
-
|
3
|
-
module GMath3D
|
4
|
-
#
|
5
|
-
# Line represents a infinite line on 3D space.
|
6
|
-
#
|
7
|
-
class Line < Geom
|
8
|
-
public
|
9
|
-
attr_accessor :base_point
|
10
|
-
attr_accessor :direction
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
"Line[point#{@base_point.to_element_s}, vector#{@direction.to_element_s}"
|
14
|
-
end
|
15
|
-
|
16
|
-
# [Input]
|
17
|
-
# _point_ and _direction_ should be Vector3.
|
18
|
-
# [Output]
|
19
|
-
# return new instance of Line.
|
20
|
-
def initialize(point = Vector3.new(0.0,0.0,0.0), direction = Vector3.new(1.0,0.0,0.0))
|
21
|
-
Util3D.check_arg_type(Vector3, point)
|
22
|
-
Util3D.check_arg_type(Vector3, direction)
|
23
|
-
super()
|
24
|
-
@base_point = point
|
25
|
-
@direction = direction
|
26
|
-
end
|
27
|
-
|
28
|
-
def initialize_copy( original_obj )
|
29
|
-
@base_point = original_obj.base_point.dup
|
30
|
-
@direction = original_obj.direction.dup
|
31
|
-
end
|
32
|
-
|
33
|
-
# [Input]
|
34
|
-
# _rhs_ is Line.
|
35
|
-
# [Output]
|
36
|
-
# return true if rhs equals myself.
|
37
|
-
def ==(rhs)
|
38
|
-
return false if rhs == nil
|
39
|
-
return false if( !rhs.kind_of?(Line) )
|
40
|
-
return false if( self.base_point != rhs.base_point)
|
41
|
-
return false if( self.direction != rhs.direction)
|
42
|
-
return true
|
43
|
-
end
|
44
|
-
|
45
|
-
# [Input]
|
46
|
-
# _parameter_ should be Numeric.
|
47
|
-
# [Output]
|
48
|
-
# return a point on line at input parameter position as Vector3
|
49
|
-
def point(parameter)
|
50
|
-
Util3D.check_arg_type(::Numeric, parameter)
|
51
|
-
@base_point + @direction*parameter
|
52
|
-
end
|
53
|
-
|
54
|
-
# This function returns closest distance between Line and anothor element.
|
55
|
-
# [Input]
|
56
|
-
# _target_ should be Vector3 or Line.
|
57
|
-
#
|
58
|
-
# [Output]
|
59
|
-
# [in case _target_ is Vector3]
|
60
|
-
# return "distance, closest point on myself, parameter on myself" as [Numeric, Vector3, Numeric]
|
61
|
-
# [in case _target_ is Line]
|
62
|
-
# return "distance, point on myself, point on target, parameter on myself, parameter on tatget"
|
63
|
-
# as [Numeric, Vector3, Vector3, Numeric, Numeric]
|
64
|
-
def distance(target)
|
65
|
-
# with Point
|
66
|
-
if(target.kind_of?(Vector3))
|
67
|
-
return distance_to_point(target)
|
68
|
-
#with Line
|
69
|
-
elsif(target.kind_of?(Line))
|
70
|
-
return distance_to_line(target)
|
71
|
-
end
|
72
|
-
Util3D.raise_argurment_error(target)
|
73
|
-
end
|
74
|
-
|
75
|
-
private
|
76
|
-
def distance_to_point(target_point)
|
77
|
-
point_on_line1 = self.base_point
|
78
|
-
point_on_line2 = self.base_point + self.direction
|
79
|
-
|
80
|
-
vecAB = point_on_line2 - point_on_line1
|
81
|
-
vecAP = target_point - point_on_line1
|
82
|
-
vecAQ, parameter = vecAP.project_to(vecAB)
|
83
|
-
cross_point = point_on_line1 + vecAQ
|
84
|
-
vecPQ = vecAQ - vecAP
|
85
|
-
return vecPQ.length, cross_point, parameter
|
86
|
-
end
|
87
|
-
|
88
|
-
def distance_to_line(target_line)
|
89
|
-
if(self.direction.parallel?(target_line.direction)) then
|
90
|
-
distanceInfo = self.distance(target_line.base_point)
|
91
|
-
return distanceInfo[0], nil, nil, nil, nil
|
92
|
-
else
|
93
|
-
line1_point1 = self.base_point
|
94
|
-
line1_point2 = self.base_point + self.direction
|
95
|
-
line2_point1 = target_line.base_point
|
96
|
-
line2_point2 = target_line.base_point + target_line.direction
|
97
|
-
|
98
|
-
vec_da = line1_point2 - line1_point1
|
99
|
-
vec_db = line2_point2 - line2_point1
|
100
|
-
vec_ab = line2_point1 - line1_point1
|
101
|
-
|
102
|
-
abs_vec_db = vec_db.length*vec_db.length
|
103
|
-
abs_vec_da = vec_da.length*vec_da.length
|
104
|
-
|
105
|
-
delta = (abs_vec_da*abs_vec_db - vec_da.dot( vec_db )*vec_da.dot( vec_db ))
|
106
|
-
|
107
|
-
if( delta < self.tolerance )
|
108
|
-
# TODO ASSERT(false)
|
109
|
-
return nil
|
110
|
-
end
|
111
|
-
parameter1 = (abs_vec_db*vec_ab.dot(vec_da) - vec_da.dot( vec_db )*vec_ab.dot( vec_db ) ) / delta
|
112
|
-
parameter2 = (vec_da.dot( vec_db )*vec_ab.dot( vec_da ) - abs_vec_da*vec_ab.dot( vec_db ))/ delta
|
113
|
-
|
114
|
-
line1_closest_point = line1_point1 + vec_da*parameter1
|
115
|
-
line2_closest_point = line2_point1 + vec_db*parameter2
|
116
|
-
distance = line1_closest_point.distance( line2_closest_point )
|
117
|
-
return distance, line1_closest_point, line2_closest_point, parameter1, parameter2
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
1
|
+
require 'gmath3D'
|
2
|
+
|
3
|
+
module GMath3D
|
4
|
+
#
|
5
|
+
# Line represents a infinite line on 3D space.
|
6
|
+
#
|
7
|
+
class Line < Geom
|
8
|
+
public
|
9
|
+
attr_accessor :base_point
|
10
|
+
attr_accessor :direction
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"Line[point#{@base_point.to_element_s}, vector#{@direction.to_element_s}"
|
14
|
+
end
|
15
|
+
|
16
|
+
# [Input]
|
17
|
+
# _point_ and _direction_ should be Vector3.
|
18
|
+
# [Output]
|
19
|
+
# return new instance of Line.
|
20
|
+
def initialize(point = Vector3.new(0.0,0.0,0.0), direction = Vector3.new(1.0,0.0,0.0))
|
21
|
+
Util3D.check_arg_type(Vector3, point)
|
22
|
+
Util3D.check_arg_type(Vector3, direction)
|
23
|
+
super()
|
24
|
+
@base_point = point
|
25
|
+
@direction = direction
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize_copy( original_obj )
|
29
|
+
@base_point = original_obj.base_point.dup
|
30
|
+
@direction = original_obj.direction.dup
|
31
|
+
end
|
32
|
+
|
33
|
+
# [Input]
|
34
|
+
# _rhs_ is Line.
|
35
|
+
# [Output]
|
36
|
+
# return true if rhs equals myself.
|
37
|
+
def ==(rhs)
|
38
|
+
return false if rhs == nil
|
39
|
+
return false if( !rhs.kind_of?(Line) )
|
40
|
+
return false if( self.base_point != rhs.base_point)
|
41
|
+
return false if( self.direction != rhs.direction)
|
42
|
+
return true
|
43
|
+
end
|
44
|
+
|
45
|
+
# [Input]
|
46
|
+
# _parameter_ should be Numeric.
|
47
|
+
# [Output]
|
48
|
+
# return a point on line at input parameter position as Vector3
|
49
|
+
def point(parameter)
|
50
|
+
Util3D.check_arg_type(::Numeric, parameter)
|
51
|
+
@base_point + @direction*parameter
|
52
|
+
end
|
53
|
+
|
54
|
+
# This function returns closest distance between Line and anothor element.
|
55
|
+
# [Input]
|
56
|
+
# _target_ should be Vector3 or Line.
|
57
|
+
#
|
58
|
+
# [Output]
|
59
|
+
# [in case _target_ is Vector3]
|
60
|
+
# return "distance, closest point on myself, parameter on myself" as [Numeric, Vector3, Numeric]
|
61
|
+
# [in case _target_ is Line]
|
62
|
+
# return "distance, point on myself, point on target, parameter on myself, parameter on tatget"
|
63
|
+
# as [Numeric, Vector3, Vector3, Numeric, Numeric]
|
64
|
+
def distance(target)
|
65
|
+
# with Point
|
66
|
+
if(target.kind_of?(Vector3))
|
67
|
+
return distance_to_point(target)
|
68
|
+
#with Line
|
69
|
+
elsif(target.kind_of?(Line))
|
70
|
+
return distance_to_line(target)
|
71
|
+
end
|
72
|
+
Util3D.raise_argurment_error(target)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
def distance_to_point(target_point)
|
77
|
+
point_on_line1 = self.base_point
|
78
|
+
point_on_line2 = self.base_point + self.direction
|
79
|
+
|
80
|
+
vecAB = point_on_line2 - point_on_line1
|
81
|
+
vecAP = target_point - point_on_line1
|
82
|
+
vecAQ, parameter = vecAP.project_to(vecAB)
|
83
|
+
cross_point = point_on_line1 + vecAQ
|
84
|
+
vecPQ = vecAQ - vecAP
|
85
|
+
return vecPQ.length, cross_point, parameter
|
86
|
+
end
|
87
|
+
|
88
|
+
def distance_to_line(target_line)
|
89
|
+
if(self.direction.parallel?(target_line.direction)) then
|
90
|
+
distanceInfo = self.distance(target_line.base_point)
|
91
|
+
return distanceInfo[0], nil, nil, nil, nil
|
92
|
+
else
|
93
|
+
line1_point1 = self.base_point
|
94
|
+
line1_point2 = self.base_point + self.direction
|
95
|
+
line2_point1 = target_line.base_point
|
96
|
+
line2_point2 = target_line.base_point + target_line.direction
|
97
|
+
|
98
|
+
vec_da = line1_point2 - line1_point1
|
99
|
+
vec_db = line2_point2 - line2_point1
|
100
|
+
vec_ab = line2_point1 - line1_point1
|
101
|
+
|
102
|
+
abs_vec_db = vec_db.length*vec_db.length
|
103
|
+
abs_vec_da = vec_da.length*vec_da.length
|
104
|
+
|
105
|
+
delta = (abs_vec_da*abs_vec_db - vec_da.dot( vec_db )*vec_da.dot( vec_db ))
|
106
|
+
|
107
|
+
if( delta < self.tolerance )
|
108
|
+
# TODO ASSERT(false)
|
109
|
+
return nil
|
110
|
+
end
|
111
|
+
parameter1 = (abs_vec_db*vec_ab.dot(vec_da) - vec_da.dot( vec_db )*vec_ab.dot( vec_db ) ) / delta
|
112
|
+
parameter2 = (vec_da.dot( vec_db )*vec_ab.dot( vec_da ) - abs_vec_da*vec_ab.dot( vec_db ))/ delta
|
113
|
+
|
114
|
+
line1_closest_point = line1_point1 + vec_da*parameter1
|
115
|
+
line2_closest_point = line2_point1 + vec_db*parameter2
|
116
|
+
distance = line1_closest_point.distance( line2_closest_point )
|
117
|
+
return distance, line1_closest_point, line2_closest_point, parameter1, parameter2
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
data/lib/plane.rb
CHANGED
@@ -1,131 +1,131 @@
|
|
1
|
-
require 'gmath3D'
|
2
|
-
|
3
|
-
module GMath3D
|
4
|
-
#
|
5
|
-
# Plane represents a infinite plane on 3D space.
|
6
|
-
#
|
7
|
-
class Plane < Geom
|
8
|
-
attr_accessor:base_point
|
9
|
-
attr_accessor:normal
|
10
|
-
|
11
|
-
# [Input]
|
12
|
-
# _base_point_ and _normal_ should be Vector3.
|
13
|
-
# [Output]
|
14
|
-
# returns new instance of Plane.
|
15
|
-
def initialize(base_point = Vector3.new(), normal = Vector3.new(0,0,1))
|
16
|
-
Util3D.check_arg_type(::Vector3, normal)
|
17
|
-
Util3D.check_arg_type(::Vector3, base_point)
|
18
|
-
super()
|
19
|
-
@base_point = base_point
|
20
|
-
@normal = normal.normalize()
|
21
|
-
end
|
22
|
-
|
23
|
-
def initialize_copy( original_obj )
|
24
|
-
@base_point = original_obj.base_point.dup
|
25
|
-
@normal = original_obj.normal.dup
|
26
|
-
end
|
27
|
-
|
28
|
-
# [Input]
|
29
|
-
# _rhs_ is Plane.
|
30
|
-
# [Output]
|
31
|
-
# return true if rhs equals myself.
|
32
|
-
def ==(rhs)
|
33
|
-
return false if rhs == nil
|
34
|
-
return false if( !rhs.kind_of?(Plane) )
|
35
|
-
return false if( self.base_point != rhs.base_point)
|
36
|
-
return false if( self.normal != rhs.normal)
|
37
|
-
return true
|
38
|
-
end
|
39
|
-
|
40
|
-
def to_s
|
41
|
-
"Plane[point#{@base_point.to_element_s}, normal#{@normal.to_element_s}]"
|
42
|
-
end
|
43
|
-
|
44
|
-
# This function returns closest distance between Line and anothor element.
|
45
|
-
# [Input]
|
46
|
-
# _target_ should be Vector3 or Line or FiniteLine or Plane.
|
47
|
-
#
|
48
|
-
# [Output]
|
49
|
-
# [in case _target_ is Vector3]
|
50
|
-
# return "distance, closest point on myself" as [Numeric, Vector3].
|
51
|
-
# [in case _target_ is Line]
|
52
|
-
# return "distance, intersect point, parameter on tatget" as [Numeric, Vector3, Numeric].
|
53
|
-
# [in case _target_ is FiniteLine]
|
54
|
-
# return "distance, point on plane, point on target, parameter on target"
|
55
|
-
# as [Numeric, Vector3, Vector3, Numeric].
|
56
|
-
# [in case _target_ is Plane]
|
57
|
-
# return "distance, intersect line" as [Numeric, Vector3].
|
58
|
-
def distance(target)
|
59
|
-
# with Point
|
60
|
-
if(target.kind_of?(Vector3))
|
61
|
-
return distance_to_point(target)
|
62
|
-
#with Line
|
63
|
-
elsif(target.kind_of?(Line))
|
64
|
-
return distance_to_line(target)
|
65
|
-
#with FiniteLine
|
66
|
-
elsif(target.kind_of?(FiniteLine))
|
67
|
-
return distance_to_finite_line(target)
|
68
|
-
#with Plane
|
69
|
-
elsif(target.kind_of?(Plane))
|
70
|
-
return distance_to_plane(target)
|
71
|
-
end
|
72
|
-
Util3D.raise_argurment_error(target)
|
73
|
-
end
|
74
|
-
|
75
|
-
# [Input]
|
76
|
-
# _target_point_ should be Vector3.
|
77
|
-
# [Output]
|
78
|
-
# retrun projected point on plane as Vector3.
|
79
|
-
def project( target_point )
|
80
|
-
Util3D.check_arg_type(::Vector3, target_point)
|
81
|
-
distance, closest_point = self.distance( target_point )
|
82
|
-
return closest_point
|
83
|
-
end
|
84
|
-
private
|
85
|
-
def distance_to_point(target_point)
|
86
|
-
vector_QA = target_point - @base_point
|
87
|
-
distance = vector_QA.dot(@normal)
|
88
|
-
closest_point = target_point - @normal*distance
|
89
|
-
return distance.abs, closest_point
|
90
|
-
end
|
91
|
-
|
92
|
-
def distance_to_line(target_line)
|
93
|
-
inner_product_normal_and_line_vec = target_line.direction.dot(self.normal)
|
94
|
-
#parallel
|
95
|
-
if( inner_product_normal_and_line_vec.abs < @tolerance)
|
96
|
-
distance, closest_point = self.distance(target_line.base_point)
|
97
|
-
return distance, nil,nil
|
98
|
-
end
|
99
|
-
parameter = ( self.normal.dot(self.base_point) - self.normal.dot( target_line.base_point ) )/inner_product_normal_and_line_vec.to_f
|
100
|
-
intersect_point = target_line.point(parameter)
|
101
|
-
return 0.0, intersect_point, parameter
|
102
|
-
end
|
103
|
-
|
104
|
-
def distance_to_finite_line(target_finite_line)
|
105
|
-
target_infinite_line = Line.new(target_finite_line.start_point, target_finite_line.direction)
|
106
|
-
distance, intersect_point, parameter = self.distance(target_infinite_line)
|
107
|
-
point_on_line = intersect_point
|
108
|
-
point_on_plane = intersect_point
|
109
|
-
if(parameter != nil and (parameter < 0 or 1 < parameter))
|
110
|
-
parameter = [0, parameter].max
|
111
|
-
parameter = [1, parameter].min
|
112
|
-
point_on_line = target_finite_line.point(parameter)
|
113
|
-
distance, point_on_plane = self.distance(point_on_line)
|
114
|
-
end
|
115
|
-
return distance, point_on_plane, point_on_line, parameter
|
116
|
-
end
|
117
|
-
def distance_to_plane(target_plane)
|
118
|
-
line_vector = target_plane.normal.cross(self.normal)
|
119
|
-
if(target_plane.normal.parallel?(self.normal))
|
120
|
-
distance, point_on_plane = self.distance(target_plane.base_point)
|
121
|
-
return distance, nil
|
122
|
-
end
|
123
|
-
line_vector = line_vector.normalize()
|
124
|
-
tangent_vector_on_target_plane = line_vector.cross(target_plane.normal)
|
125
|
-
distance, intersect_point, parameter = self.distance(Line.new( target_plane.base_point, tangent_vector_on_target_plane))
|
126
|
-
intersect_line = Line.new(intersect_point, line_vector)
|
127
|
-
return 0, intersect_line
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
1
|
+
require 'gmath3D'
|
2
|
+
|
3
|
+
module GMath3D
|
4
|
+
#
|
5
|
+
# Plane represents a infinite plane on 3D space.
|
6
|
+
#
|
7
|
+
class Plane < Geom
|
8
|
+
attr_accessor:base_point
|
9
|
+
attr_accessor:normal
|
10
|
+
|
11
|
+
# [Input]
|
12
|
+
# _base_point_ and _normal_ should be Vector3.
|
13
|
+
# [Output]
|
14
|
+
# returns new instance of Plane.
|
15
|
+
def initialize(base_point = Vector3.new(), normal = Vector3.new(0,0,1))
|
16
|
+
Util3D.check_arg_type(::Vector3, normal)
|
17
|
+
Util3D.check_arg_type(::Vector3, base_point)
|
18
|
+
super()
|
19
|
+
@base_point = base_point
|
20
|
+
@normal = normal.normalize()
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize_copy( original_obj )
|
24
|
+
@base_point = original_obj.base_point.dup
|
25
|
+
@normal = original_obj.normal.dup
|
26
|
+
end
|
27
|
+
|
28
|
+
# [Input]
|
29
|
+
# _rhs_ is Plane.
|
30
|
+
# [Output]
|
31
|
+
# return true if rhs equals myself.
|
32
|
+
def ==(rhs)
|
33
|
+
return false if rhs == nil
|
34
|
+
return false if( !rhs.kind_of?(Plane) )
|
35
|
+
return false if( self.base_point != rhs.base_point)
|
36
|
+
return false if( self.normal != rhs.normal)
|
37
|
+
return true
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
"Plane[point#{@base_point.to_element_s}, normal#{@normal.to_element_s}]"
|
42
|
+
end
|
43
|
+
|
44
|
+
# This function returns closest distance between Line and anothor element.
|
45
|
+
# [Input]
|
46
|
+
# _target_ should be Vector3 or Line or FiniteLine or Plane.
|
47
|
+
#
|
48
|
+
# [Output]
|
49
|
+
# [in case _target_ is Vector3]
|
50
|
+
# return "distance, closest point on myself" as [Numeric, Vector3].
|
51
|
+
# [in case _target_ is Line]
|
52
|
+
# return "distance, intersect point, parameter on tatget" as [Numeric, Vector3, Numeric].
|
53
|
+
# [in case _target_ is FiniteLine]
|
54
|
+
# return "distance, point on plane, point on target, parameter on target"
|
55
|
+
# as [Numeric, Vector3, Vector3, Numeric].
|
56
|
+
# [in case _target_ is Plane]
|
57
|
+
# return "distance, intersect line" as [Numeric, Vector3].
|
58
|
+
def distance(target)
|
59
|
+
# with Point
|
60
|
+
if(target.kind_of?(Vector3))
|
61
|
+
return distance_to_point(target)
|
62
|
+
#with Line
|
63
|
+
elsif(target.kind_of?(Line))
|
64
|
+
return distance_to_line(target)
|
65
|
+
#with FiniteLine
|
66
|
+
elsif(target.kind_of?(FiniteLine))
|
67
|
+
return distance_to_finite_line(target)
|
68
|
+
#with Plane
|
69
|
+
elsif(target.kind_of?(Plane))
|
70
|
+
return distance_to_plane(target)
|
71
|
+
end
|
72
|
+
Util3D.raise_argurment_error(target)
|
73
|
+
end
|
74
|
+
|
75
|
+
# [Input]
|
76
|
+
# _target_point_ should be Vector3.
|
77
|
+
# [Output]
|
78
|
+
# retrun projected point on plane as Vector3.
|
79
|
+
def project( target_point )
|
80
|
+
Util3D.check_arg_type(::Vector3, target_point)
|
81
|
+
distance, closest_point = self.distance( target_point )
|
82
|
+
return closest_point
|
83
|
+
end
|
84
|
+
private
|
85
|
+
def distance_to_point(target_point)
|
86
|
+
vector_QA = target_point - @base_point
|
87
|
+
distance = vector_QA.dot(@normal)
|
88
|
+
closest_point = target_point - @normal*distance
|
89
|
+
return distance.abs, closest_point
|
90
|
+
end
|
91
|
+
|
92
|
+
def distance_to_line(target_line)
|
93
|
+
inner_product_normal_and_line_vec = target_line.direction.dot(self.normal)
|
94
|
+
#parallel
|
95
|
+
if( inner_product_normal_and_line_vec.abs < @tolerance)
|
96
|
+
distance, closest_point = self.distance(target_line.base_point)
|
97
|
+
return distance, nil,nil
|
98
|
+
end
|
99
|
+
parameter = ( self.normal.dot(self.base_point) - self.normal.dot( target_line.base_point ) )/inner_product_normal_and_line_vec.to_f
|
100
|
+
intersect_point = target_line.point(parameter)
|
101
|
+
return 0.0, intersect_point, parameter
|
102
|
+
end
|
103
|
+
|
104
|
+
def distance_to_finite_line(target_finite_line)
|
105
|
+
target_infinite_line = Line.new(target_finite_line.start_point, target_finite_line.direction)
|
106
|
+
distance, intersect_point, parameter = self.distance(target_infinite_line)
|
107
|
+
point_on_line = intersect_point
|
108
|
+
point_on_plane = intersect_point
|
109
|
+
if(parameter != nil and (parameter < 0 or 1 < parameter))
|
110
|
+
parameter = [0, parameter].max
|
111
|
+
parameter = [1, parameter].min
|
112
|
+
point_on_line = target_finite_line.point(parameter)
|
113
|
+
distance, point_on_plane = self.distance(point_on_line)
|
114
|
+
end
|
115
|
+
return distance, point_on_plane, point_on_line, parameter
|
116
|
+
end
|
117
|
+
def distance_to_plane(target_plane)
|
118
|
+
line_vector = target_plane.normal.cross(self.normal)
|
119
|
+
if(target_plane.normal.parallel?(self.normal))
|
120
|
+
distance, point_on_plane = self.distance(target_plane.base_point)
|
121
|
+
return distance, nil
|
122
|
+
end
|
123
|
+
line_vector = line_vector.normalize()
|
124
|
+
tangent_vector_on_target_plane = line_vector.cross(target_plane.normal)
|
125
|
+
distance, intersect_point, parameter = self.distance(Line.new( target_plane.base_point, tangent_vector_on_target_plane))
|
126
|
+
intersect_line = Line.new(intersect_point, line_vector)
|
127
|
+
return 0, intersect_line
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|