geomotion 0.10.0 → 0.12.1
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/.travis.yml +2 -0
- data/Gemfile.lock +1 -1
- data/README.md +104 -0
- data/app/app_delegate.rb +5 -0
- data/app/next_controller.rb +19 -0
- data/app/perspective_controller.rb +76 -0
- data/app/shearing_controller.rb +77 -0
- data/lib/geomotion/ca_transform_3d.rb +223 -0
- data/lib/geomotion/cg_affine_transform.rb +181 -0
- data/lib/geomotion/cg_rect.rb +4 -4
- data/lib/geomotion/version.rb +1 -1
- data/resources/perspective.png +0 -0
- data/resources/shearing.png +0 -0
- data/spec/ca_transform_3d_spec.rb +345 -0
- data/spec/cg_affine_transform_spec.rb +247 -0
- data/spec/cg_rect_spec.rb +8 -1
- metadata +14 -3
@@ -0,0 +1,181 @@
|
|
1
|
+
class CGAffineTransform
|
2
|
+
# CGAffineTransform.make # default transform: identity matrix
|
3
|
+
# # make a transform from scratch
|
4
|
+
# CGAffineTransform.make(a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0)
|
5
|
+
#
|
6
|
+
# # make a transform using primitives
|
7
|
+
# CGAffineTransform.make(scale: 2, translate: [10, 10], rotate: Math::PI)
|
8
|
+
def self.make(options = {})
|
9
|
+
if options.key?(:a)
|
10
|
+
args = [
|
11
|
+
:a, :b,
|
12
|
+
:c, :d,
|
13
|
+
:tx, :ty,
|
14
|
+
].map do |key|
|
15
|
+
raise "#{key.inspect} is required" unless options.key? key
|
16
|
+
options[key]
|
17
|
+
end
|
18
|
+
return self.new(*args)
|
19
|
+
else
|
20
|
+
retval = self.identity
|
21
|
+
if options[:translate]
|
22
|
+
retval = retval.translate(options[:translate])
|
23
|
+
end
|
24
|
+
if options[:scale]
|
25
|
+
retval = retval.scale(options[:scale])
|
26
|
+
end
|
27
|
+
if options[:rotate]
|
28
|
+
retval = retval.rotate(options[:rotate])
|
29
|
+
end
|
30
|
+
return retval
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a transform that is translated. Accepts one or two arguments. One
|
35
|
+
# argument can be a Point or Array with two items, two arguments should be the
|
36
|
+
# x and y values.
|
37
|
+
# @return CGAffineTransform
|
38
|
+
def self.translate(point, ty=nil)
|
39
|
+
if ty
|
40
|
+
tx = point
|
41
|
+
else
|
42
|
+
tx = point[0]
|
43
|
+
ty = point[1]
|
44
|
+
end
|
45
|
+
CGAffineTransformMakeTranslation(tx, ty)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns a transform that is scaled. Accepts one or two arguments. One
|
49
|
+
# argument can be a Point or Array with two items or a number that will be
|
50
|
+
# used to scale both directions. Two arguments should be the x and y values.
|
51
|
+
def self.scale(scale, sy=nil)
|
52
|
+
if sy
|
53
|
+
sx = scale
|
54
|
+
elsif scale.is_a?(Numeric)
|
55
|
+
sx = sy = scale
|
56
|
+
else
|
57
|
+
sx = scale[0]
|
58
|
+
sy = scale[1]
|
59
|
+
end
|
60
|
+
CGAffineTransformMakeScale(sx, sy)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns a transform that is rotated by `angle` (+ => counterclockwise, - => clockwise)
|
64
|
+
# @return CGAffineTransform
|
65
|
+
def self.rotate(angle)
|
66
|
+
CGAffineTransformMakeRotation(angle)
|
67
|
+
end
|
68
|
+
|
69
|
+
# A "shear" translation turns a rectangle into a parallelogram
|
70
|
+
# @param px [Numeric] how much to shear in x direction
|
71
|
+
# @param py [Numeric] how much to shear in y direction
|
72
|
+
# @return CGAffineTransform
|
73
|
+
def self.shear(px, py)
|
74
|
+
CGAffineTransformMake(1, py, px, 1, 0, 0)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the CGAffineTransform identity matrix
|
78
|
+
# @return CGAffineTransform
|
79
|
+
def self.identity
|
80
|
+
CGAffineTransformIdentity
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return true if the receiver is the identity matrix, false otherwise
|
84
|
+
# @return CGAffineTransform
|
85
|
+
def identity?
|
86
|
+
CGAffineTransformIsIdentity(self)
|
87
|
+
end
|
88
|
+
|
89
|
+
# @return [CATransform3D]
|
90
|
+
def to_transform3d
|
91
|
+
CATransform3DMakeAffineTransform(self)
|
92
|
+
end
|
93
|
+
|
94
|
+
# @return [Boolean] true if the two matrices are equal
|
95
|
+
def ==(transform)
|
96
|
+
CGAffineTransformEqualToTransform(self, transform)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns self
|
100
|
+
# @return CGAffineTransform
|
101
|
+
def +@
|
102
|
+
self
|
103
|
+
end
|
104
|
+
|
105
|
+
# Concatenates the two transforms
|
106
|
+
# @return CGAffineTransform
|
107
|
+
def concat(transform)
|
108
|
+
CGAffineTransformConcat(self, transform)
|
109
|
+
end
|
110
|
+
alias :+ :concat
|
111
|
+
alias :<< :concat
|
112
|
+
|
113
|
+
# Inverts the transform
|
114
|
+
# @return CGAffineTransform
|
115
|
+
def invert
|
116
|
+
CGAffineTransformInvert(self)
|
117
|
+
end
|
118
|
+
alias :-@ :invert
|
119
|
+
|
120
|
+
# Inverts the second transform and adds the result to `self`
|
121
|
+
# @return CGAffineTransform
|
122
|
+
def -(transform)
|
123
|
+
self.concat transform.invert
|
124
|
+
end
|
125
|
+
|
126
|
+
# Applies a translation transform to the receiver
|
127
|
+
# @return CGAffineTransform
|
128
|
+
def translate(point, ty=nil)
|
129
|
+
if ty
|
130
|
+
tx = point
|
131
|
+
else
|
132
|
+
tx = point[0]
|
133
|
+
ty = point[1]
|
134
|
+
end
|
135
|
+
CGAffineTransformTranslate(self, tx, ty)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Applies a scale transform to the receiver
|
139
|
+
# @return CGAffineTransform
|
140
|
+
def scale(scale, sy=nil)
|
141
|
+
if sy
|
142
|
+
sx = scale
|
143
|
+
elsif scale.is_a?(Numeric)
|
144
|
+
sx = sy = scale
|
145
|
+
else
|
146
|
+
sx = scale[0]
|
147
|
+
sy = scale[1]
|
148
|
+
end
|
149
|
+
CGAffineTransformScale(self, sx, sy)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Applies a rotation transform to the receiver
|
153
|
+
# @return CGAffineTransform
|
154
|
+
def rotate(angle)
|
155
|
+
CGAffineTransformRotate(self, angle)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Applies a shear transform to the receiver
|
159
|
+
# @return CGAffineTransform
|
160
|
+
def shear(px, py)
|
161
|
+
self.concat CGAffineTransform.shear(px, py)
|
162
|
+
end
|
163
|
+
|
164
|
+
def apply_to(thing)
|
165
|
+
case thing
|
166
|
+
when CGPoint
|
167
|
+
CGPointApplyAffineTransform(thing, self)
|
168
|
+
when CGSize
|
169
|
+
CGSizeApplyAffineTransform(thing, self)
|
170
|
+
when CGRect
|
171
|
+
CGRectApplyAffineTransform(thing, self)
|
172
|
+
else
|
173
|
+
raise "Cannot apply transform to #{thing.inspect}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def to_a
|
178
|
+
[self.a, self.b, self.c, self.d, self.tx, self.ty]
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
data/lib/geomotion/cg_rect.rb
CHANGED
@@ -9,15 +9,15 @@ class CGRect
|
|
9
9
|
# CGRect.make(origin: point, size: size)
|
10
10
|
def self.make(options = {})
|
11
11
|
if options[:origin]
|
12
|
-
x = options[:origin]
|
13
|
-
y = options[:origin]
|
12
|
+
x = options[:origin][0]
|
13
|
+
y = options[:origin][1]
|
14
14
|
else
|
15
15
|
x = options[:x] || 0
|
16
16
|
y = options[:y] || 0
|
17
17
|
end
|
18
18
|
if options[:size]
|
19
|
-
w = options[:size]
|
20
|
-
h = options[:size]
|
19
|
+
w = options[:size][0]
|
20
|
+
h = options[:size][1]
|
21
21
|
else
|
22
22
|
w = options[:width] || 0
|
23
23
|
h = options[:height] || 0
|
data/lib/geomotion/version.rb
CHANGED
Binary file
|
Binary file
|
@@ -0,0 +1,345 @@
|
|
1
|
+
describe "CATransform3D" do
|
2
|
+
|
3
|
+
describe "operations" do
|
4
|
+
|
5
|
+
it "should support ==" do
|
6
|
+
CATransform3D.make(
|
7
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
8
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
9
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
10
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
11
|
+
).should == CATransform3D.make(
|
12
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
13
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
14
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
15
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should support +" do
|
20
|
+
t1 = CATransform3D.make(
|
21
|
+
m11: 2, m12: 0, m13: 0, m14: 0,
|
22
|
+
m21: 0, m22: 2, m23: 0, m24: 0,
|
23
|
+
m31: 0, m32: 0, m33: 2, m34: 0,
|
24
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
25
|
+
)
|
26
|
+
t2 = CATransform3D.make(
|
27
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
28
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
29
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
30
|
+
m41: 1, m42: 2, m43: 3, m44: 1,
|
31
|
+
)
|
32
|
+
(t1 + t2).should == CATransform3D.make(
|
33
|
+
m11: 2, m12: 0, m13: 0, m14: 0,
|
34
|
+
m21: 0, m22: 2, m23: 0, m24: 0,
|
35
|
+
m31: 0, m32: 0, m33: 2, m34: 0,
|
36
|
+
m41: 1, m42: 2, m43: 3, m44: 1,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should support <<" do
|
41
|
+
t1 = CATransform3D.make(
|
42
|
+
m11: 2, m12: 0, m13: 0, m14: 0,
|
43
|
+
m21: 0, m22: 2, m23: 0, m24: 0,
|
44
|
+
m31: 0, m32: 0, m33: 2, m34: 0,
|
45
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
46
|
+
)
|
47
|
+
t2 = CATransform3D.make(
|
48
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
49
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
50
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
51
|
+
m41: 1, m42: 2, m43: 3, m44: 1,
|
52
|
+
)
|
53
|
+
(t1 << t2).should == CATransform3D.make(
|
54
|
+
m11: 2, m12: 0, m13: 0, m14: 0,
|
55
|
+
m21: 0, m22: 2, m23: 0, m24: 0,
|
56
|
+
m31: 0, m32: 0, m33: 2, m34: 0,
|
57
|
+
m41: 1, m42: 2, m43: 3, m44: 1,
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should support -" do
|
62
|
+
t1 = CATransform3D.make(
|
63
|
+
m11: 2, m12: 0, m13: 0, m14: 0,
|
64
|
+
m21: 0, m22: 2, m23: 0, m24: 0,
|
65
|
+
m31: 0, m32: 0, m33: 2, m34: 0,
|
66
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
67
|
+
)
|
68
|
+
t2 = CATransform3D.make(
|
69
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
70
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
71
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
72
|
+
m41: 1, m42: 2, m43: 3, m44: 1,
|
73
|
+
)
|
74
|
+
(t1 - t2).should == CATransform3D.make(
|
75
|
+
m11: 2, m12: 0, m13: 0, m14: 0,
|
76
|
+
m21: 0, m22: 2, m23: 0, m24: 0,
|
77
|
+
m31: 0, m32: 0, m33: 2, m34: 0,
|
78
|
+
m41: -1, m42: -2, m43: -3, m44: 1,
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "subtracting itself should return identity (scale)" do
|
83
|
+
t1 = CATransform3D.make(
|
84
|
+
m11: 2, m12: 0, m13: 0, m14: 0,
|
85
|
+
m21: 0, m22: 2, m23: 0, m24: 0,
|
86
|
+
m31: 0, m32: 0, m33: 2, m34: 0,
|
87
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
88
|
+
)
|
89
|
+
(t1 - t1).should == CATransform3D.make(
|
90
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
91
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
92
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
93
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "subtracting itself should return identity (translate)" do
|
98
|
+
t1 = CATransform3D.make(
|
99
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
100
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
101
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
102
|
+
m41: 1, m42: 2, m43: 3, m44: 1,
|
103
|
+
)
|
104
|
+
(t1 - t1).should == CATransform3D.make(
|
105
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
106
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
107
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
108
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "subtracting itself should return identity (rotate)" do
|
113
|
+
t1 = CATransform3D.make(
|
114
|
+
m11:-1, m12: 0, m13: 0, m14: 0,
|
115
|
+
m21: 0, m22:-1, m23: 0, m24: 0,
|
116
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
117
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
118
|
+
)
|
119
|
+
(t1 - t1).should == CATransform3D.make(
|
120
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
121
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
122
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
123
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should support unary -" do
|
128
|
+
(- CATransform3D.make(
|
129
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
130
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
131
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
132
|
+
m41: 1, m42: 2, m43: 3, m44: 1,
|
133
|
+
)).should == CATransform3D.make(
|
134
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
135
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
136
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
137
|
+
m41:-1, m42:-2, m43:-3, m44: 1,
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should support unary +" do
|
142
|
+
(+ CATransform3D.make(
|
143
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
144
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
145
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
146
|
+
m41: 1, m42: 2, m43: 3, m44: 1,
|
147
|
+
)).should == CATransform3D.make(
|
148
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
149
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
150
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
151
|
+
m41: 1, m42: 2, m43: 3, m44: 1,
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
describe ".make" do
|
158
|
+
|
159
|
+
it "should work with no arguments" do
|
160
|
+
transform = CATransform3D.make
|
161
|
+
transform.should == CATransform3D.identity
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should work with options" do
|
165
|
+
transform = CATransform3D.make(
|
166
|
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
167
|
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
168
|
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
169
|
+
m41: 0, m42: 0, m43: 0, m44: 1,
|
170
|
+
)
|
171
|
+
CATransform3DIsIdentity(transform).should == true
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should work with transform options (scale)" do
|
175
|
+
CATransform3D.make(scale: [2, 3, 4]).should == CATransform3D.new(2,0,0,0 ,0,3,0,0 ,0,0,4,0 ,0,0,0,1)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should work with transform options (translate)" do
|
179
|
+
CATransform3D.make(translate: [10, 20, 30]).should == CATransform3D.new(1,0,0,0 ,0,1,0,0 ,0,0,1,0 ,10,20,30,1)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should work with transform options (rotate)" do
|
183
|
+
transform = CATransform3D.make(rotate: Math::PI).to_a.map { |v| v.round(3) }
|
184
|
+
CATransform3D.new(*transform).should == CATransform3D.new(-1,0,0,0 ,0,-1,0,0 ,0,0,1,0 ,0,0,0,1)
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should work with transform options (scale + translate)" do
|
188
|
+
CATransform3D.make(scale: [2, 3, 4], translate: [10, 20, 30]).should == CATransform3D.new(2,0,0,0 ,0,3,0,0 ,0,0,4,0 ,10,20,30,1)
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should work with transform options (scale + translate + rotation)" do
|
192
|
+
transform = CATransform3D.make(scale: [2, 3, 4], rotate: Math::PI, translate: [10, 20, 30]).to_a.map { |v| v.round(3) }
|
193
|
+
CATransform3D.new(*transform).should == CATransform3D.new(-2,0,0,0 ,0,-3,0,0 ,0,0,4,0 ,10,20,30,1)
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "identity" do
|
199
|
+
|
200
|
+
it "should return the identity matrix" do
|
201
|
+
CATransform3DIsIdentity(CATransform3D.identity).should == true
|
202
|
+
end
|
203
|
+
|
204
|
+
it "identity? should return true for identity matrix" do
|
205
|
+
CATransform3D.identity.identity?.should == true
|
206
|
+
end
|
207
|
+
|
208
|
+
it "identity? should return false other matrices" do
|
209
|
+
CATransform3D.scale(2).identity?.should == false
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
describe ".rotate" do
|
215
|
+
|
216
|
+
it "should work as a factory (x-axis)" do
|
217
|
+
transform = CATransform3D.rotate(Math::PI, 1, 0, 0).to_a.map { |v| v.round(3) }
|
218
|
+
CATransform3D.new(*transform).should == CATransform3D.new(1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0,0,0,1)
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should work as a factory (y-axis)" do
|
222
|
+
transform = CATransform3D.rotate(Math::PI, 0, 1, 0).to_a.map { |v| v.round(3) }
|
223
|
+
CATransform3D.new(*transform).should == CATransform3D.new(-1,0,0,0, 0,1,0,0, 0,0,-1,0, 0,0,0,1)
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should work as a factory (z-axis)" do
|
227
|
+
transform = CATransform3D.rotate(Math::PI, 0, 0, 1).to_a.map { |v| v.round(3) }
|
228
|
+
CATransform3D.new(*transform).should == CATransform3D.new(-1,0,0,0 ,0,-1,0,0 ,0,0,1,0 ,0,0,0,1)
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should work as a factory (default)" do
|
232
|
+
transform = CATransform3D.rotate(Math::PI).to_a.map { |v| v.round(3) }
|
233
|
+
CATransform3D.new(*transform).should == CATransform3D.new(-1,0,0,0 ,0,-1,0,0 ,0,0,1,0 ,0,0,0,1)
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should work as an instance method (x-axis)" do
|
237
|
+
transform = CATransform3D.identity.rotate(Math::PI, 1, 0, 0).to_a.map { |v| v.round(3) }
|
238
|
+
CATransform3D.new(*transform).should == CATransform3D.new(1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0,0,0,1)
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should work as an instance method (y-axis)" do
|
242
|
+
transform = CATransform3D.identity.rotate(Math::PI, 0, 1, 0).to_a.map { |v| v.round(3) }
|
243
|
+
CATransform3D.new(*transform).should == CATransform3D.new(-1,0,0,0, 0,1,0,0, 0,0,-1,0, 0,0,0,1)
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should work as an instance method (z-axis)" do
|
247
|
+
transform = CATransform3D.identity.rotate(Math::PI, 0, 0, 1).to_a.map { |v| v.round(3) }
|
248
|
+
CATransform3D.new(*transform).should == CATransform3D.new(-1,0,0,0 ,0,-1,0,0 ,0,0,1,0 ,0,0,0,1)
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should work as an instance method (default)" do
|
252
|
+
transform = CATransform3D.identity.rotate(Math::PI).to_a.map { |v| v.round(3) }
|
253
|
+
CATransform3D.new(*transform).should == CATransform3D.new(-1,0,0,0 ,0,-1,0,0 ,0,0,1,0 ,0,0,0,1)
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
describe ".scale" do
|
259
|
+
|
260
|
+
it "should work as a factory with one argument" do
|
261
|
+
CATransform3D.scale(2).should == CATransform3D.new(2,0,0,0 ,0,2,0,0 ,0,0,1,0 ,0,0,0,1)
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should work as a factory with three arguments" do
|
265
|
+
CATransform3D.scale(2, 3, 4).should == CATransform3D.new(2,0,0,0 ,0,3,0,0 ,0,0,4,0 ,0,0,0,1)
|
266
|
+
end
|
267
|
+
|
268
|
+
it "should work as a factory with one array" do
|
269
|
+
CATransform3D.scale([2, 3, 4]).should == CATransform3D.new(2,0,0,0 ,0,3,0,0 ,0,0,4,0 ,0,0,0,1)
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should work as an instance method with one argument" do
|
273
|
+
CATransform3D.identity.scale(2).should == CATransform3D.new(2,0,0,0 ,0,2,0,0 ,0,0,1,0 ,0,0,0,1)
|
274
|
+
end
|
275
|
+
|
276
|
+
it "should work as an instance method with three arguments" do
|
277
|
+
CATransform3D.identity.scale(2, 3, 4).should == CATransform3D.new(2,0,0,0 ,0,3,0,0 ,0,0,4,0 ,0,0,0,1)
|
278
|
+
end
|
279
|
+
|
280
|
+
it "should work as an instance method with one array" do
|
281
|
+
CATransform3D.identity.scale([2, 3, 4]).should == CATransform3D.new(2,0,0,0 ,0,3,0,0 ,0,0,4,0 ,0,0,0,1)
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|
285
|
+
|
286
|
+
describe ".translate" do
|
287
|
+
|
288
|
+
it "should work as a factory with three arguments" do
|
289
|
+
CATransform3D.translate(10, 20, 30).should == CATransform3D.new(1,0,0,0 ,0,1,0,0 ,0,0,1,0 ,10,20,30,1)
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should work as a factory with one array" do
|
293
|
+
CATransform3D.translate([10, 20, 30]).should == CATransform3D.new(1,0,0,0 ,0,1,0,0 ,0,0,1,0 ,10,20,30,1)
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should work as an instance method with three arguments" do
|
297
|
+
CATransform3D.identity.translate(10, 20, 30).should == CATransform3D.new(1,0,0,0 ,0,1,0,0 ,0,0,1,0 ,10,20,30,1)
|
298
|
+
end
|
299
|
+
|
300
|
+
it "should work as an instance method with one array" do
|
301
|
+
CATransform3D.identity.translate([10, 20, 30]).should == CATransform3D.new(1,0,0,0 ,0,1,0,0 ,0,0,1,0 ,10,20,30,1)
|
302
|
+
end
|
303
|
+
|
304
|
+
end
|
305
|
+
|
306
|
+
describe ".perspective" do
|
307
|
+
|
308
|
+
it "should work as a factory with two arguments" do
|
309
|
+
CATransform3D.perspective(0.002, 0).should == CATransform3D.new(1,0,0,0.002, 0,1,0,0, 0,0,1,0, 0,0,0,1)
|
310
|
+
CATransform3D.perspective(0, 0.002).should == CATransform3D.new(1,0,0,0, 0,1,0,0.002, 0,0,1,0, 0,0,0,1)
|
311
|
+
end
|
312
|
+
|
313
|
+
it "should work as an instance method with two arguments" do
|
314
|
+
CATransform3D.identity.perspective(0.002, 0).should == CATransform3D.new(1,0,0,0.002, 0,1,0,0, 0,0,1,0, 0,0,0,1)
|
315
|
+
CATransform3D.identity.perspective(0, 0.002).should == CATransform3D.new(1,0,0,0, 0,1,0,0.002, 0,0,1,0, 0,0,0,1)
|
316
|
+
end
|
317
|
+
|
318
|
+
end
|
319
|
+
|
320
|
+
describe "other methods" do
|
321
|
+
|
322
|
+
it "should support concat" do
|
323
|
+
t1 = CATransform3D.translate(10, 20, 30)
|
324
|
+
t2 = CATransform3D.scale(2)
|
325
|
+
t1.concat(t2).should == CATransform3D.new(2,0,0,0 ,0,2,0,0 ,0,0,1,0 ,20,40,30,1)
|
326
|
+
end
|
327
|
+
|
328
|
+
it "should support invert" do
|
329
|
+
t1 = CATransform3D.scale(2)
|
330
|
+
t1.invert.should == CATransform3D.new(0.5,0,0,0 ,0,0.5,0,0 ,0,0,1,0 ,0,0,0,1)
|
331
|
+
end
|
332
|
+
|
333
|
+
it "should support to_affine_transform" do
|
334
|
+
t1 = CATransform3D.new(2,0,0,0 ,0,2,0,0 ,0,0,2,0 ,0,0,0,1)
|
335
|
+
t1.to_affine_transform.should == CGAffineTransformMake(2, 0, 0, 2, 0, 0)
|
336
|
+
end
|
337
|
+
|
338
|
+
it 'should support to_a' do
|
339
|
+
t1 = CATransform3D.identity
|
340
|
+
t1.to_a.should == [1,0,0,0 ,0,1,0,0 ,0,0,1,0 ,0,0,0,1]
|
341
|
+
end
|
342
|
+
|
343
|
+
end
|
344
|
+
|
345
|
+
end
|