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/.document +5 -5
- data/Gemfile +5 -11
- data/LICENSE.txt +20 -20
- data/README.rdoc +19 -19
- data/Rakefile +45 -45
- data/VERSION +1 -1
- data/gmath3D.gemspec +79 -80
- data/lib/box.rb +145 -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 -23
- data/lib/vector3.rb +227 -227
- data/test/helper.rb +15 -15
- data/test/test_box.rb +167 -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 -57
- data/test/test_vector3.rb +439 -439
- metadata +8 -11
- data/Gemfile.lock +0 -16
data/lib/vector3.rb
CHANGED
@@ -1,227 +1,227 @@
|
|
1
|
-
# -*- coding: cp932 -*-
|
2
|
-
require 'gmath3D'
|
3
|
-
|
4
|
-
module GMath3D
|
5
|
-
#
|
6
|
-
# Vector3 represents a point or a vector on 3D space.
|
7
|
-
#
|
8
|
-
class Vector3 < Geom
|
9
|
-
attr_accessor :x
|
10
|
-
attr_accessor :y
|
11
|
-
attr_accessor :z
|
12
|
-
|
13
|
-
# [Input]
|
14
|
-
# _x_, _y_, _z_ should be Numeric.
|
15
|
-
# [Output]
|
16
|
-
# return new instance as Vector3.
|
17
|
-
def initialize(x=0.0,y=0.0,z=0.0)
|
18
|
-
Util3D.check_arg_type(Numeric, x)
|
19
|
-
Util3D.check_arg_type(Numeric, y)
|
20
|
-
Util3D.check_arg_type(Numeric, z)
|
21
|
-
super()
|
22
|
-
@x = x
|
23
|
-
@y = y
|
24
|
-
@z = z
|
25
|
-
end
|
26
|
-
|
27
|
-
def to_element_s
|
28
|
-
"[#{@x}, #{@y}, #{@z}]"
|
29
|
-
end
|
30
|
-
|
31
|
-
def to_s
|
32
|
-
"Vector3" + to_element_s
|
33
|
-
end
|
34
|
-
|
35
|
-
# [Input]
|
36
|
-
# _rhs_ should be Vector3.
|
37
|
-
# [Output]
|
38
|
-
# return true if rhs equals myself.
|
39
|
-
def ==(rhs)
|
40
|
-
return false if( !rhs.kind_of?(Vector3) )
|
41
|
-
equals_inner(rhs)
|
42
|
-
end
|
43
|
-
|
44
|
-
# For using Vector3 as hash key
|
45
|
-
def hash
|
46
|
-
[@x.to_f, @y.to_f, @z.to_f].hash
|
47
|
-
end
|
48
|
-
def eql?(rhs)
|
49
|
-
equals_inner(rhs)
|
50
|
-
end
|
51
|
-
|
52
|
-
# [Output]
|
53
|
-
# return axially aligned bounding box as Box.
|
54
|
-
def box
|
55
|
-
return Box.new(self, self)
|
56
|
-
end
|
57
|
-
|
58
|
-
# [Input]
|
59
|
-
# _rhs_ should be Vector3.
|
60
|
-
# [Output]
|
61
|
-
# return added result as Vector3.
|
62
|
-
def +(rhs)
|
63
|
-
add(rhs)
|
64
|
-
end
|
65
|
-
|
66
|
-
# [Input]
|
67
|
-
# _rhs_ should be Vector3.
|
68
|
-
# [Output]
|
69
|
-
# return subtracted result as Vector3.
|
70
|
-
def -(rhs)
|
71
|
-
subtract(rhs)
|
72
|
-
end
|
73
|
-
|
74
|
-
# [Input]
|
75
|
-
# _rsh_ should be Numeric.
|
76
|
-
# [Output]
|
77
|
-
# return multiplyed result as Vector3.
|
78
|
-
def *(rhs)
|
79
|
-
multiply(rhs)
|
80
|
-
end
|
81
|
-
|
82
|
-
# [Input]
|
83
|
-
# _rhs_ should be Numeric.
|
84
|
-
# [Output]
|
85
|
-
# return divided result as Vector3.
|
86
|
-
def /(rhs)
|
87
|
-
divide(rhs)
|
88
|
-
end
|
89
|
-
|
90
|
-
# [Input]
|
91
|
-
# _rhs_ should be Vector3.
|
92
|
-
# [Output]
|
93
|
-
# return inner product as Numeric
|
94
|
-
def dot(rhs)
|
95
|
-
Util3D.check_arg_type(Vector3, rhs)
|
96
|
-
self.x*rhs.x + self.y*rhs.y + self.z*rhs.z
|
97
|
-
end
|
98
|
-
|
99
|
-
# [Input]
|
100
|
-
# _rhs_ should be Vector3.
|
101
|
-
# [Output]
|
102
|
-
# return cross product as Vector3.
|
103
|
-
def cross(rhs)
|
104
|
-
Util3D.check_arg_type(Vector3, rhs)
|
105
|
-
Vector3.new(
|
106
|
-
self.y*rhs.z - self.z*rhs.y,
|
107
|
-
self.z*rhs.x - self.x*rhs.z,
|
108
|
-
self.x*rhs.y - self.y*rhs.x)
|
109
|
-
end
|
110
|
-
|
111
|
-
# [Output]
|
112
|
-
# return orthogonal vector as Vector3.
|
113
|
-
def arbitrary_orthogonal
|
114
|
-
return Vector3.new() if(self.length < self.tolerance)
|
115
|
-
|
116
|
-
if(!self.parallel?( Vector3.new(0.0, 1.0, 0.0) ))
|
117
|
-
un_parallel_vec = Vector3.new(0.0,1.0,0.0)
|
118
|
-
elsif(!self.parallel?( Vector3.new(0.0,0.0,1.0) ))
|
119
|
-
un_parallel_vec = Vector3.new(0.0,0.0,1.0)
|
120
|
-
else
|
121
|
-
un_parallel_vec = Vector3.new(1.0,0.0,0.0)
|
122
|
-
end
|
123
|
-
|
124
|
-
orthogonal = self.cross(un_parallel_vec)
|
125
|
-
return orthogonal.normalize
|
126
|
-
end
|
127
|
-
|
128
|
-
# [Output]
|
129
|
-
# return vector length as Numeric
|
130
|
-
def length
|
131
|
-
Math::sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
|
132
|
-
end
|
133
|
-
|
134
|
-
# [Input]
|
135
|
-
# _rhs_ should be Vector3.
|
136
|
-
# [Output]
|
137
|
-
# return distance between two points as Numeric.
|
138
|
-
def distance(rhs)
|
139
|
-
Util3D.check_arg_type(Vector3, rhs)
|
140
|
-
Math::sqrt((self.x - rhs.x)*(self.x - rhs.x) + (self.y - rhs.y)*(self.y - rhs.y) + (self.z - rhs.z)*(self.z - rhs.z))
|
141
|
-
end
|
142
|
-
|
143
|
-
# [Input]
|
144
|
-
# _rhs_ should be Vector3.
|
145
|
-
# [Output]
|
146
|
-
# return two vectors angle as Numeric (rad).
|
147
|
-
def angle(rhs)
|
148
|
-
Util3D.check_arg_type(Vector3, rhs)
|
149
|
-
vec1Length = self.length ;
|
150
|
-
vec2Length = rhs.length ;
|
151
|
-
return 0.0 if(vec1Length*vec2Length < self.tolerance )
|
152
|
-
v = self.dot(rhs)/(vec1Length*vec2Length)
|
153
|
-
Math::acos( v )
|
154
|
-
end
|
155
|
-
|
156
|
-
# [Output]
|
157
|
-
# return normalized vector as Vector3
|
158
|
-
def normalize()
|
159
|
-
self / self.length.to_f
|
160
|
-
end
|
161
|
-
|
162
|
-
# [Input]
|
163
|
-
# _rhs_ should be Vector3
|
164
|
-
# [Output]
|
165
|
-
# return true if myself and rhs is parallel as boolean
|
166
|
-
def parallel?(rhs)
|
167
|
-
Util3D.check_arg_type(Vector3, rhs)
|
168
|
-
return false if(self.length < self.tolerance or rhs.length < rhs.tolerance)
|
169
|
-
return false if(self.cross(rhs).length > self.tolerance)
|
170
|
-
return true
|
171
|
-
end
|
172
|
-
|
173
|
-
# [Input]
|
174
|
-
# _rhs_ should be Vector3.
|
175
|
-
# [Output]
|
176
|
-
# return true if myself and rhs have same direction as boolean.
|
177
|
-
def same_direction?(rhs)
|
178
|
-
Util3D.check_arg_type(Vector3, rhs)
|
179
|
-
return false if(!parallel?(rhs))
|
180
|
-
return false if(self.dot(rhs) < self.tolerance)
|
181
|
-
return true
|
182
|
-
end
|
183
|
-
|
184
|
-
# This function projects self vector to rhs vector.
|
185
|
-
# [Input]
|
186
|
-
# _rhs_ should be Vector3.
|
187
|
-
# [Output]
|
188
|
-
# return projected result as Vector3.
|
189
|
-
def project_to(rhs)
|
190
|
-
Util3D.check_arg_type(Vector3, rhs)
|
191
|
-
return Vector3.new, 0.0 if( rhs.length < rhs.tolerance )
|
192
|
-
parameter = self.dot( rhs ) / ( rhs.x * rhs.x + rhs.y * rhs.y + rhs.z * rhs.z ).to_f
|
193
|
-
return rhs*parameter, parameter
|
194
|
-
end
|
195
|
-
|
196
|
-
# [Output]
|
197
|
-
# return column vector as Matrix
|
198
|
-
def to_column_vector
|
199
|
-
return Matrix.column_vector([x,y,z])
|
200
|
-
end
|
201
|
-
|
202
|
-
private
|
203
|
-
def equals_inner(rhs)
|
204
|
-
return false if((self.x - rhs.x).abs > @tolerance)
|
205
|
-
return false if((self.y - rhs.y).abs > @tolerance)
|
206
|
-
return false if((self.z - rhs.z).abs > @tolerance)
|
207
|
-
true
|
208
|
-
end
|
209
|
-
def add(rhs)
|
210
|
-
Util3D.check_arg_type(Vector3, rhs)
|
211
|
-
Vector3.new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
|
212
|
-
end
|
213
|
-
def subtract(rhs)
|
214
|
-
Util3D.check_arg_type(Vector3, rhs)
|
215
|
-
Vector3.new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
|
216
|
-
end
|
217
|
-
def multiply(rhs)
|
218
|
-
Util3D.check_arg_type(::Numeric, rhs)
|
219
|
-
Vector3.new(self.x * rhs, self.y * rhs, self.z * rhs)
|
220
|
-
end
|
221
|
-
def divide(rhs)
|
222
|
-
Util3D.check_arg_type(::Numeric, rhs)
|
223
|
-
Vector3.new(self.x.to_f / rhs, self.y / rhs.to_f, self.z / rhs.to_f)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
1
|
+
# -*- coding: cp932 -*-
|
2
|
+
require 'gmath3D'
|
3
|
+
|
4
|
+
module GMath3D
|
5
|
+
#
|
6
|
+
# Vector3 represents a point or a vector on 3D space.
|
7
|
+
#
|
8
|
+
class Vector3 < Geom
|
9
|
+
attr_accessor :x
|
10
|
+
attr_accessor :y
|
11
|
+
attr_accessor :z
|
12
|
+
|
13
|
+
# [Input]
|
14
|
+
# _x_, _y_, _z_ should be Numeric.
|
15
|
+
# [Output]
|
16
|
+
# return new instance as Vector3.
|
17
|
+
def initialize(x=0.0,y=0.0,z=0.0)
|
18
|
+
Util3D.check_arg_type(Numeric, x)
|
19
|
+
Util3D.check_arg_type(Numeric, y)
|
20
|
+
Util3D.check_arg_type(Numeric, z)
|
21
|
+
super()
|
22
|
+
@x = x
|
23
|
+
@y = y
|
24
|
+
@z = z
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_element_s
|
28
|
+
"[#{@x}, #{@y}, #{@z}]"
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
"Vector3" + to_element_s
|
33
|
+
end
|
34
|
+
|
35
|
+
# [Input]
|
36
|
+
# _rhs_ should be Vector3.
|
37
|
+
# [Output]
|
38
|
+
# return true if rhs equals myself.
|
39
|
+
def ==(rhs)
|
40
|
+
return false if( !rhs.kind_of?(Vector3) )
|
41
|
+
equals_inner(rhs)
|
42
|
+
end
|
43
|
+
|
44
|
+
# For using Vector3 as hash key
|
45
|
+
def hash
|
46
|
+
[@x.to_f, @y.to_f, @z.to_f].hash
|
47
|
+
end
|
48
|
+
def eql?(rhs)
|
49
|
+
equals_inner(rhs)
|
50
|
+
end
|
51
|
+
|
52
|
+
# [Output]
|
53
|
+
# return axially aligned bounding box as Box.
|
54
|
+
def box
|
55
|
+
return Box.new(self, self)
|
56
|
+
end
|
57
|
+
|
58
|
+
# [Input]
|
59
|
+
# _rhs_ should be Vector3.
|
60
|
+
# [Output]
|
61
|
+
# return added result as Vector3.
|
62
|
+
def +(rhs)
|
63
|
+
add(rhs)
|
64
|
+
end
|
65
|
+
|
66
|
+
# [Input]
|
67
|
+
# _rhs_ should be Vector3.
|
68
|
+
# [Output]
|
69
|
+
# return subtracted result as Vector3.
|
70
|
+
def -(rhs)
|
71
|
+
subtract(rhs)
|
72
|
+
end
|
73
|
+
|
74
|
+
# [Input]
|
75
|
+
# _rsh_ should be Numeric.
|
76
|
+
# [Output]
|
77
|
+
# return multiplyed result as Vector3.
|
78
|
+
def *(rhs)
|
79
|
+
multiply(rhs)
|
80
|
+
end
|
81
|
+
|
82
|
+
# [Input]
|
83
|
+
# _rhs_ should be Numeric.
|
84
|
+
# [Output]
|
85
|
+
# return divided result as Vector3.
|
86
|
+
def /(rhs)
|
87
|
+
divide(rhs)
|
88
|
+
end
|
89
|
+
|
90
|
+
# [Input]
|
91
|
+
# _rhs_ should be Vector3.
|
92
|
+
# [Output]
|
93
|
+
# return inner product as Numeric
|
94
|
+
def dot(rhs)
|
95
|
+
Util3D.check_arg_type(Vector3, rhs)
|
96
|
+
self.x*rhs.x + self.y*rhs.y + self.z*rhs.z
|
97
|
+
end
|
98
|
+
|
99
|
+
# [Input]
|
100
|
+
# _rhs_ should be Vector3.
|
101
|
+
# [Output]
|
102
|
+
# return cross product as Vector3.
|
103
|
+
def cross(rhs)
|
104
|
+
Util3D.check_arg_type(Vector3, rhs)
|
105
|
+
Vector3.new(
|
106
|
+
self.y*rhs.z - self.z*rhs.y,
|
107
|
+
self.z*rhs.x - self.x*rhs.z,
|
108
|
+
self.x*rhs.y - self.y*rhs.x)
|
109
|
+
end
|
110
|
+
|
111
|
+
# [Output]
|
112
|
+
# return orthogonal vector as Vector3.
|
113
|
+
def arbitrary_orthogonal
|
114
|
+
return Vector3.new() if(self.length < self.tolerance)
|
115
|
+
|
116
|
+
if(!self.parallel?( Vector3.new(0.0, 1.0, 0.0) ))
|
117
|
+
un_parallel_vec = Vector3.new(0.0,1.0,0.0)
|
118
|
+
elsif(!self.parallel?( Vector3.new(0.0,0.0,1.0) ))
|
119
|
+
un_parallel_vec = Vector3.new(0.0,0.0,1.0)
|
120
|
+
else
|
121
|
+
un_parallel_vec = Vector3.new(1.0,0.0,0.0)
|
122
|
+
end
|
123
|
+
|
124
|
+
orthogonal = self.cross(un_parallel_vec)
|
125
|
+
return orthogonal.normalize
|
126
|
+
end
|
127
|
+
|
128
|
+
# [Output]
|
129
|
+
# return vector length as Numeric
|
130
|
+
def length
|
131
|
+
Math::sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
|
132
|
+
end
|
133
|
+
|
134
|
+
# [Input]
|
135
|
+
# _rhs_ should be Vector3.
|
136
|
+
# [Output]
|
137
|
+
# return distance between two points as Numeric.
|
138
|
+
def distance(rhs)
|
139
|
+
Util3D.check_arg_type(Vector3, rhs)
|
140
|
+
Math::sqrt((self.x - rhs.x)*(self.x - rhs.x) + (self.y - rhs.y)*(self.y - rhs.y) + (self.z - rhs.z)*(self.z - rhs.z))
|
141
|
+
end
|
142
|
+
|
143
|
+
# [Input]
|
144
|
+
# _rhs_ should be Vector3.
|
145
|
+
# [Output]
|
146
|
+
# return two vectors angle as Numeric (rad).
|
147
|
+
def angle(rhs)
|
148
|
+
Util3D.check_arg_type(Vector3, rhs)
|
149
|
+
vec1Length = self.length ;
|
150
|
+
vec2Length = rhs.length ;
|
151
|
+
return 0.0 if(vec1Length*vec2Length < self.tolerance )
|
152
|
+
v = self.dot(rhs)/(vec1Length*vec2Length)
|
153
|
+
Math::acos( v )
|
154
|
+
end
|
155
|
+
|
156
|
+
# [Output]
|
157
|
+
# return normalized vector as Vector3
|
158
|
+
def normalize()
|
159
|
+
self / self.length.to_f
|
160
|
+
end
|
161
|
+
|
162
|
+
# [Input]
|
163
|
+
# _rhs_ should be Vector3
|
164
|
+
# [Output]
|
165
|
+
# return true if myself and rhs is parallel as boolean
|
166
|
+
def parallel?(rhs)
|
167
|
+
Util3D.check_arg_type(Vector3, rhs)
|
168
|
+
return false if(self.length < self.tolerance or rhs.length < rhs.tolerance)
|
169
|
+
return false if(self.cross(rhs).length > self.tolerance)
|
170
|
+
return true
|
171
|
+
end
|
172
|
+
|
173
|
+
# [Input]
|
174
|
+
# _rhs_ should be Vector3.
|
175
|
+
# [Output]
|
176
|
+
# return true if myself and rhs have same direction as boolean.
|
177
|
+
def same_direction?(rhs)
|
178
|
+
Util3D.check_arg_type(Vector3, rhs)
|
179
|
+
return false if(!parallel?(rhs))
|
180
|
+
return false if(self.dot(rhs) < self.tolerance)
|
181
|
+
return true
|
182
|
+
end
|
183
|
+
|
184
|
+
# This function projects self vector to rhs vector.
|
185
|
+
# [Input]
|
186
|
+
# _rhs_ should be Vector3.
|
187
|
+
# [Output]
|
188
|
+
# return projected result as Vector3.
|
189
|
+
def project_to(rhs)
|
190
|
+
Util3D.check_arg_type(Vector3, rhs)
|
191
|
+
return Vector3.new, 0.0 if( rhs.length < rhs.tolerance )
|
192
|
+
parameter = self.dot( rhs ) / ( rhs.x * rhs.x + rhs.y * rhs.y + rhs.z * rhs.z ).to_f
|
193
|
+
return rhs*parameter, parameter
|
194
|
+
end
|
195
|
+
|
196
|
+
# [Output]
|
197
|
+
# return column vector as Matrix
|
198
|
+
def to_column_vector
|
199
|
+
return Matrix.column_vector([x,y,z])
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
def equals_inner(rhs)
|
204
|
+
return false if((self.x - rhs.x).abs > @tolerance)
|
205
|
+
return false if((self.y - rhs.y).abs > @tolerance)
|
206
|
+
return false if((self.z - rhs.z).abs > @tolerance)
|
207
|
+
true
|
208
|
+
end
|
209
|
+
def add(rhs)
|
210
|
+
Util3D.check_arg_type(Vector3, rhs)
|
211
|
+
Vector3.new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
|
212
|
+
end
|
213
|
+
def subtract(rhs)
|
214
|
+
Util3D.check_arg_type(Vector3, rhs)
|
215
|
+
Vector3.new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
|
216
|
+
end
|
217
|
+
def multiply(rhs)
|
218
|
+
Util3D.check_arg_type(::Numeric, rhs)
|
219
|
+
Vector3.new(self.x * rhs, self.y * rhs, self.z * rhs)
|
220
|
+
end
|
221
|
+
def divide(rhs)
|
222
|
+
Util3D.check_arg_type(::Numeric, rhs)
|
223
|
+
Vector3.new(self.x.to_f / rhs, self.y / rhs.to_f, self.z / rhs.to_f)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
data/test/helper.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler'
|
3
|
-
|
4
|
-
begin
|
5
|
-
Bundler.setup(:default, :development)
|
6
|
-
rescue Bundler::BundlerError => e
|
7
|
-
$stderr.puts e.message
|
8
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
9
|
-
exit e.status_code
|
10
|
-
end
|
11
|
-
require 'minitest/unit'
|
12
|
-
|
13
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
-
|
15
|
-
require 'gmath3D'
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
begin
|
5
|
+
Bundler.setup(:default, :development)
|
6
|
+
rescue Bundler::BundlerError => e
|
7
|
+
$stderr.puts e.message
|
8
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
9
|
+
exit e.status_code
|
10
|
+
end
|
11
|
+
require 'minitest/unit'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
|
15
|
+
require 'gmath3D'
|