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/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
+
data/lib/polyline.rb CHANGED
@@ -1,73 +1,73 @@
1
- require 'gmath3D'
2
-
3
- module GMath3D
4
- #
5
- # Polyline represents a closed or open polyline on 3D space.
6
- #
7
- class Polyline < Geom
8
- public
9
- attr_accessor :vertices
10
- attr_accessor :is_open
11
-
12
- include BoxAvailable
13
-
14
- # [Input]
15
- # _vertices_ should be Array of Vector3.
16
- # [Output]
17
- # return new instance of Polyline.
18
- def initialize(vertices = [], is_open = true)
19
- Util3D.check_arg_type(Array, vertices)
20
- super()
21
- @vertices = vertices
22
- @is_open = is_open
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
- @is_open = original_obj.is_open
31
- end
32
-
33
- # [Input]
34
- # _rhs_ is Polyline.
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?(Polyline) )
40
- return false if( self.is_open != rhs.is_open )
41
- return false if(@vertices.size != rhs.vertices.size)
42
- for i in 0..(@vertices.size-1)
43
- return false if( self.vertices[i] != rhs.vertices[i])
44
- end
45
- return true
46
- end
47
-
48
- def to_s
49
- str = "Polyline["
50
- vertices.each do |vertex|
51
- str += vertex.to_element_s + ", "
52
- end
53
- str.slice!(str.length - 2, 2) if(vertices.size > 0)
54
- str += "] "
55
- str += "open" if(@is_open)
56
- str += "closed" if(!@is_open)
57
- return str
58
- end
59
-
60
- # [Output]
61
- # return center point as Vector3.
62
- def center
63
- center = Vector3.new()
64
- @vertices.each do |vertex|
65
- center += vertex
66
- end
67
- center /= @vertices.size
68
- return center
69
- end
70
-
71
- end
72
- end
73
-
1
+ require 'gmath3D'
2
+
3
+ module GMath3D
4
+ #
5
+ # Polyline represents a closed or open polyline on 3D space.
6
+ #
7
+ class Polyline < Geom
8
+ public
9
+ attr_accessor :vertices
10
+ attr_accessor :is_open
11
+
12
+ include BoxAvailable
13
+
14
+ # [Input]
15
+ # _vertices_ should be Array of Vector3.
16
+ # [Output]
17
+ # return new instance of Polyline.
18
+ def initialize(vertices = [], is_open = true)
19
+ Util3D.check_arg_type(Array, vertices)
20
+ super()
21
+ @vertices = vertices
22
+ @is_open = is_open
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
+ @is_open = original_obj.is_open
31
+ end
32
+
33
+ # [Input]
34
+ # _rhs_ is Polyline.
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?(Polyline) )
40
+ return false if( self.is_open != rhs.is_open )
41
+ return false if(@vertices.size != rhs.vertices.size)
42
+ for i in 0..(@vertices.size-1)
43
+ return false if( self.vertices[i] != rhs.vertices[i])
44
+ end
45
+ return true
46
+ end
47
+
48
+ def to_s
49
+ str = "Polyline["
50
+ vertices.each do |vertex|
51
+ str += vertex.to_element_s + ", "
52
+ end
53
+ str.slice!(str.length - 2, 2) if(vertices.size > 0)
54
+ str += "] "
55
+ str += "open" if(@is_open)
56
+ str += "closed" if(!@is_open)
57
+ return str
58
+ end
59
+
60
+ # [Output]
61
+ # return center point as Vector3.
62
+ def center
63
+ center = Vector3.new()
64
+ @vertices.each do |vertex|
65
+ center += vertex
66
+ end
67
+ center /= @vertices.size
68
+ return center
69
+ end
70
+
71
+ end
72
+ end
73
+