geo3d 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +49 -1
- data/Rakefile +7 -0
- data/geo3d.gemspec +1 -0
- data/lib/geo3d.rb +1 -0
- data/lib/geo3d/version.rb +1 -1
- data/lib/matrix.rb +39 -12
- data/lib/plane.rb +95 -0
- data/lib/quaternion.rb +5 -4
- data/lib/vector.rb +8 -0
- data/spec/lib/matrix_spec.rb +227 -0
- data/spec/lib/plane_spec.rb +80 -0
- data/spec/lib/quaternion_spec.rb +113 -0
- data/spec/lib/vector_spec.rb +77 -0
- data/spec/spec_helper.rb +1 -0
- metadata +28 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8f3862b698223418bf989a4cce3c0dc45c74aec
|
4
|
+
data.tar.gz: 8df829279ef53a7003215b5aeb18c3a4127af036
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef96a2ee15de30cc29f298cac21258a45c764d8895837525b172280973f89bf905ef7ceb5af4240471b5894c890e57aed57856e2c8337aca7472a47411462e66
|
7
|
+
data.tar.gz: 79c5f1a2776f2647d139f7de64f4fcc148a242bfe0bf9e9c0db3ba0357cda31d522114da94adf2cfd20581080028b36577c67bc814296b36c0d8428a93552518
|
data/README.md
CHANGED
@@ -179,23 +179,71 @@ Matrix Decomposition
|
|
179
179
|
|
180
180
|
A mathematical construct to represent rotations in 3d space.
|
181
181
|
|
182
|
+
Quaternions support all the basic math operations.
|
183
|
+
|
184
|
+
Addition
|
185
|
+
```
|
186
|
+
quat_a + quat_b
|
187
|
+
```
|
188
|
+
Subtraction
|
189
|
+
```
|
190
|
+
quat_a - quat_b
|
191
|
+
```
|
182
192
|
Quaternion Multiplication
|
183
193
|
```
|
184
194
|
quat_a * quat_b
|
185
195
|
```
|
196
|
+
Scalar Multiplication
|
197
|
+
```
|
198
|
+
quat * scalar
|
199
|
+
```
|
200
|
+
Scalar Division
|
201
|
+
```
|
202
|
+
quat / scalar
|
203
|
+
```
|
186
204
|
Getting axis and angle
|
187
205
|
```
|
188
206
|
quat.axis
|
189
|
-
quat.angle
|
207
|
+
quat.angle #returns angle in radians
|
208
|
+
quat.angle_degrees #returns angle in degrees
|
190
209
|
```
|
191
210
|
Converting to a matrix
|
192
211
|
```
|
193
212
|
quat.to_matrix
|
194
213
|
```
|
214
|
+
|
215
|
+
Additional quaternion operations
|
216
|
+
Magnitude
|
217
|
+
```
|
218
|
+
quat.length
|
219
|
+
```
|
220
|
+
Squared Magnitude
|
221
|
+
```
|
222
|
+
quat.length_squared
|
223
|
+
```
|
224
|
+
Normalize
|
225
|
+
```
|
226
|
+
quat.normalize #returns a normalized version of the quaternion
|
227
|
+
quat.normalize! #normalizes the quaternion in place
|
228
|
+
```
|
229
|
+
Inverse
|
230
|
+
```
|
231
|
+
quat.inverse #returns inverse of quaternion
|
232
|
+
```
|
233
|
+
Conjugate
|
234
|
+
```
|
235
|
+
quat.conjugate
|
236
|
+
```
|
237
|
+
Dot product
|
238
|
+
```
|
239
|
+
quat.dot
|
240
|
+
```
|
241
|
+
|
195
242
|
Constructors
|
196
243
|
```
|
197
244
|
Geo3d::Quaternion.from_axis rotation_axis, radians #returns a quaternion from an axis and angle
|
198
245
|
Geo3d::Quaternion.from_matrix m #returns a quaternion from a rotation matrix
|
246
|
+
Geo3d::Quaternion.identity #returns the identity quaternion
|
199
247
|
|
200
248
|
```
|
201
249
|
|
data/Rakefile
CHANGED
data/geo3d.gemspec
CHANGED
data/lib/geo3d.rb
CHANGED
data/lib/geo3d/version.rb
CHANGED
data/lib/matrix.rb
CHANGED
@@ -54,6 +54,32 @@ module Geo3d
|
|
54
54
|
send (%w{_11 _12 _13 _14 _21 _22 _23 _24 _31 _32 _33 _34 _41 _42 _43 _44}[4*x + y] + '=').to_sym, v
|
55
55
|
end
|
56
56
|
|
57
|
+
def row i
|
58
|
+
if i >= 0 && i <= 3
|
59
|
+
Vector.new self[0, i], self[1, i], self[2, i], self[3, i]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def col i
|
64
|
+
if i >= 0 && i <= 3
|
65
|
+
Vector.new self[i, 0], self[i, 1], self [i, 2], self[i, 3]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def set_row i, v
|
70
|
+
self[0, i] = v.x
|
71
|
+
self[1, i] = v.y
|
72
|
+
self[2, i] = v.z
|
73
|
+
self[3, i] = v.w
|
74
|
+
end
|
75
|
+
|
76
|
+
def set_col i, v
|
77
|
+
self[i, 0] = v.x
|
78
|
+
self[i, 1] = v.y
|
79
|
+
self[i, 2] = v.z
|
80
|
+
self[i, 3] = v.w
|
81
|
+
end
|
82
|
+
|
57
83
|
def == m
|
58
84
|
a = to_a
|
59
85
|
b = m.to_a
|
@@ -155,10 +181,10 @@ module Geo3d
|
|
155
181
|
elsif Vector == v.class
|
156
182
|
vec = v
|
157
183
|
transformed_vector = Vector.new
|
158
|
-
transformed_vector.x = _11 * vec.x + _21 * vec.y + _31 * vec.z + _41
|
159
|
-
transformed_vector.y = _12 * vec.x + _22 * vec.y + _32 * vec.z + _42
|
160
|
-
transformed_vector.z = _13 * vec.x + _23 * vec.y + _33 * vec.z + _43
|
161
|
-
transformed_vector.w = _14 * vec.x + _24 * vec.y + _34 * vec.z + _44
|
184
|
+
transformed_vector.x = _11 * vec.x + _21 * vec.y + _31 * vec.z + _41 * vec.w
|
185
|
+
transformed_vector.y = _12 * vec.x + _22 * vec.y + _32 * vec.z + _42 * vec.w
|
186
|
+
transformed_vector.z = _13 * vec.x + _23 * vec.y + _33 * vec.z + _43 * vec.w
|
187
|
+
transformed_vector.w = _14 * vec.x + _24 * vec.y + _34 * vec.z + _44 * vec.w
|
162
188
|
return transformed_vector
|
163
189
|
else
|
164
190
|
scalar = v
|
@@ -212,12 +238,7 @@ module Geo3d
|
|
212
238
|
end
|
213
239
|
|
214
240
|
def transform_coord vec
|
215
|
-
|
216
|
-
transformed_vector = self * vec
|
217
|
-
transformed_vector.x /= norm
|
218
|
-
transformed_vector.y /= norm
|
219
|
-
transformed_vector.z /= norm
|
220
|
-
transformed_vector
|
241
|
+
self * Vector.new( vec.x, vec.y, vec.z, 1.0 )
|
221
242
|
end
|
222
243
|
|
223
244
|
def transform vec
|
@@ -348,9 +369,9 @@ module Geo3d
|
|
348
369
|
|
349
370
|
|
350
371
|
# calculate matrix inverse
|
351
|
-
|
372
|
+
inverse_det = 1.0/det
|
352
373
|
for j in 0..15
|
353
|
-
dst[j] *=
|
374
|
+
dst[j] *= inverse_det
|
354
375
|
end
|
355
376
|
|
356
377
|
inverted_matrix = self.class.new *dst
|
@@ -402,6 +423,10 @@ module Geo3d
|
|
402
423
|
puts "_44: #{_44}\n"
|
403
424
|
end
|
404
425
|
|
426
|
+
def to_s
|
427
|
+
(0..3).to_a.map{ |i| row(i).to_s}.join "\n"
|
428
|
+
end
|
429
|
+
|
405
430
|
def self.perspective_fov_rh fovy, aspect, zn, zf
|
406
431
|
fovy = fovy.to_f
|
407
432
|
aspect = aspect.to_f
|
@@ -533,6 +558,7 @@ module Geo3d
|
|
533
558
|
end
|
534
559
|
|
535
560
|
def self.reflection reflection_plane
|
561
|
+
reflection_plane = Geo3d::Vector.new *reflection_plane.to_a
|
536
562
|
reflection_matrix = self.new
|
537
563
|
|
538
564
|
plane_magnitude = Vector.new(reflection_plane.x, reflection_plane.y, reflection_plane.z, 0).length
|
@@ -566,6 +592,7 @@ module Geo3d
|
|
566
592
|
end
|
567
593
|
|
568
594
|
def self.shadow light_position, plane
|
595
|
+
plane = Geo3d::Vector.new *plane.to_a
|
569
596
|
norm = plane.x * plane.x + plane.y * plane.y + plane.z * plane.z
|
570
597
|
normalized_plane = plane / norm
|
571
598
|
dot = normalized_plane.dot(light_position)
|
data/lib/plane.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
module Geo3d
|
2
|
+
class Plane
|
3
|
+
attr_accessor :a, :b, :c, :d
|
4
|
+
alias :x :a
|
5
|
+
alias :y :b
|
6
|
+
alias :z :c
|
7
|
+
alias :w :d
|
8
|
+
|
9
|
+
def initialize *args
|
10
|
+
@a = 0.0
|
11
|
+
@b = 0.0
|
12
|
+
@c = 0.0
|
13
|
+
@d = 0.0
|
14
|
+
@a = args[0].to_f if args.size > 0
|
15
|
+
@b = args[1].to_f if args.size > 1
|
16
|
+
@c = args[2].to_f if args.size > 2
|
17
|
+
@d = args[3].to_f if args.size > 3
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.from_points pv1, pv2, pv3
|
21
|
+
edge1 = pv2 - pv1
|
22
|
+
edge2 = pv3 - pv1
|
23
|
+
from_point_and_normal pv1, edge1.cross(edge2).normalize
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.from_point_and_normal point, normal
|
27
|
+
point.w = 0
|
28
|
+
self.new normal.x, normal.y, normal.z, -point.dot(normal)
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_a
|
32
|
+
[a,b,c,d]
|
33
|
+
end
|
34
|
+
|
35
|
+
def == p
|
36
|
+
Geo3d::Utils.float_cmp(a, p.a) && Geo3d::Utils.float_cmp(b, p.b) && Geo3d::Utils.float_cmp(c, p.c) && Geo3d::Utils.float_cmp(d, p.d)
|
37
|
+
end
|
38
|
+
|
39
|
+
def != vec
|
40
|
+
!(self == vec)
|
41
|
+
end
|
42
|
+
|
43
|
+
def dot v
|
44
|
+
a * v.x + b * v.y + c * v.z + d * v.w
|
45
|
+
end
|
46
|
+
|
47
|
+
def normalize!
|
48
|
+
norm = Math.sqrt(a*a + b*b + c*c)
|
49
|
+
if norm.zero?
|
50
|
+
@a = 0
|
51
|
+
@b = 0
|
52
|
+
@c = 0
|
53
|
+
@d = 0
|
54
|
+
else
|
55
|
+
@a /= norm
|
56
|
+
@b /= norm
|
57
|
+
@c /= norm
|
58
|
+
@d /= norm
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def normalize
|
63
|
+
p = self.class.new a, b, c, d
|
64
|
+
p.normalize!
|
65
|
+
p
|
66
|
+
end
|
67
|
+
|
68
|
+
def normal
|
69
|
+
Vector.new a, b, c
|
70
|
+
end
|
71
|
+
|
72
|
+
def line_intersection line_start, line_end
|
73
|
+
direction = line_end - line_start
|
74
|
+
|
75
|
+
normal_dot_direction = normal.dot direction
|
76
|
+
|
77
|
+
if (normal_dot_direction.zero?)
|
78
|
+
nil
|
79
|
+
else
|
80
|
+
temp = (d + normal.dot(line_start)) / normal_dot_direction
|
81
|
+
line_start - direction * temp
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def transform matrix, use_inverse_transpose = true
|
86
|
+
matrix = matrix.inverse.transpose if use_inverse_transpose
|
87
|
+
p = self.class.new
|
88
|
+
p.a = dot matrix.row(0)
|
89
|
+
p.b = dot matrix.row(1)
|
90
|
+
p.c = dot matrix.row(2)
|
91
|
+
p.d = dot matrix.row(3)
|
92
|
+
p
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/quaternion.rb
CHANGED
@@ -46,9 +46,7 @@ module Geo3d
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def self.from_axis rotation_axis, radians = 0
|
49
|
-
normalized_rotation_axis = rotation_axis.normalize
|
50
|
-
#const float radians = GeoConvertToRadians( degrees );
|
51
|
-
|
49
|
+
normalized_rotation_axis = rotation_axis.zero_w.normalize
|
52
50
|
q = self.new
|
53
51
|
q.x = Math.sin(radians / 2.0) * normalized_rotation_axis.x
|
54
52
|
q.y = Math.sin(radians / 2.0) * normalized_rotation_axis.y
|
@@ -70,6 +68,8 @@ module Geo3d
|
|
70
68
|
pout.y = (pm._31 - pm._13) / (2.0 * Math.sqrt(trace))
|
71
69
|
pout.z = (pm._12- pm._21) / (2.0 * Math.sqrt(trace))
|
72
70
|
pout.w = Math.sqrt(trace) / 2.0
|
71
|
+
puts "a and pout is #{pout.inspect}"
|
72
|
+
|
73
73
|
return pout
|
74
74
|
end
|
75
75
|
maxi = 0
|
@@ -104,6 +104,7 @@ module Geo3d
|
|
104
104
|
pout.z = 0.25 * s
|
105
105
|
pout.w = (pm._12 - pm._21) / s
|
106
106
|
end
|
107
|
+
puts "b"
|
107
108
|
pout
|
108
109
|
end
|
109
110
|
|
@@ -134,7 +135,7 @@ module Geo3d
|
|
134
135
|
end
|
135
136
|
|
136
137
|
def to_matrix
|
137
|
-
v =
|
138
|
+
v = normalize
|
138
139
|
matrix = Matrix.identity
|
139
140
|
matrix._11 = 1.0 - 2.0 * (v.y * v.y + v.z * v.z)
|
140
141
|
matrix._12 = 2.0 * (v.x * v.y + v.z * v.w)
|
data/lib/vector.rb
CHANGED
@@ -0,0 +1,227 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Geo3d::Matrix do
|
4
|
+
def random_matrix
|
5
|
+
r = Geo3d::Matrix.new
|
6
|
+
for i in 0..3
|
7
|
+
for j in 0..3
|
8
|
+
r[i, j] = rand 10000
|
9
|
+
end
|
10
|
+
end
|
11
|
+
r
|
12
|
+
end
|
13
|
+
|
14
|
+
def random_vector
|
15
|
+
v = Geo3d::Vector.new
|
16
|
+
v.x = rand 10000
|
17
|
+
v.y = rand 10000
|
18
|
+
v.z = rand 10000
|
19
|
+
v.w = rand 10000
|
20
|
+
v
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
it "should default all values to zero" do
|
25
|
+
Geo3d::Matrix.new.to_a.select(&:zero?).size.should == 16
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be able to extract translation component" do
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should be able to extract scaling component" do
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should be able to extract rotation component" do
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should be invertible" do
|
41
|
+
100.times do
|
42
|
+
r = random_matrix
|
43
|
+
(r * r.inverse).identity?.should == true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return the determinant" do
|
48
|
+
[{:matrix => [0.321046, 0.000000, 0.000000, 0.000000, 0.000000, 0.642093, 0.000000, 0.000000, 0.000000, 0.000000, -1.000095, -1.000000, 0.000000, 0.000000, -2.000190, 0.000000], :expected => -0.412322},
|
49
|
+
{:matrix => [1.000000, 0.000000, 0.000000, 0.000000, 0.000000, -1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, -2.000000, 0.000000, 1.000000], :expected => -1},
|
50
|
+
{:matrix => [-0.392804, -0.878379, -0.272314, 0.000000, 0.000000, 0.296115, -0.955152, 0.000000, 0.919622, -0.375187, -0.116315, 0.000000, -2.366064, 1.411711, 2.531564, 1.000000], :expected => 1}].each do |data|
|
51
|
+
data[:matrix].size.should == 16
|
52
|
+
Geo3d::Utils.float_cmp( Geo3d::Matrix.new(*data[:matrix]).determinant, data[:expected] ).should == true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be transposable" do
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should have an identity constructor" do
|
61
|
+
identity = Geo3d::Matrix.identity
|
62
|
+
identity.identity?.should == true
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should have a right handed perspective projection constructor" do
|
66
|
+
[{:fovy => 2, :aspect => 2, :zn => 2, :zf => 21000, :expected => [0.321046, 0.000000, 0.000000, 0.000000, 0.000000, 0.642093, 0.000000, 0.000000, 0.000000, 0.000000, -1.000095, -1.000000, 0.000000, 0.000000, -2.000190, 0.000000]}].each do |data|
|
67
|
+
matrix = Geo3d::Matrix.perspective_fov_rh data[:fovy], data[:aspect], data[:zn], data[:zf]
|
68
|
+
data[:expected].size.should == 16
|
69
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
70
|
+
matrix.should == expected
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
it "should have a left handed perspective projection constructor" do
|
76
|
+
[{:fovy => 2, :aspect => 2, :zn => 2, :zf => 21000, :expected => [0.321046, 0.000000, 0.000000, 0.000000, 0.000000, 0.642093, 0.000000, 0.000000, 0.000000, 0.000000, 1.000095, 1.000000, 0.000000, 0.000000, -2.000190, 0.000000]}].each do |data|
|
77
|
+
matrix = Geo3d::Matrix.perspective_fov_lh data[:fovy], data[:aspect], data[:zn], data[:zf]
|
78
|
+
data[:expected].size.should == 16
|
79
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
80
|
+
matrix.should == expected
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
it "should have a right handed orthographic projection constructor" do
|
86
|
+
[{:l => -100, :r => 100, :b => -200, :t => 200, :zn => 1, :zf => 2000, :expected => [0.010000, 0.000000, 0.000000, 0.000000, 0.000000, 0.005000, 0.000000, 0.000000, 0.000000, 0.000000, -0.000500, 0.000000, -0.000000, -0.000000, -0.000500, 1.000000]}].each do |data|
|
87
|
+
matrix = Geo3d::Matrix.ortho_off_center_rh data[:l], data[:r], data[:b], data[:t], data[:zn], data[:zf]
|
88
|
+
data[:expected].size.should == 16
|
89
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
90
|
+
matrix.should == expected
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
it "should have a left handed orthographic projection constructor" do
|
96
|
+
[{:l => -100, :r => 100, :b => -200, :t => 200, :zn => 1, :zf => 2000, :expected => [0.010000, 0.000000, 0.000000, 0.000000, 0.000000, 0.005000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000500, 0.000000, -0.000000, -0.000000, -0.000500, 1.000000]}].each do |data|
|
97
|
+
matrix = Geo3d::Matrix.ortho_off_center_lh data[:l], data[:r], data[:b], data[:t], data[:zn], data[:zf]
|
98
|
+
data[:expected].size.should == 16
|
99
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
100
|
+
matrix.should == expected
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
it "should have a right handed view constructor" do
|
106
|
+
[{:eye => [1, 2, 3], :focus => [200, 700, 88], :up => [0, 1, 0], :expected => [-0.392804, -0.878379, -0.272314, 0.000000, 0.000000, 0.296115, -0.955152, 0.000000, 0.919622, -0.375187, -0.116315, 0.000000, -2.366064, 1.411711, 2.531564, 1.000000]}].each do |data|
|
107
|
+
matrix = Geo3d::Matrix.look_at_rh Geo3d::Vector.new(*data[:eye]), Geo3d::Vector.new(*data[:focus]), Geo3d::Vector.new(*data[:up])
|
108
|
+
data[:expected].size.should == 16
|
109
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
110
|
+
matrix.should == expected
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
it "should have a left handed view constructor" do
|
116
|
+
[{:eye => [1, 2, 3], :focus => [200, 700, 88], :up => [0, 1, 0], :expected => [0.392804, -0.878379, 0.272314, 0.000000, 0.000000, 0.296115, 0.955152, 0.000000, -0.919622, -0.375187, 0.116315, 0.000000, 2.366064, 1.411711, -2.531564, 1.000000]}].each do |data|
|
117
|
+
matrix = Geo3d::Matrix.look_at_lh Geo3d::Vector.new(*data[:eye]), Geo3d::Vector.new(*data[:focus]), Geo3d::Vector.new(*data[:up])
|
118
|
+
data[:expected].size.should == 16
|
119
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
120
|
+
matrix.should == expected
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should have a translation constructor" do
|
125
|
+
10.times do
|
126
|
+
random_translation = random_vector
|
127
|
+
matrix = Geo3d::Matrix.translation random_translation.x, random_translation.y, random_translation.z
|
128
|
+
10.times do
|
129
|
+
random_vec = random_vector.one_w
|
130
|
+
Geo3d::Utils.float_cmp((matrix * random_vec).x, random_vec.x + random_translation.x).should == true
|
131
|
+
Geo3d::Utils.float_cmp((matrix * random_vec).y, random_vec.y + random_translation.y).should == true
|
132
|
+
Geo3d::Utils.float_cmp((matrix * random_vec).z, random_vec.z + random_translation.z).should == true
|
133
|
+
Geo3d::Utils.float_cmp((matrix * random_vec).w, 1).should == true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should have a scaling constructor" do
|
139
|
+
10.times do
|
140
|
+
random_scaling = random_vector
|
141
|
+
matrix = Geo3d::Matrix.scaling random_scaling.x, random_scaling.y, random_scaling.z
|
142
|
+
10.times do
|
143
|
+
random_vec = random_vector.one_w
|
144
|
+
Geo3d::Utils.float_cmp((matrix * random_vec).x, random_vec.x * random_scaling.x).should == true
|
145
|
+
Geo3d::Utils.float_cmp((matrix * random_vec).y, random_vec.y * random_scaling.y).should == true
|
146
|
+
Geo3d::Utils.float_cmp((matrix * random_vec).z, random_vec.z * random_scaling.z).should == true
|
147
|
+
Geo3d::Utils.float_cmp((matrix * random_vec).w, 1).should == true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
it "should have an x-axis rotation constructor" do
|
154
|
+
[{:angle => 1, :expected => [1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.540302, 0.841471, 0.000000, 0.000000, -0.841471, 0.540302, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000]},
|
155
|
+
{:angle => 3.2, :expected => [1.000000, 0.000000, 0.000000, 0.000000, 0.000000, -0.998295, -0.058374, 0.000000, 0.000000, 0.058374, -0.998295, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000]}].each do |data|
|
156
|
+
matrix = Geo3d::Matrix.rotation_x data[:angle]
|
157
|
+
data[:expected].size.should == 16
|
158
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
159
|
+
matrix.should == expected
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should have an y-axis rotation constructor" do
|
164
|
+
[{:angle => 1, :expected => [0.540302, 0.000000, -0.841471, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.841471, 0.000000, 0.540302, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000]},
|
165
|
+
{:angle => 3.2, :expected => [-0.998295, 0.000000, 0.058374, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, -0.058374, 0.000000, -0.998295, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000]}].each do |data|
|
166
|
+
matrix = Geo3d::Matrix.rotation_y data[:angle]
|
167
|
+
data[:expected].size.should == 16
|
168
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
169
|
+
matrix.should == expected
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should have a z-axis rotation constructor" do
|
174
|
+
[{:angle => 1, :expected => [0.540302, 0.841471, 0.000000, 0.000000, -0.841471, 0.540302, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000]},
|
175
|
+
{:angle => 3.2, :expected => [-0.998295, -0.058374, 0.000000, 0.000000, 0.058374, -0.998295, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000]}].each do |data|
|
176
|
+
matrix = Geo3d::Matrix.rotation_z data[:angle]
|
177
|
+
data[:expected].size.should == 16
|
178
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
179
|
+
matrix.should == expected
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should have an arbitrary axis rotation constructor" do
|
184
|
+
[{:axis => [1, 1, 0], :angle => 88.7, :expected => [0.870782, 0.129218, -0.474385, 0.000000, 0.129218, 0.870782, 0.474385, 0.000000, 0.474385, -0.474385, 0.741564, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000]}].each do |data|
|
185
|
+
matrix = Geo3d::Matrix.rotation Geo3d::Vector.new(*data[:axis]), data[:angle]
|
186
|
+
data[:expected].size.should == 16
|
187
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
188
|
+
matrix.should == expected
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should have a reflection constructor" do
|
193
|
+
[{:plane => [0, 1, 0, 0], :expected => [1.000000, 0.000000, 0.000000, 0.000000, 0.000000, -1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000]},
|
194
|
+
{:plane => [0, 1, 0, 1], :expected => [1.000000, 0.000000, 0.000000, 0.000000, 0.000000, -1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, -2.000000, 0.000000, 1.000000]}].each do |data|
|
195
|
+
matrix = Geo3d::Matrix.reflection Geo3d::Plane.new(*data[:plane])
|
196
|
+
data[:expected].size.should == 16
|
197
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
198
|
+
matrix.should == expected
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should have a shadow constructor" do
|
203
|
+
[{:plane => [0, 1, 0, 1], :light_pos => [0, 700, 0, 1], :expected => [701.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, -1.000000, 0.000000, 0.000000, 701.000000, 0.000000, 0.000000, -700.000000, 0.000000, 700.000000]}].each do |data|
|
204
|
+
matrix = Geo3d::Matrix.shadow Geo3d::Vector.new(*data[:light_pos]), Geo3d::Plane.new(*data[:plane])
|
205
|
+
data[:expected].size.should == 16
|
206
|
+
expected = Geo3d::Matrix.new *data[:expected]
|
207
|
+
matrix.should == expected
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
it "multiplying a matrix by the identity matrix should result in the same matrix" do
|
212
|
+
identity = Geo3d::Matrix.identity
|
213
|
+
10.times do
|
214
|
+
r = random_matrix
|
215
|
+
(r * identity).should == r
|
216
|
+
(identity * r).should == r
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should transform vectors" do
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should multiply with other matrices" do
|
225
|
+
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Geo3d::Plane do
|
4
|
+
it "should default all values to zero" do
|
5
|
+
p = Geo3d::Plane.new
|
6
|
+
p.a.zero?.should == true
|
7
|
+
p.b.zero?.should == true
|
8
|
+
p.c.zero?.should == true
|
9
|
+
p.d.zero?.should == true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should construct from a point and a normal" do
|
13
|
+
[{:point => [0, 0, 0], :normal => [0, 1, 0], :expected => [0, 1, 0, 0]},
|
14
|
+
{:point => [1, 2, 3], :normal => [1, 1, 1], :expected => [1, 1, 1, -6]},
|
15
|
+
{:point => [221, 772, 33], :normal => [2, 0, 1], :expected => [2, 0, 1, -475]},
|
16
|
+
{:point => [999, 888, 777], :normal => [-1, 3, 0], :expected => [-1, 3, 0, -1665]}].each do |data|
|
17
|
+
plane = Geo3d::Plane.from_point_and_normal Geo3d::Vector.new(*data[:point]), Geo3d::Vector.new(*data[:normal])
|
18
|
+
expected = Geo3d::Plane.new *data[:expected]
|
19
|
+
plane.should == expected
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should construct from points" do
|
24
|
+
[{:a => [1, 1, 1], :b => [2, 2, 2], :c => [3, 3, 3], :expected => [0, 0, 0, 0]},
|
25
|
+
{:a => [-1.5, 1.5, 3.0, 0], :b => [1.5, 1.5, 3.0, 0], :c => [-1.5, -1.5, 3.0, 0], :expected => [0, 0, -1, 3]},
|
26
|
+
{:a => [10, 1, 33], :b => [1, 11, 3], :c => [-1, -1, 3], :expected => [-0.930808, 0.155135, 0.330954, -1.768534]}].each do |data|
|
27
|
+
plane = Geo3d::Plane.from_points Geo3d::Vector.new(*data[:a]), Geo3d::Vector.new(*data[:b]), Geo3d::Vector.new(*data[:c])
|
28
|
+
expected = Geo3d::Plane.new *data[:expected]
|
29
|
+
plane.should == expected
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should support dot products with vectors" do
|
34
|
+
[{:plane => [1, 1, 1, 1], :vector => [2, 2, 2, 2], :expected => 8},
|
35
|
+
{:plane => [0, 1, 0, -99], :vector => [0, -42, 2, 52], :expected => -5190},
|
36
|
+
{:plane => [91, -2731, 1, 123], :vector => [2, 7, -9, 2], :expected => -18698},
|
37
|
+
].each do |data|
|
38
|
+
plane = Geo3d::Plane.new *data[:plane]
|
39
|
+
vector = Geo3d::Vector.new *data[:vector]
|
40
|
+
Geo3d::Utils.float_cmp(plane.dot(vector), data[:expected]).should == true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should be normalizable" do
|
45
|
+
[{:plane => [0, 0, -1, 3], :expected => [0, 0, -1, 3]},
|
46
|
+
{:plane => [11, 11, -7, 3], :expected => [0.644831, 0.644831, -0.410347, 0.175863]},
|
47
|
+
{:plane => [-56, 23, 923, 9], :expected => [-0.060542, 0.024865, 0.997856, 0.009730]}].each do |data|
|
48
|
+
plane = Geo3d::Plane.new(*data[:plane]).normalize
|
49
|
+
expected = Geo3d::Plane.new *data[:expected]
|
50
|
+
plane.should == expected
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be able to detect line intersections" do
|
55
|
+
[{:plane => [0,0,-1,3], :line_start => [1,1,1,0], :line_end => [2,2,2,0], :expected => [3,3,3,0]},
|
56
|
+
{:plane => [0,0,-1,3], :line_start => [1,1,1,1], :line_end => [2,2,2,1], :expected => [3,3,3,1]},
|
57
|
+
{:plane => [0,1,0,-30], :line_start => [1,0,0,0], :line_end => [2,0,0,0], :expected => nil},
|
58
|
+
{:plane => [0,1,0,-30], :line_start => [1,1,0,0], :line_end => [2,0,0,0], :expected => [-28,30,0,0]},
|
59
|
+
{:plane => [0,1,0,-30], :line_start => [1,1,0,1], :line_end => [2,0,0,1], :expected => [-28,30,0,1]}].each do |data|
|
60
|
+
plane = Geo3d::Plane.new *data[:plane]
|
61
|
+
line_start = Geo3d::Vector.new *data[:line_start]
|
62
|
+
line_end = Geo3d::Vector.new *data[:line_end]
|
63
|
+
if data[:expected]
|
64
|
+
expected = Geo3d::Vector.new *data[:expected]
|
65
|
+
else
|
66
|
+
expected = nil
|
67
|
+
end
|
68
|
+
plane.line_intersection(line_start, line_end).should == expected
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should be transformable" do
|
73
|
+
test_transform = ->(matrix, plane,expected) do
|
74
|
+
plane.transform(matrix).should == expected
|
75
|
+
end
|
76
|
+
test_transform.call Geo3d::Matrix.translation(0,5,0), Geo3d::Plane.new(0,1,0,0), Geo3d::Plane.new(0,1,0,-5)
|
77
|
+
test_transform.call Geo3d::Matrix.translation(0,5,0), Geo3d::Plane.new(1,1,1,1), Geo3d::Plane.new(1,1,1,-4)
|
78
|
+
test_transform.call Geo3d::Matrix.rotation_x(1), Geo3d::Plane.new(1,1,1,1), Geo3d::Plane.new(1.000000, -0.301169, 1.381773, 1.000000)
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Geo3d::Quaternion do
|
4
|
+
it "should default all values to zero" do
|
5
|
+
q = Geo3d::Quaternion.new
|
6
|
+
q.x.zero?.should == true
|
7
|
+
q.y.zero?.should == true
|
8
|
+
q.z.zero?.should == true
|
9
|
+
q.w.zero?.should == true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be constructable from an axis and angle" do
|
13
|
+
[{:axis => [0, 1, 0], :angle => 1, :expected => [0.000000, 0.479426, 0.000000, 0.877583]},
|
14
|
+
{:axis => [0, -1, 0], :angle => 1, :expected => [0.000000, -0.479426, 0.000000, 0.877583]},
|
15
|
+
{:axis => [0, 1, 0], :angle => -1, :expected => [0.000000, -0.479426, 0.000000, 0.877583]},
|
16
|
+
{:axis => [0, 1, 0], :angle => -6, :expected => [-0.000000, -0.141120, -0.000000, -0.989992]},
|
17
|
+
{:axis => [-213, 133, 22, -232], :angle => -3432, :expected => [0.538065, -0.335975, -0.055575, 0.771050]}].each do |data|
|
18
|
+
Geo3d::Quaternion.from_axis(Geo3d::Vector.new(*data[:axis]), data[:angle]).should == Geo3d::Quaternion.new(*data[:expected])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be constructable from a rotation matrix" do
|
23
|
+
Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_x 1).should == Geo3d::Quaternion.new(0.479426, 0.000000, -0.000000, 0.877583)
|
24
|
+
Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_y 1).should == Geo3d::Quaternion.new(-0.000000, 0.479426, -0.000000, 0.877583)
|
25
|
+
Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_z 1).should == Geo3d::Quaternion.new(-0.000000, 0.000000, 0.479426, 0.877583)
|
26
|
+
Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_x 3.2).should == Geo3d::Quaternion.new(0.999574, 0.000000, 0.000000, -0.029200)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be able to construct as the identity quaternion" do
|
30
|
+
q = Geo3d::Quaternion.identity
|
31
|
+
q.should == Geo3d::Quaternion.new(0, 0, 0, 1)
|
32
|
+
q.identity?.should == true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be able to convert to a rotation matrix" do
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return axis of rotation" do
|
40
|
+
for i in 0..10000
|
41
|
+
angle = 0.1 * i + 0.1
|
42
|
+
# puts "angle is #{angle}"
|
43
|
+
#Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_x angle).axis.should == Geo3d::Vector.new(1, 0, 0)
|
44
|
+
#Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_y angle).axis.should == Geo3d::Vector.new(0, 1, 0)
|
45
|
+
#Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_z angle).axis.should == Geo3d::Vector.new(0, 0, 1)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return rotation amount as angle" do
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return conjugate" do
|
54
|
+
[{:quaternion => [1, 1, 1, 1], :expected => [-1, -1, -1, 1]}].each do |data|
|
55
|
+
quaternion = Geo3d::Quaternion.new *data[:quaternion]
|
56
|
+
expected = Geo3d::Quaternion.new *data[:expected]
|
57
|
+
quaternion.conjugate.should == expected
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return inverse" do
|
62
|
+
[{:quaternion => [1, 1, 1, 1], :expected => [-0.250000, -0.250000, -0.250000, 0.250000]},
|
63
|
+
{:quaternion => [-1, -1, -1, -1], :expected => [0.250000, 0.250000, 0.250000, -0.250000]}].each do |data|
|
64
|
+
quaternion = Geo3d::Quaternion.new *data[:quaternion]
|
65
|
+
expected = Geo3d::Quaternion.new *data[:expected]
|
66
|
+
quaternion.inverse.should == expected
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should support dot products with other quaternions" do
|
71
|
+
[{:a => [1, 1, 1, 1], :b => [2, 2, 2, 2], :expected => 8},
|
72
|
+
{:a => [0, 1, 0, -99], :b => [0, -42, 2, 52], :expected => -5190},
|
73
|
+
{:a => [91, -2731, 1, 123], :b => [2, 7, -9, 2], :expected => -18698},
|
74
|
+
].each do |data|
|
75
|
+
a = Geo3d::Quaternion.new *data[:a]
|
76
|
+
b = Geo3d::Quaternion.new *data[:b]
|
77
|
+
Geo3d::Utils.float_cmp(a.dot(b), data[:expected]).should == true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should return length" do
|
82
|
+
[{:quaternion => [0, 0, -1, 3], :expected => 3.162278},
|
83
|
+
{:quaternion => [11, 11, -7, 3], :expected => 17.320509},
|
84
|
+
{:quaternion => [-56, 23, 923, 9], :expected => 925.027039}].each do |data|
|
85
|
+
quaternion = Geo3d::Quaternion.new *data[:quaternion]
|
86
|
+
expected = data[:expected]
|
87
|
+
Geo3d::Utils.float_cmp(quaternion.length, expected).should == true
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return length squared" do
|
92
|
+
[{:quaternion => [0, 0, -1, 3], :expected => 10},
|
93
|
+
{:quaternion => [11, 11, -7, 3], :expected => 300},
|
94
|
+
{:quaternion => [-56, 23, 923, 9], :expected => 855675}].each do |data|
|
95
|
+
quaternion = Geo3d::Quaternion.new *data[:quaternion]
|
96
|
+
expected = data[:expected]
|
97
|
+
Geo3d::Utils.float_cmp(quaternion.length_squared, expected).should == true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should be normalizable" do
|
102
|
+
[{:quaternion => [0, 0, -1, 3], :expected => [0, 0, -0.316228, 0.948683]},
|
103
|
+
{:quaternion => [11, 11, -7, 3], :expected => [0.635085, 0.635085, -0.404145, 0.173205]},
|
104
|
+
{:quaternion => [-56, 23, 923, 9], :expected => [-0.060539, 0.024864, 0.997809, 0.009729]}].each do |data|
|
105
|
+
quaternion = Geo3d::Quaternion.new(*data[:quaternion]).normalize
|
106
|
+
expected = Geo3d::Quaternion.new *data[:expected]
|
107
|
+
quaternion.should == expected
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
#todo: add tests for quaternion interpolation
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Geo3d::Vector do
|
4
|
+
it "should default all values to zero" do
|
5
|
+
v = Geo3d::Vector.new
|
6
|
+
v.x.zero?.should == true
|
7
|
+
v.y.zero?.should == true
|
8
|
+
v.z.zero?.should == true
|
9
|
+
v.w.zero?.should == true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should support dot products with other vectors" do
|
13
|
+
[{:a => [1, 1, 1, 1], :b => [2, 2, 2, 2], :expected => 8},
|
14
|
+
{:a => [0, 1, 0, -99], :b => [0, -42, 2, 52], :expected => -5190},
|
15
|
+
{:a => [91, -2731, 1, 123], :b => [2, 7, -9, 2], :expected => -18698},
|
16
|
+
].each do |data|
|
17
|
+
a = Geo3d::Vector.new *data[:a]
|
18
|
+
b = Geo3d::Vector.new *data[:b]
|
19
|
+
Geo3d::Utils.float_cmp(a.dot(b), data[:expected]).should == true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should support cross products with other vectors" do
|
24
|
+
[{:a => [1,0,0,0], :b => [0,1,0,0], :expected => [0,0,1,0] },
|
25
|
+
{:a => [1,0,0,1], :b => [0,1,0,1], :expected => [0,0,1,0] },
|
26
|
+
{:a => [1,1,1,1], :b => [1,1,1,1], :expected => [0,0,0,0] },
|
27
|
+
{:a => [2,99,6,0], :b => [-11,-91,77,0], :expected => [8169.000000, -220.000000, 907.000000, 0.000000] }].each do |data|
|
28
|
+
a = Geo3d::Vector.new *data[:a]
|
29
|
+
b = Geo3d::Vector.new *data[:b]
|
30
|
+
expected = Geo3d::Vector.new *data[:expected]
|
31
|
+
a.cross(b).should == expected
|
32
|
+
b.cross(a).should == -expected
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return length" do
|
37
|
+
[{:vector => [0, 0, -1, 3], :expected => 3.162278},
|
38
|
+
{:vector => [11, 11, -7, 3], :expected => 17.320509},
|
39
|
+
{:vector => [-56, 23, 923, 9], :expected => 925.027039}].each do |data|
|
40
|
+
vector = Geo3d::Vector.new *data[:vector]
|
41
|
+
expected = data[:expected]
|
42
|
+
Geo3d::Utils.float_cmp(vector.length, expected).should == true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should return length squared" do
|
47
|
+
[{:vector => [0, 0, -1, 3], :expected => 10},
|
48
|
+
{:vector => [11, 11, -7, 3], :expected => 300},
|
49
|
+
{:vector => [-56, 23, 923, 9], :expected => 855675}].each do |data|
|
50
|
+
vector = Geo3d::Vector.new *data[:vector]
|
51
|
+
expected = data[:expected]
|
52
|
+
Geo3d::Utils.float_cmp(vector.length_squared, expected).should == true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be normalizable" do
|
57
|
+
[{:vector => [0, 0, -1, 3], :expected => [0, 0, -0.316228, 0.948683]},
|
58
|
+
{:vector => [11, 11, -7, 3], :expected => [0.635085, 0.635085, -0.404145, 0.173205]},
|
59
|
+
{:vector => [-56, 23, 923, 9], :expected => [-0.060539, 0.024864, 0.997809, 0.009729]}].each do |data|
|
60
|
+
vector = Geo3d::Vector.new(*data[:vector]).normalize
|
61
|
+
expected = Geo3d::Vector.new *data[:expected]
|
62
|
+
vector.should == expected
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should be able to linearly interpolate" do
|
67
|
+
[{:a => [0,0,0,0], :b => [1,1,1,1], :interpolate_fraction => 0.5, :expected => [0.5, 0.5, 0.5, 0.5]},
|
68
|
+
{:a => [23,-3,425,-332], :b => [-22,-45443,886,122], :interpolate_fraction => 0.21234433, :expected => [13.444505, -9651.926758, 522.890747, -235.595673]}].each do |data|
|
69
|
+
a = Geo3d::Vector.new *data[:a]
|
70
|
+
b = Geo3d::Vector.new *data[:b]
|
71
|
+
expected = Geo3d::Vector.new *data[:expected]
|
72
|
+
s = data[:interpolate_fraction]
|
73
|
+
a.lerp( b, s).should == expected
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'geo3d'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geo3d
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Misha Conway
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
description: Library for common 3d graphics vector and matrix operations
|
42
56
|
email:
|
43
57
|
- MishaAConway@gmail.com
|
@@ -54,9 +68,15 @@ files:
|
|
54
68
|
- lib/geo3d.rb
|
55
69
|
- lib/geo3d/version.rb
|
56
70
|
- lib/matrix.rb
|
71
|
+
- lib/plane.rb
|
57
72
|
- lib/quaternion.rb
|
58
73
|
- lib/utils.rb
|
59
74
|
- lib/vector.rb
|
75
|
+
- spec/lib/matrix_spec.rb
|
76
|
+
- spec/lib/plane_spec.rb
|
77
|
+
- spec/lib/quaternion_spec.rb
|
78
|
+
- spec/lib/vector_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
60
80
|
homepage: https://github.com/MishaConway/geo3d
|
61
81
|
licenses:
|
62
82
|
- MIT
|
@@ -81,4 +101,9 @@ rubygems_version: 2.1.11
|
|
81
101
|
signing_key:
|
82
102
|
specification_version: 4
|
83
103
|
summary: Library for common 3d graphics vector and matrix operations
|
84
|
-
test_files:
|
104
|
+
test_files:
|
105
|
+
- spec/lib/matrix_spec.rb
|
106
|
+
- spec/lib/plane_spec.rb
|
107
|
+
- spec/lib/quaternion_spec.rb
|
108
|
+
- spec/lib/vector_spec.rb
|
109
|
+
- spec/spec_helper.rb
|