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

Side by Side Diff: ui/gfx/transform_util.cc

Issue 692593003: More robust matrix decomposition (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « ui/gfx/transform_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/transform_util.h" 5 #include "ui/gfx/transform_util.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "ui/gfx/point.h" 12 #include "ui/gfx/point.h"
13 #include "ui/gfx/point3_f.h" 13 #include "ui/gfx/point3_f.h"
14 #include "ui/gfx/rect.h" 14 #include "ui/gfx/rect.h"
15 15
16 namespace gfx { 16 namespace gfx {
17 17
18 namespace { 18 namespace {
19 19
20 SkMScalar Length3(SkMScalar v[3]) { 20 SkMScalar Length3(SkMScalar v[3]) {
21 double vd[3] = {SkMScalarToDouble(v[0]), SkMScalarToDouble(v[1]), 21 double vd[3] = {SkMScalarToDouble(v[0]), SkMScalarToDouble(v[1]),
22 SkMScalarToDouble(v[2])}; 22 SkMScalarToDouble(v[2])};
23 return SkDoubleToMScalar( 23 return SkDoubleToMScalar(
24 std::sqrt(vd[0] * vd[0] + vd[1] * vd[1] + vd[2] * vd[2])); 24 std::sqrt(vd[0] * vd[0] + vd[1] * vd[1] + vd[2] * vd[2]));
25 } 25 }
26 26
27 void Scale3(SkMScalar v[3], SkMScalar scale) {
28 for (int i = 0; i < 3; ++i)
29 v[i] *= scale;
30 }
31
32 template <int n> 27 template <int n>
33 SkMScalar Dot(const SkMScalar* a, const SkMScalar* b) { 28 SkMScalar Dot(const SkMScalar* a, const SkMScalar* b) {
34 double total = 0.0; 29 double total = 0.0;
35 for (int i = 0; i < n; ++i) 30 for (int i = 0; i < n; ++i)
36 total += a[i] * b[i]; 31 total += a[i] * b[i];
37 return SkDoubleToMScalar(total); 32 return SkDoubleToMScalar(total);
38 } 33 }
39 34
40 template <int n> 35 template <int n>
41 void Combine(SkMScalar* out, 36 void Combine(SkMScalar* out,
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 for (int i = 0; i < 3; i++) 360 for (int i = 0; i < 3; i++)
366 decomp->translate[i] = matrix.get(i, 3); 361 decomp->translate[i] = matrix.get(i, 3);
367 362
368 SkMScalar row[3][3]; 363 SkMScalar row[3][3];
369 for (int i = 0; i < 3; i++) 364 for (int i = 0; i < 3; i++)
370 for (int j = 0; j < 3; ++j) 365 for (int j = 0; j < 3; ++j)
371 row[i][j] = matrix.get(j, i); 366 row[i][j] = matrix.get(j, i);
372 367
373 // Compute X scale factor and normalize first row. 368 // Compute X scale factor and normalize first row.
374 decomp->scale[0] = Length3(row[0]); 369 decomp->scale[0] = Length3(row[0]);
375 if (decomp->scale[0] != 0.0) 370 if (decomp->scale[0] != 0.0) {
376 Scale3(row[0], 1.0 / decomp->scale[0]); 371 row[0][0] /= decomp->scale[0];
372 row[0][1] /= decomp->scale[0];
373 row[0][2] /= decomp->scale[0];
374 }
377 375
378 // Compute XY shear factor and make 2nd row orthogonal to 1st. 376 // Compute XY shear factor and make 2nd row orthogonal to 1st.
379 decomp->skew[0] = Dot<3>(row[0], row[1]); 377 decomp->skew[0] = Dot<3>(row[0], row[1]);
380 Combine<3>(row[1], row[1], row[0], 1.0, -decomp->skew[0]); 378 Combine<3>(row[1], row[1], row[0], 1.0, -decomp->skew[0]);
381 379
382 // Now, compute Y scale and normalize 2nd row. 380 // Now, compute Y scale and normalize 2nd row.
383 decomp->scale[1] = Length3(row[1]); 381 decomp->scale[1] = Length3(row[1]);
384 if (decomp->scale[1] != 0.0) 382 if (decomp->scale[1] != 0.0) {
385 Scale3(row[1], 1.0 / decomp->scale[1]); 383 row[1][0] /= decomp->scale[1];
384 row[1][1] /= decomp->scale[1];
385 row[1][2] /= decomp->scale[1];
386 }
386 387
387 decomp->skew[0] /= decomp->scale[1]; 388 decomp->skew[0] /= decomp->scale[1];
388 389
389 // Compute XZ and YZ shears, orthogonalize 3rd row 390 // Compute XZ and YZ shears, orthogonalize 3rd row
390 decomp->skew[1] = Dot<3>(row[0], row[2]); 391 decomp->skew[1] = Dot<3>(row[0], row[2]);
391 Combine<3>(row[2], row[2], row[0], 1.0, -decomp->skew[1]); 392 Combine<3>(row[2], row[2], row[0], 1.0, -decomp->skew[1]);
392 decomp->skew[2] = Dot<3>(row[1], row[2]); 393 decomp->skew[2] = Dot<3>(row[1], row[2]);
393 Combine<3>(row[2], row[2], row[1], 1.0, -decomp->skew[2]); 394 Combine<3>(row[2], row[2], row[1], 1.0, -decomp->skew[2]);
394 395
395 // Next, get Z scale and normalize 3rd row. 396 // Next, get Z scale and normalize 3rd row.
396 decomp->scale[2] = Length3(row[2]); 397 decomp->scale[2] = Length3(row[2]);
397 if (decomp->scale[2] != 0.0) 398 if (decomp->scale[2] != 0.0) {
398 Scale3(row[2], 1.0 / decomp->scale[2]); 399 row[2][0] /= decomp->scale[2];
400 row[2][1] /= decomp->scale[2];
401 row[2][2] /= decomp->scale[2];
402 }
399 403
400 decomp->skew[1] /= decomp->scale[2]; 404 decomp->skew[1] /= decomp->scale[2];
401 decomp->skew[2] /= decomp->scale[2]; 405 decomp->skew[2] /= decomp->scale[2];
402 406
403 // At this point, the matrix (in rows) is orthonormal. 407 // At this point, the matrix (in rows) is orthonormal.
404 // Check for a coordinate system flip. If the determinant 408 // Check for a coordinate system flip. If the determinant
405 // is -1, then negate the matrix and the scaling factors. 409 // is -1, then negate the matrix and the scaling factors.
406 SkMScalar pdum3[3]; 410 SkMScalar pdum3[3];
407 Cross3(pdum3, row[1], row[2]); 411 Cross3(pdum3, row[1], row[2]);
408 if (Dot<3>(row[0], pdum3) < 0) { 412 if (Dot<3>(row[0], pdum3) < 0) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 perspective[1], 496 perspective[1],
493 perspective[2], 497 perspective[2],
494 perspective[3], 498 perspective[3],
495 quaternion[0], 499 quaternion[0],
496 quaternion[1], 500 quaternion[1],
497 quaternion[2], 501 quaternion[2],
498 quaternion[3]); 502 quaternion[3]);
499 } 503 }
500 504
501 } // namespace ui 505 } // namespace ui
OLDNEW
« no previous file with comments | « ui/gfx/transform_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698