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/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'