geo3d 0.0.6 → 0.0.7

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.
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