7 category:'Graphics-Transformations' |
7 category:'Graphics-Transformations' |
8 ! |
8 ! |
9 |
9 |
10 MatrixTransform2x3 comment:'This class represents a transformation for points, that is a combination of scale, offset, and rotation. It is implemented as a 2x3 matrix containing the transformation from the local coordinate system in the global coordinate system. Thus, transforming points from local to global coordinates is fast and cheap whereas transformations from global to local coordinate systems are relatively expensive. |
10 MatrixTransform2x3 comment:'This class represents a transformation for points, that is a combination of scale, offset, and rotation. It is implemented as a 2x3 matrix containing the transformation from the local coordinate system in the global coordinate system. Thus, transforming points from local to global coordinates is fast and cheap whereas transformations from global to local coordinate systems are relatively expensive. |
11 |
11 |
12 Implementation Note: It is assumed that the transformation deals with Integer points. All transformations will return Integer coordinates (even though float points may be passed in here).'! |
12 Implementation Note: It is assumed that the transformation deals with Integer points. All transformations will return Integer coordinates (even though float points may be passed in here).' |
|
13 ! |
13 |
14 |
14 |
15 |
15 !MatrixTransform2x3 class methodsFor:'instance creation'! |
16 !MatrixTransform2x3 class methodsFor:'instance creation'! |
16 |
17 |
17 identity |
18 identity |
18 ^self new setScale: 1.0! |
19 ^self new setScale: 1.0 |
|
20 ! |
19 |
21 |
20 new |
22 new |
21 ^self new: 6! |
23 ^self new: 6 |
|
24 ! |
22 |
25 |
23 transformFromLocal: localBounds toGlobal: globalBounds |
26 transformFromLocal: localBounds toGlobal: globalBounds |
24 ^((self withOffset: (globalBounds center)) composedWithLocal: |
27 ^((self withOffset: (globalBounds center)) composedWithLocal: |
25 (self withScale: (globalBounds extent / localBounds extent) asFloatPoint)) |
28 (self withScale: (globalBounds extent / localBounds extent) asFloatPoint)) |
26 composedWithLocal: (self withOffset: localBounds center negated) |
29 composedWithLocal: (self withOffset: localBounds center negated) |
27 " |
30 " |
28 ^(self identity) |
31 ^(self identity) |
29 setScale: (globalBounds extent / localBounds extent) asFloatPoint; |
32 setScale: (globalBounds extent / localBounds extent) asFloatPoint; |
30 setOffset: localBounds center negated asFloatPoint; |
33 setOffset: localBounds center negated asFloatPoint; |
31 composedWithGlobal:(self withOffset: globalBounds center asFloatPoint) |
34 composedWithGlobal:(self withOffset: globalBounds center asFloatPoint) |
32 "! |
35 " |
|
36 ! |
33 |
37 |
34 withAngle: angle |
38 withAngle: angle |
35 ^self new setAngle: angle! |
39 ^self new setAngle: angle |
|
40 ! |
36 |
41 |
37 withOffset: aPoint |
42 withOffset: aPoint |
38 ^self identity setOffset: aPoint! |
43 ^self identity setOffset: aPoint |
|
44 ! |
39 |
45 |
40 withRotation: angle |
46 withRotation: angle |
41 ^self new setAngle: angle! |
47 ^self new setAngle: angle |
|
48 ! |
42 |
49 |
43 withScale: aPoint |
50 withScale: aPoint |
44 ^self new setScale: aPoint! ! |
51 ^self new setScale: aPoint |
|
52 ! ! |
45 |
53 |
46 !MatrixTransform2x3 methodsFor:'accessing'! |
54 !MatrixTransform2x3 methodsFor:'accessing'! |
47 |
55 |
48 at: index |
56 at: index |
49 "/ <primitive: 'primitiveFloatArrayAt'> |
57 "/ <primitive: 'primitiveFloatArrayAt'> |
71 r2 _ (self invertPoint: 0@1) - r3. |
79 r2 _ (self invertPoint: 0@1) - r3. |
72 m _ self species new. |
80 m _ self species new. |
73 m |
81 m |
74 a11: r1 x; a12: r2 x; a13: r3 x; |
82 a11: r1 x; a12: r2 x; a13: r3 x; |
75 a21: r1 y; a22: r2 y; a23: r3 y. |
83 a21: r1 y; a22: r2 y; a23: r3 y. |
76 ^m! |
84 ^m |
|
85 ! |
77 |
86 |
78 offset |
87 offset |
79 ^self a13 @ self a23! |
88 ^self a13 @ self a23 |
|
89 ! |
80 |
90 |
81 offset: aPoint |
91 offset: aPoint |
82 self a13: aPoint x asFloat. |
92 self a13: aPoint x asFloat. |
83 self a23: aPoint y asFloat.! ! |
93 self a23: aPoint y asFloat. |
|
94 ! ! |
84 |
95 |
85 !MatrixTransform2x3 methodsFor:'comparing'! |
96 !MatrixTransform2x3 methodsFor:'comparing'! |
86 |
97 |
87 = MatrixTransform2x3 |
98 = MatrixTransform2x3 |
88 | length | |
99 | length | |
108 !MatrixTransform2x3 methodsFor:'composing'! |
119 !MatrixTransform2x3 methodsFor:'composing'! |
109 |
120 |
110 composedWithLocal: aTransformation |
121 composedWithLocal: aTransformation |
111 "Return the composition of the receiver and the local transformation passed in" |
122 "Return the composition of the receiver and the local transformation passed in" |
112 aTransformation isMatrixTransform2x3 ifFalse:[^super composedWith: aTransformation]. |
123 aTransformation isMatrixTransform2x3 ifFalse:[^super composedWith: aTransformation]. |
113 ^self composedWithLocal: aTransformation asMatrixTransform2x3 into: self class new! |
124 ^self composedWithLocal: aTransformation asMatrixTransform2x3 into: self class new |
|
125 ! |
114 |
126 |
115 composedWithLocal: aTransformation into: result |
127 composedWithLocal: aTransformation into: result |
116 "Return the composition of the receiver and the local transformation passed in. |
128 "Return the composition of the receiver and the local transformation passed in. |
117 Store the composed matrix into result." |
129 Store the composed matrix into result." |
118 | a11 a12 a13 a21 a22 a23 b11 b12 b13 b21 b22 b23 matrix | |
130 | a11 a12 a13 a21 a22 a23 b11 b12 b13 b21 b22 b23 matrix | |
134 ! ! |
146 ! ! |
135 |
147 |
136 !MatrixTransform2x3 methodsFor:'converting'! |
148 !MatrixTransform2x3 methodsFor:'converting'! |
137 |
149 |
138 asMatrixTransform2x3 |
150 asMatrixTransform2x3 |
139 ^self! ! |
151 ^self |
|
152 ! ! |
140 |
153 |
141 !MatrixTransform2x3 methodsFor:'element access'! |
154 !MatrixTransform2x3 methodsFor:'element access'! |
142 |
155 |
143 a11 |
156 a11 |
144 ^self at: 1! |
157 ^self at: 1 |
|
158 ! |
145 |
159 |
146 a11: value |
160 a11: value |
147 self at: 1 put: value! |
161 self at: 1 put: value |
|
162 ! |
148 |
163 |
149 a12 |
164 a12 |
150 ^self at: 2! |
165 ^self at: 2 |
|
166 ! |
151 |
167 |
152 a12: value |
168 a12: value |
153 self at: 2 put: value! |
169 self at: 2 put: value |
|
170 ! |
154 |
171 |
155 a13 |
172 a13 |
156 ^self at: 3! |
173 ^self at: 3 |
|
174 ! |
157 |
175 |
158 a13: value |
176 a13: value |
159 self at: 3 put: value! |
177 self at: 3 put: value |
|
178 ! |
160 |
179 |
161 a21 |
180 a21 |
162 ^self at: 4! |
181 ^self at: 4 |
|
182 ! |
163 |
183 |
164 a21: value |
184 a21: value |
165 self at: 4 put: value! |
185 self at: 4 put: value |
|
186 ! |
166 |
187 |
167 a22 |
188 a22 |
168 ^self at: 5! |
189 ^self at: 5 |
|
190 ! |
169 |
191 |
170 a22: value |
192 a22: value |
171 self at: 5 put: value! |
193 self at: 5 put: value |
|
194 ! |
172 |
195 |
173 a23 |
196 a23 |
174 ^self at: 6! |
197 ^self at: 6 |
|
198 ! |
175 |
199 |
176 a23: value |
200 a23: value |
177 self at: 6 put: value! ! |
201 self at: 6 put: value |
|
202 ! ! |
178 |
203 |
179 !MatrixTransform2x3 methodsFor:'initialize'! |
204 !MatrixTransform2x3 methodsFor:'initialize'! |
180 |
205 |
181 setIdentiy |
206 setIdentiy |
182 "Initialize the receiver to the identity transformation (e.g., not affecting points)" |
207 "Initialize the receiver to the identity transformation (e.g., not affecting points)" |
183 self |
208 self |
184 a11: 1.0; a12: 0.0; a13: 0.0; |
209 a11: 1.0; a12: 0.0; a13: 0.0; |
185 a21: 0.0; a22: 1.0; a23: 0.0.! ! |
210 a21: 0.0; a22: 1.0; a23: 0.0. |
|
211 ! ! |
186 |
212 |
187 !MatrixTransform2x3 methodsFor:'printing'! |
213 !MatrixTransform2x3 methodsFor:'printing'! |
188 |
214 |
189 printOn: aStream |
215 printOn: aStream |
190 aStream |
216 aStream |
191 nextPutAll: self class name; |
217 nextPutAll: self class name; |
192 nextPut: $(; |
218 nextPut: $(; |
193 cr; print: self a11; tab; print: self a12; tab; print: self a13; |
219 cr; print: self a11; tab; print: self a12; tab; print: self a13; |
194 cr; print: self a21; tab; print: self a22; tab; print: self a23; |
220 cr; print: self a21; tab; print: self a22; tab; print: self a23; |
195 cr; nextPut:$).! ! |
221 cr; nextPut:$). |
|
222 ! ! |
196 |
223 |
197 !MatrixTransform2x3 methodsFor:'private'! |
224 !MatrixTransform2x3 methodsFor:'private'! |
198 |
225 |
199 setAngle: angle |
226 setAngle: angle |
200 "Set the raw rotation angle in the receiver" |
227 "Set the raw rotation angle in the receiver" |
203 s := rad sin. |
230 s := rad sin. |
204 c := rad cos. |
231 c := rad cos. |
205 self a11: c. |
232 self a11: c. |
206 self a12: s negated. |
233 self a12: s negated. |
207 self a21: s. |
234 self a21: s. |
208 self a22: c.! |
235 self a22: c. |
|
236 ! |
209 |
237 |
210 setOffset: aPoint |
238 setOffset: aPoint |
211 "Set the raw offset in the receiver" |
239 "Set the raw offset in the receiver" |
212 | pt | |
240 | pt | |
213 pt _ aPoint asPoint. |
241 pt := aPoint asPoint. |
214 self a13: pt x asFloat. |
242 self a13: pt x asFloat. |
215 self a23: pt y asFloat.! |
243 self a23: pt y asFloat. |
|
244 ! |
216 |
245 |
217 setScale: aPoint |
246 setScale: aPoint |
218 "Set the raw scale in the receiver" |
247 "Set the raw scale in the receiver" |
219 | pt | |
248 | pt | |
220 pt _ aPoint asPoint. |
249 pt := aPoint asPoint. |
221 self a11: pt x asFloat. |
250 self a11: pt x asFloat. |
222 self a22: pt y asFloat.! ! |
251 self a22: pt y asFloat. |
|
252 ! ! |
223 |
253 |
224 !MatrixTransform2x3 methodsFor:'testing'! |
254 !MatrixTransform2x3 methodsFor:'testing'! |
225 |
255 |
226 isIdentity |
256 isIdentity |
227 "Return true if the receiver is the identity transform; that is, if applying to a point returns the point itself." |
257 "Return true if the receiver is the identity transform; that is, if applying to a point returns the point itself." |
229 ^self isPureTranslation and:[self a13 = 0.0 and:[self a23 = 0.0]] |
259 ^self isPureTranslation and:[self a13 = 0.0 and:[self a23 = 0.0]] |
230 ! |
260 ! |
231 |
261 |
232 isMatrixTransform2x3 |
262 isMatrixTransform2x3 |
233 "Return true if the receiver is 2x3 matrix transformation" |
263 "Return true if the receiver is 2x3 matrix transformation" |
234 ^true! |
264 ^true |
|
265 ! |
235 |
266 |
236 isPureTranslation |
267 isPureTranslation |
237 "Return true if the receiver specifies no rotation or scaling." |
268 "Return true if the receiver specifies no rotation or scaling." |
238 "/ <primitive: 'm23PrimitiveIsPureTranslation'> |
269 "/ <primitive: 'm23PrimitiveIsPureTranslation'> |
239 ^self a11 = 1.0 and:[self a12 = 0.0 and:[self a22 = 0.0 and:[self a21 = 1.0]]] |
270 ^self a11 = 1.0 and:[self a12 = 0.0 and:[self a22 = 0.0 and:[self a21 = 1.0]]] |
257 det _ (a11 * a22) - (a12 * a21). |
288 det _ (a11 * a22) - (a12 * a21). |
258 det = 0.0 ifTrue:[^0@0]. "So we have at least a valid result" |
289 det = 0.0 ifTrue:[^0@0]. "So we have at least a valid result" |
259 det _ 1.0 / det. |
290 det _ 1.0 / det. |
260 detX _ (x * a22) - (a12 * y). |
291 detX _ (x * a22) - (a12 * y). |
261 detY _ (a11 * y) - (x * a21). |
292 detY _ (a11 * y) - (x * a21). |
262 ^(detX * det) @ (detY * det)! |
293 ^(detX * det) @ (detY * det) |
|
294 ! |
263 |
295 |
264 localPointToGlobal: aPoint |
296 localPointToGlobal: aPoint |
265 "Transform aPoint from local coordinates into global coordinates" |
297 "Transform aPoint from local coordinates into global coordinates" |
266 "/ <primitive: 'm23PrimitiveTransformPoint'> |
298 "/ <primitive: 'm23PrimitiveTransformPoint'> |
267 ^(self transformPoint: aPoint) rounded |
299 ^(self transformPoint: aPoint) rounded |
268 ! |
300 ! |
269 |
301 |
|
302 transformDirection: aPoint |
|
303 "Transform aPoint from local coordinates into global coordinates; |
|
304 Ignores the offset." |
|
305 | x y | |
|
306 x := (aPoint x * self a11) + (aPoint y * self a12). |
|
307 y := (aPoint x * self a21) + (aPoint y * self a22). |
|
308 ^x @ y |
|
309 ! |
|
310 |
270 transformPoint: aPoint |
311 transformPoint: aPoint |
271 "Transform aPoint from local coordinates into global coordinates" |
312 "Transform aPoint from local coordinates into global coordinates" |
272 | x y | |
313 | x y | |
273 x _ (aPoint x * self a11) + (aPoint y * self a12) + self a13. |
314 x := (aPoint x * self a11) + (aPoint y * self a12) + self a13. |
274 y _ (aPoint x * self a21) + (aPoint y * self a22) + self a23. |
315 y := (aPoint x * self a21) + (aPoint y * self a22) + self a23. |
275 ^x @ y! ! |
316 ^x @ y |
|
317 ! ! |
276 |
318 |
277 !MatrixTransform2x3 methodsFor:'transforming rects'! |
319 !MatrixTransform2x3 methodsFor:'transforming rects'! |
278 |
320 |
279 globalBounds: srcRect toLocal: dstRect |
321 globalBounds: srcRect toLocal: dstRect |
280 "Transform aRectangle from global coordinates into local coordinates" |
322 "Transform aRectangle from global coordinates into local coordinates" |
282 ^super globalBoundsToLocal: srcRect |
324 ^super globalBoundsToLocal: srcRect |
283 ! |
325 ! |
284 |
326 |
285 globalBoundsToLocal: aRectangle |
327 globalBoundsToLocal: aRectangle |
286 "Transform aRectangle from global coordinates into local coordinates" |
328 "Transform aRectangle from global coordinates into local coordinates" |
287 ^self globalBounds: aRectangle toLocal: Rectangle new! |
329 ^self globalBounds: aRectangle toLocal: Rectangle new |
|
330 ! |
288 |
331 |
289 localBounds: srcRect toGlobal: dstRect |
332 localBounds: srcRect toGlobal: dstRect |
290 "Transform aRectangle from local coordinates into global coordinates" |
333 "Transform aRectangle from local coordinates into global coordinates" |
291 "/ <primitive:'m23PrimitiveTransformRectInto'> |
334 "/ <primitive:'m23PrimitiveTransformRectInto'> |
292 ^super localBoundsToGlobal: srcRect |
335 ^super localBoundsToGlobal: srcRect |
293 ! |
336 ! |
294 |
337 |
295 localBoundsToGlobal: aRectangle |
338 localBoundsToGlobal: aRectangle |
296 "Transform aRectangle from local coordinates into global coordinates" |
339 "Transform aRectangle from local coordinates into global coordinates" |
297 ^self localBounds: aRectangle toGlobal: Rectangle new! ! |
340 ^self localBounds: aRectangle toGlobal: Rectangle new |
|
341 ! ! |
298 |
342 |
299 !MatrixTransform2x3 class methodsFor:'documentation'! |
343 !MatrixTransform2x3 class methodsFor:'documentation'! |
300 |
344 |
301 version |
345 version |
302 ^ '$Header: /cvs/stx/stx/libview2/MatrixTransform2x3.st,v 1.2 2000-07-18 12:21:06 cg Exp $' |
346 ^ '$Header: /cvs/stx/stx/libview2/MatrixTransform2x3.st,v 1.3 2013-03-30 00:54:53 cg Exp $' |
303 ! ! |
347 ! ! |
|
348 |