geo3d 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d8f3862b698223418bf989a4cce3c0dc45c74aec
4
- data.tar.gz: 8df829279ef53a7003215b5aeb18c3a4127af036
3
+ metadata.gz: 96291332d1c108ec9adeee6a9ce2deb8244dac5e
4
+ data.tar.gz: 95de37c194cda4d9462e9cd13accad6e4da44acf
5
5
  SHA512:
6
- metadata.gz: ef96a2ee15de30cc29f298cac21258a45c764d8895837525b172280973f89bf905ef7ceb5af4240471b5894c890e57aed57856e2c8337aca7472a47411462e66
7
- data.tar.gz: 79c5f1a2776f2647d139f7de64f4fcc148a242bfe0bf9e9c0db3ba0357cda31d522114da94adf2cfd20581080028b36577c67bc814296b36c0d8428a93552518
6
+ metadata.gz: f7fa1397c73eb27f538fac995e5c5ce422059342968c51cf12ddc3653994fe0615ba893fc50fdb51a3ba76ca26815c2de1a1c2e40ccda50efb24fcecfa916062
7
+ data.tar.gz: 0670ed712274a93812c7d304c194342edb08560ae6152afb0842fc3b617239576268e0329b92ddb3594a267bd5279c3acd6ad7fb4d6f3474a2e655db5887a71c
data/README.md CHANGED
@@ -119,10 +119,11 @@ Inverse
119
119
  ```
120
120
  mat.inverse #returns inverse of matrix
121
121
  mat.inverse true #returns inverse of matrix along with its determinant
122
+ mat.determinant #returns the determinant
122
123
  ```
123
124
  Transpose
124
125
  ```
125
- mat.tranpose
126
+ mat.transpose
126
127
  ```
127
128
 
128
129
  Common matrix constructors
@@ -174,6 +175,37 @@ Matrix Decomposition
174
175
  matrix.rotation_component
175
176
  ```
176
177
 
178
+ ## Plane
179
+
180
+ Represents a 2d surface in three dimensional space. Has the attributes a,b,c,d that mirror the standard plane equations.
181
+
182
+ There are a couple constructors to build planes from points and normals.
183
+ ````
184
+ Geo3d::Plane.from_points pv1, pv2, pv3 #builds a plane from known points on the plane
185
+ Geo3d::Plane.from_point_and_normal point, normal #builds a plane from it's normal and a known point
186
+ ````
187
+
188
+ Additional plane operations
189
+
190
+ Dot product
191
+ ```
192
+ plane.dot v #v can be a vector or another plane
193
+ ```
194
+ Normalize
195
+ ```
196
+ plane.normalize #returns a normalized version of the plane
197
+ plane.normalize! #normalizes the plane in place
198
+ ```
199
+ Line intersection
200
+ ```
201
+ plane.line_intersection line_start, line_end #returns the intersection of the line onto the plane
202
+ ````
203
+ Plane Transformation
204
+ ````
205
+ #transforms plane by the matrix, if use_inverse_transpose is set to true, the plane will be transformed by the inverse transpose of matrix
206
+ plane.transform matrix, use_inverse_transpose = true
207
+ ````
208
+
177
209
 
178
210
  ## Quaternion
179
211
 
data/lib/geo3d/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Geo3d
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
data/lib/matrix.rb CHANGED
@@ -287,6 +287,18 @@ module Geo3d
287
287
  inverse(true).last
288
288
  end
289
289
 
290
+ def trace
291
+ _11 + _22 + _33 + _44
292
+ end
293
+
294
+ def orthogonal?
295
+ inverse == transpose
296
+ end
297
+
298
+ def is_rotation_transform?
299
+ orthogonal? && Geo3d::Utils.float_cmp(determinant, 1.0)
300
+ end
301
+
290
302
  def inverse with_determinant = false
291
303
  mat = to_a
292
304
  dst = Array.new 16
data/lib/quaternion.rb CHANGED
@@ -13,6 +13,10 @@ module Geo3d
13
13
  @w = args[3].to_f if args.size > 3
14
14
  end
15
15
 
16
+ def to_a
17
+ [x,y,z,w]
18
+ end
19
+
16
20
  def x= v
17
21
  @x = v.to_f
18
22
  end
@@ -46,6 +50,7 @@ module Geo3d
46
50
  end
47
51
 
48
52
  def self.from_axis rotation_axis, radians = 0
53
+ radians = Geo3d::Utils.normalize_angle radians #todo: is this cheating?....
49
54
  normalized_rotation_axis = rotation_axis.zero_w.normalize
50
55
  q = self.new
51
56
  q.x = Math.sin(radians / 2.0) * normalized_rotation_axis.x
@@ -62,13 +67,14 @@ module Geo3d
62
67
  def self.from_matrix pm
63
68
  pout = self.new
64
69
 
65
- trace = pm._11 + pm._22 + pm._33 + 1.0
66
- if trace > 0
67
- pout.x = (pm._23 - pm._32) / (2.0 * Math.sqrt(trace))
68
- pout.y = (pm._31 - pm._13) / (2.0 * Math.sqrt(trace))
69
- pout.z = (pm._12- pm._21) / (2.0 * Math.sqrt(trace))
70
- pout.w = Math.sqrt(trace) / 2.0
71
- puts "a and pout is #{pout.inspect}"
70
+ #puts "trace is #{pm.trace}"
71
+ if false && pm.trace > 1.0
72
+ sq_root_of_trace = Math.sqrt pm.trace
73
+ pout.x = (pm._23 - pm._32) / (2.0 * sq_root_of_trace)
74
+ pout.y = (pm._31 - pm._13) / (2.0 * sq_root_of_trace)
75
+ pout.z = (pm._12- pm._21) / (2.0 * sq_root_of_trace)
76
+ pout.w = sq_root_of_trace / 2.0
77
+ #puts "a and pout is #{pout.inspect}"
72
78
 
73
79
  return pout
74
80
  end
@@ -104,7 +110,7 @@ module Geo3d
104
110
  pout.z = 0.25 * s
105
111
  pout.w = (pm._12 - pm._21) / s
106
112
  end
107
- puts "b"
113
+ #puts "b"
108
114
  pout
109
115
  end
110
116
 
@@ -150,17 +156,11 @@ module Geo3d
150
156
  end
151
157
 
152
158
  def axis
153
- q = normalize
154
- v = Vector.new
155
- v.x = q.x / Math.sqrt(1-q.w*q.w)
156
- v.y = q.y / Math.sqrt(1-q.w*q.w)
157
- v.z = q.z / Math.sqrt(1-q.w*q.w)
158
- v
159
+ Vector.new( *(normalize / Math.sin( angle / 2.0 )).to_a ).zero_w
159
160
  end
160
161
 
161
162
  def angle
162
- q = normalize
163
- Math.acos(q.w) * 2.0
163
+ Math.acos(normalize.w) * 2.0
164
164
  end
165
165
 
166
166
  def angle_degrees
data/lib/utils.rb CHANGED
@@ -11,5 +11,18 @@ module Geo3d
11
11
  def self.to_radians degrees
12
12
  degrees * Math::PI / 180.0
13
13
  end
14
+
15
+ def self.normalize_angle radians
16
+ if radians.abs > Math::PI * 2.0
17
+ absolute = radians.abs % (Math::PI * 2.0 )
18
+ if radians < 0
19
+ -absolute
20
+ else
21
+ absolute
22
+ end
23
+ else
24
+ radians
25
+ end
26
+ end
14
27
  end
15
28
  end
@@ -26,15 +26,21 @@ describe Geo3d::Matrix do
26
26
  end
27
27
 
28
28
  it "should be able to extract translation component" do
29
-
29
+ translation = Geo3d::Vector.new 3,-4,6
30
+ matrix = Geo3d::Matrix.translation translation.x, translation.y, translation.z
31
+ matrix.translation_component.should == translation
30
32
  end
31
33
 
32
34
  it "should be able to extract scaling component" do
33
-
35
+ scaling = Geo3d::Vector.new 3,4,6
36
+ matrix = Geo3d::Matrix.scaling scaling.x, scaling.y, scaling.z
37
+ matrix.scaling_component.should == scaling
34
38
  end
35
39
 
36
40
  it "should be able to extract rotation component" do
37
-
41
+ angle = 2.234
42
+ matrix = Geo3d::Matrix.rotation_z angle
43
+ matrix.rotation_component.should == Geo3d::Quaternion.from_axis(Geo3d::Vector.new(0,0,1), angle)
38
44
  end
39
45
 
40
46
  it "should be invertible" do
@@ -157,6 +163,8 @@ describe Geo3d::Matrix do
157
163
  data[:expected].size.should == 16
158
164
  expected = Geo3d::Matrix.new *data[:expected]
159
165
  matrix.should == expected
166
+ matrix.is_rotation_transform?.should == true
167
+ expected.is_rotation_transform?.should == true
160
168
  end
161
169
  end
162
170
 
@@ -167,6 +175,8 @@ describe Geo3d::Matrix do
167
175
  data[:expected].size.should == 16
168
176
  expected = Geo3d::Matrix.new *data[:expected]
169
177
  matrix.should == expected
178
+ matrix.is_rotation_transform?.should == true
179
+ expected.is_rotation_transform?.should == true
170
180
  end
171
181
  end
172
182
 
@@ -177,6 +187,8 @@ describe Geo3d::Matrix do
177
187
  data[:expected].size.should == 16
178
188
  expected = Geo3d::Matrix.new *data[:expected]
179
189
  matrix.should == expected
190
+ matrix.is_rotation_transform?.should == true
191
+ expected.is_rotation_transform?.should == true
180
192
  end
181
193
  end
182
194
 
@@ -186,6 +198,8 @@ describe Geo3d::Matrix do
186
198
  data[:expected].size.should == 16
187
199
  expected = Geo3d::Matrix.new *data[:expected]
188
200
  matrix.should == expected
201
+ matrix.is_rotation_transform?.should == true
202
+ expected.is_rotation_transform?.should == true
189
203
  end
190
204
  end
191
205
 
@@ -33,21 +33,32 @@ describe Geo3d::Quaternion do
33
33
  end
34
34
 
35
35
  it "should be able to convert to a rotation matrix" do
36
-
36
+ [{:quaternion => [0.0, 0.7071067811865475, 0.0, 0.7071067811865475], :expected => [0.000000, 0.000000, -1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000]}].each do |data|
37
+ quaternion = Geo3d::Quaternion.new *data[:quaternion]
38
+ data[:expected].size.should == 16
39
+ expected = Geo3d::Matrix.new *data[:expected]
40
+ quaternion.to_matrix.should == expected
41
+ end
37
42
  end
38
43
 
39
- it "should return axis of rotation" do
44
+ it "should return axis and angle of rotation" do
40
45
  for i in 0..10000
41
46
  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
47
+ normalized_angle = Geo3d::Utils.normalize_angle angle
48
+
49
+ Geo3d::Quaternion.from_axis(Geo3d::Vector.new(1, 0, 0), angle).axis.should == Geo3d::Vector.new(1, 0, 0)
50
+ Geo3d::Quaternion.from_axis(Geo3d::Vector.new(0, 1, 0), angle).axis.should == Geo3d::Vector.new(0, 1, 0)
51
+ Geo3d::Quaternion.from_axis(Geo3d::Vector.new(0, 0, 1), angle).axis.should == Geo3d::Vector.new(0, 0, 1)
48
52
 
49
- it "should return rotation amount as angle" do
50
53
 
54
+ Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_x angle).axis.should == Geo3d::Vector.new(1, 0, 0)
55
+ Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_y angle).axis.should == Geo3d::Vector.new(0, 1, 0)
56
+ Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_z angle).axis.should == Geo3d::Vector.new(0, 0, 1)
57
+
58
+ Geo3d::Utils.float_cmp(Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_x angle).angle, normalized_angle).should == true
59
+ Geo3d::Utils.float_cmp(Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_y angle).angle, normalized_angle).should == true
60
+ Geo3d::Utils.float_cmp(Geo3d::Quaternion.from_matrix(Geo3d::Matrix.rotation_z angle).angle, normalized_angle).should == true
61
+ end
51
62
  end
52
63
 
53
64
  it "should return conjugate" do
@@ -108,6 +119,33 @@ describe Geo3d::Quaternion do
108
119
  end
109
120
  end
110
121
 
122
+
123
+ it "multiplying two quaternions with same axis should result in a quaternion with the same axis and the sum of their angles" do
124
+ [[1, 0, 0], [0, 1, 0], [0, 0, 1], [2, 2, 8]].each do |axis|
125
+ axis = Geo3d::Vector.new *axis
126
+
127
+ [[2.3, 0.4],
128
+ [2.3, 0.4, -0.1],
129
+ [-1, -0.25, -0.5, 2.3]].each do |angles|
130
+ product = nil
131
+ angles.each do |angle|
132
+ q = Geo3d::Quaternion.from_axis axis, angle
133
+ if product.nil?
134
+ product = q
135
+ else
136
+ product *= q
137
+ end
138
+ end
139
+
140
+ Geo3d::Utils.float_cmp(product.angle, angles.inject(:+)).should == true
141
+ product.axis.should == axis.normalize
142
+ end
143
+ end
144
+ end
145
+
146
+
147
+
148
+
111
149
  #todo: add tests for quaternion interpolation
112
150
 
113
151
  end
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.6
4
+ version: 0.0.7
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-15 00:00:00.000000000 Z
11
+ date: 2014-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler