Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: src/core/SkMatrix.cpp

Issue 19569007: Add basic SVD support to SkMatrix. Allows you to pull out the x- and y-scale factors, sandwiched by… (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkMatrix.h" 8 #include "SkMatrix.h"
9 #include "Sk64.h" 9 #include "Sk64.h"
10 #include "SkFloatBits.h" 10 #include "SkFloatBits.h"
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 // it has scales and skews, but it could also be rotation, check it out. 233 // it has scales and skews, but it could also be rotation, check it out.
234 SkVector vec[2]; 234 SkVector vec[2];
235 vec[0].set(mx, sx); 235 vec[0].set(mx, sx);
236 vec[1].set(sy, my); 236 vec[1].set(sy, my);
237 237
238 return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) && 238 return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) &&
239 SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(), 239 SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(),
240 SkScalarSquare(tol)); 240 SkScalarSquare(tol));
241 } 241 }
242 242
243 bool SkMatrix::decomposeUpper2x2(SkScalar* rotation0,
244 SkScalar* xScale, SkScalar* yScale,
245 SkScalar* rotation1) const {
246
247 // borrowed from Jim Blinn's article "Consider the Lowly 2x2 Matrix"
248 // Note: he uses row vectors, so we have to do some swapping of terms
249 SkScalar A = fMat[kMScaleX];
250 SkScalar B = fMat[kMSkewX];
251 SkScalar C = fMat[kMSkewY];
252 SkScalar D = fMat[kMScaleY];
253
254 SkScalar E = SK_ScalarHalf*(A + D);
255 SkScalar F = SK_ScalarHalf*(A - D);
256 SkScalar G = SK_ScalarHalf*(C + B);
257 SkScalar H = SK_ScalarHalf*(C - B);
258
259 SkScalar sqrt0 = SkScalarSqrt(E*E + H*H);
260 SkScalar sqrt1 = SkScalarSqrt(F*F + G*G);
261
262 // can't have zero yScale, must be degenerate
263 if (SkScalarNearlyEqual(sqrt0, sqrt1)) {
264 return false;
265 }
266 if (NULL != xScale) {
267 *xScale = sqrt0 + sqrt1;
268 }
269 if (NULL != yScale) {
270 *yScale = sqrt0 - sqrt1;
271 }
272
273 // uniformly scaled rotation
274 if (SkScalarNearlyZero(F) && SkScalarNearlyZero(G)) {
275 SkASSERT(!SkScalarNearlyZero(E));
276 if (NULL != rotation0) {
277 *rotation0 = SkScalarATan2(H, E);
278 }
279 if (NULL != rotation1) {
280 *rotation1 = 0;
281 }
282 // uniformly scaled reflection
283 } else if (SkScalarNearlyZero(E) && SkScalarNearlyZero(H)) {
284 SkASSERT(!SkScalarNearlyZero(F));
285 if (NULL != rotation0) {
286 *rotation0 = -SkScalarATan2(G, F);
287 }
288 if (NULL != rotation1) {
289 *rotation1 = 0;
290 }
291 } else {
292 SkASSERT(!SkScalarNearlyZero(E));
293 SkASSERT(!SkScalarNearlyZero(F));
294
295 SkScalar arctan0 = SkScalarATan2(H, E);
296 SkScalar arctan1 = SkScalarATan2(G, F);
297 if (NULL != rotation0) {
298 *rotation0 = SK_ScalarHalf*(arctan0 - arctan1);
299 }
300 if (NULL != rotation1) {
301 *rotation1 = SK_ScalarHalf*(arctan0 + arctan1);
302 }
303 }
304
305 return true;
306 }
307
243 /////////////////////////////////////////////////////////////////////////////// 308 ///////////////////////////////////////////////////////////////////////////////
244 309
245 void SkMatrix::setTranslate(SkScalar dx, SkScalar dy) { 310 void SkMatrix::setTranslate(SkScalar dx, SkScalar dy) {
246 if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) { 311 if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) {
247 fMat[kMTransX] = dx; 312 fMat[kMTransX] = dx;
248 fMat[kMTransY] = dy; 313 fMat[kMTransY] = dy;
249 314
250 fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; 315 fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1;
251 fMat[kMSkewX] = fMat[kMSkewY] = 316 fMat[kMSkewX] = fMat[kMSkewY] =
252 fMat[kMPersp0] = fMat[kMPersp1] = 0; 317 fMat[kMPersp0] = fMat[kMPersp1] = 0;
(...skipping 1706 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 dst.fLeft *= scale; 2024 dst.fLeft *= scale;
1960 dst.fTop *= scale; 2025 dst.fTop *= scale;
1961 dst.fRight *= scale; 2026 dst.fRight *= scale;
1962 dst.fBottom *= scale; 2027 dst.fBottom *= scale;
1963 } 2028 }
1964 2029
1965 SkIRect idst; 2030 SkIRect idst;
1966 dst.round(&idst); 2031 dst.round(&idst);
1967 return isrc == idst; 2032 return isrc == idst;
1968 } 2033 }
OLDNEW
« include/core/SkMatrix.h ('K') | « include/core/SkMatrix.h ('k') | tests/MatrixTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698