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

Side by Side Diff: tests/MatrixTest.cpp

Issue 23596006: Revise SVD code to remove arctangents. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix matrix_decompose bench to actually check random matrices. Created 7 years, 3 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
« no previous file with comments | « tests/Matrix44Test.cpp ('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 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #include "Test.h" 8 #include "Test.h"
9 #include "SkMath.h" 9 #include "SkMath.h"
10 #include "SkMatrix.h" 10 #include "SkMatrix.h"
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 mat.setAll(0, SK_Scalar1, 0, 343 mat.setAll(0, SK_Scalar1, 0,
344 SK_Scalar1, 0, 0, 344 SK_Scalar1, 0, 0,
345 0, 0, SkMatrix::I()[8]); 345 0, 0, SkMatrix::I()[8]);
346 REPORTER_ASSERT(reporter, mat.isSimilarity()); 346 REPORTER_ASSERT(reporter, mat.isSimilarity());
347 } 347 }
348 348
349 // For test_matrix_decomposition, below. 349 // For test_matrix_decomposition, below.
350 static bool scalar_nearly_equal_relative(SkScalar a, SkScalar b, 350 static bool scalar_nearly_equal_relative(SkScalar a, SkScalar b,
351 SkScalar tolerance = SK_ScalarNearlyZer o) { 351 SkScalar tolerance = SK_ScalarNearlyZer o) {
352 // from Bruce Dawson 352 // from Bruce Dawson
353 // absolute check
353 SkScalar diff = SkScalarAbs(a - b); 354 SkScalar diff = SkScalarAbs(a - b);
354 if (diff < tolerance) { 355 if (diff < tolerance) {
355 return true; 356 return true;
356 } 357 }
357 358
359 // relative check
358 a = SkScalarAbs(a); 360 a = SkScalarAbs(a);
359 b = SkScalarAbs(b); 361 b = SkScalarAbs(b);
360 SkScalar largest = (b > a) ? b : a; 362 SkScalar largest = (b > a) ? b : a;
361 363
362 if (diff <= largest*tolerance) { 364 if (diff <= largest*tolerance) {
363 return true; 365 return true;
364 } 366 }
365 367
366 return false; 368 return false;
367 } 369 }
368 370
371 static bool check_matrix_recomposition(const SkMatrix& mat,
372 const SkPoint& rotation1,
373 const SkPoint& scale,
374 const SkPoint& rotation2) {
375 SkScalar c1 = rotation1.fX;
376 SkScalar s1 = rotation1.fY;
377 SkScalar scaleX = scale.fX;
378 SkScalar scaleY = scale.fY;
379 SkScalar c2 = rotation2.fX;
380 SkScalar s2 = rotation2.fY;
381
382 // We do a relative check here because large scale factors cause problems wi th an absolute check
383 bool result = scalar_nearly_equal_relative(mat[SkMatrix::kMScaleX],
384 scaleX*c1*c2 - scaleY*s1*s2) &&
385 scalar_nearly_equal_relative(mat[SkMatrix::kMSkewX],
386 -scaleX*s1*c2 - scaleY*c1*s2) &&
387 scalar_nearly_equal_relative(mat[SkMatrix::kMSkewY],
388 scaleX*c1*s2 + scaleY*s1*c2) &&
389 scalar_nearly_equal_relative(mat[SkMatrix::kMScaleY],
390 -scaleX*s1*s2 + scaleY*c1*c2);
391 return result;
392 }
393
369 static void test_matrix_decomposition(skiatest::Reporter* reporter) { 394 static void test_matrix_decomposition(skiatest::Reporter* reporter) {
370 SkMatrix mat; 395 SkMatrix mat;
371 SkScalar rotation0, scaleX, scaleY, rotation1; 396 SkPoint rotation1, scale, rotation2;
372 397
373 const float kRotation0 = 15.5f; 398 const float kRotation0 = 15.5f;
374 const float kRotation1 = -50.f; 399 const float kRotation1 = -50.f;
375 const float kScale0 = 5000.f; 400 const float kScale0 = 5000.f;
376 const float kScale1 = 0.001f; 401 const float kScale1 = 0.001f;
377 402
378 // identity 403 // identity
379 mat.reset(); 404 mat.reset();
380 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 405 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
381 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0)); 406 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
382 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, SK_Scalar1));
383 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, SK_Scalar1));
384 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
385 // make sure it doesn't crash if we pass in NULLs 407 // make sure it doesn't crash if we pass in NULLs
386 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, NULL, NULL, NULL, NULL)); 408 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, NULL, NULL, NULL));
387 409
388 // rotation only 410 // rotation only
389 mat.setRotate(kRotation0); 411 mat.setRotate(kRotation0);
390 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 412 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
391 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( kRotation0))); 413 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
392 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, SK_Scalar1));
393 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, SK_Scalar1));
394 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
395 414
396 // uniform scale only 415 // uniform scale only
397 mat.setScale(kScale0, kScale0); 416 mat.setScale(kScale0, kScale0);
398 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 417 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
399 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0)); 418 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
400 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
401 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0));
402 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
403 419
404 // anisotropic scale only 420 // anisotropic scale only
405 mat.setScale(kScale1, kScale0); 421 mat.setScale(kScale1, kScale0);
406 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 422 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
407 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0)); 423 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
408 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale1));
409 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0));
410 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
411 424
412 // rotation then uniform scale 425 // rotation then uniform scale
413 mat.setRotate(kRotation1); 426 mat.setRotate(kRotation1);
414 mat.postScale(kScale0, kScale0); 427 mat.postScale(kScale0, kScale0);
415 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 428 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
416 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( kRotation1))); 429 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
417 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
418 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0));
419 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
420 430
421 // uniform scale then rotation 431 // uniform scale then rotation
422 mat.setScale(kScale0, kScale0); 432 mat.setScale(kScale0, kScale0);
423 mat.postRotate(kRotation1); 433 mat.postRotate(kRotation1);
424 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 434 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
425 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( kRotation1))); 435 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
426 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
427 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0));
428 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
429 436
430 // rotation then uniform scale+reflection 437 // rotation then uniform scale+reflection
431 mat.setRotate(kRotation0); 438 mat.setRotate(kRotation0);
432 mat.postScale(kScale1, -kScale1); 439 mat.postScale(kScale1, -kScale1);
433 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 440 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
434 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( kRotation0))); 441 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
435 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale1));
436 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, -kScale1));
437 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
438 442
439 // uniform scale+reflection, then rotate 443 // uniform scale+reflection, then rotate
440 mat.setScale(kScale0, -kScale0); 444 mat.setScale(kScale0, -kScale0);
441 mat.postRotate(kRotation1); 445 mat.postRotate(kRotation1);
442 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 446 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
443 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( -kRotation1))); 447 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
444 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
445 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, -kScale0));
446 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
447 448
448 // rotation then anisotropic scale 449 // rotation then anisotropic scale
449 mat.setRotate(kRotation1); 450 mat.setRotate(kRotation1);
450 mat.postScale(kScale1, kScale0); 451 mat.postScale(kScale1, kScale0);
451 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 452 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
452 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( kRotation1))); 453 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
453 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale1));
454 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0));
455 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
456 454
455 // rotation then anisotropic scale
456 mat.setRotate(90);
457 mat.postScale(kScale1, kScale0);
458 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
459 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
460
457 // anisotropic scale then rotation 461 // anisotropic scale then rotation
458 mat.setScale(kScale1, kScale0); 462 mat.setScale(kScale1, kScale0);
459 mat.postRotate(kRotation0); 463 mat.postRotate(kRotation0);
460 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 464 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
461 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0)); 465 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
462 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale1)); 466
463 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0)); 467 // anisotropic scale then rotation
464 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation1, SkDegreesToRadians( kRotation0))); 468 mat.setScale(kScale1, kScale0);
469 mat.postRotate(90);
470 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
471 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
465 472
466 // rotation, uniform scale, then different rotation 473 // rotation, uniform scale, then different rotation
467 mat.setRotate(kRotation1); 474 mat.setRotate(kRotation1);
468 mat.postScale(kScale0, kScale0); 475 mat.postScale(kScale0, kScale0);
469 mat.postRotate(kRotation0); 476 mat.postRotate(kRotation0);
470 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 477 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
471 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, 478 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
472 SkDegreesToRadians(kRotation0 + kRotation1)));
473 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
474 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0));
475 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
476 479
477 // rotation, anisotropic scale, then different rotation 480 // rotation, anisotropic scale, then different rotation
478 mat.setRotate(kRotation0); 481 mat.setRotate(kRotation0);
479 mat.postScale(kScale1, kScale0); 482 mat.postScale(kScale1, kScale0);
480 mat.postRotate(kRotation1); 483 mat.postRotate(kRotation1);
481 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 484 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
482 // Because of the shear/skew we won't get the same results, so we need to mu ltiply it out. 485 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
483 // Generating the matrices requires doing a radian-to-degree calculation, th en degree-to-radian 486
484 // calculation (in setRotate()), which adds error, so this just computes the matrix elements 487 // rotation, anisotropic scale + reflection, then different rotation
485 // directly. 488 mat.setRotate(kRotation0);
486 SkScalar c0; 489 mat.postScale(-kScale1, kScale0);
487 SkScalar s0 = SkScalarSinCos(rotation0, &c0); 490 mat.postRotate(kRotation1);
488 SkScalar c1; 491 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
489 SkScalar s1 = SkScalarSinCos(rotation1, &c1); 492 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
490 // We do a relative check here because large scale factors cause problems wi th an absolute check
491 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMScale X],
492 scaleX*c0*c1 - scaleY *s0*s1));
493 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMSkewX ],
494 -scaleX*s0*c1 - scale Y*c0*s1));
495 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMSkewY ],
496 scaleX*c0*s1 + scaleY *s0*c1));
497 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMScale Y],
498 -scaleX*s0*s1 + scale Y*c0*c1));
499 493
500 // try some random matrices 494 // try some random matrices
501 SkMWCRandom rand; 495 SkMWCRandom rand;
502 for (int m = 0; m < 1000; ++m) { 496 for (int m = 0; m < 1000; ++m) {
503 SkScalar rot0 = rand.nextRangeF(-SK_ScalarPI, SK_ScalarPI); 497 SkScalar rot0 = rand.nextRangeF(-180, 180);
504 SkScalar sx = rand.nextRangeF(-3000.f, 3000.f); 498 SkScalar sx = rand.nextRangeF(-3000.f, 3000.f);
505 SkScalar sy = rand.nextRangeF(-3000.f, 3000.f); 499 SkScalar sy = rand.nextRangeF(-3000.f, 3000.f);
506 SkScalar rot1 = rand.nextRangeF(-SK_ScalarPI, SK_ScalarPI); 500 SkScalar rot1 = rand.nextRangeF(-180, 180);
507 mat.setRotate(rot0); 501 mat.setRotate(rot0);
508 mat.postScale(sx, sy); 502 mat.postScale(sx, sy);
509 mat.postRotate(rot1); 503 mat.postRotate(rot1);
510 504
511 if (SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &scaleY, &rotation1)) { 505 if (SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)) {
512 SkScalar c0; 506 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
513 SkScalar s0 = SkScalarSinCos(rotation0, &c0);
514 SkScalar c1;
515 SkScalar s1 = SkScalarSinCos(rotation1, &c1);
516 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix: :kMScaleX],
517 scaleX*c0*c1 - scaleY*s0*s1));
518 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix: :kMSkewX],
519 -scaleX*s0*c1 - scaleY*c0*s1));
520 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix: :kMSkewY],
521 scaleX*c0*s1 + scaleY*s0*c1));
522 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix: :kMScaleY],
523 -scaleX*s0*s1 + scaleY*c0*c1));
524 } else { 507 } else {
525 // if the matrix is degenerate, the basis vectors should be near-par allel or near-zero 508 // if the matrix is degenerate, the basis vectors should be near-par allel or near-zero
526 SkScalar perpdot = mat[SkMatrix::kMScaleX]*mat[SkMatrix::kMScaleY] - 509 SkScalar perpdot = mat[SkMatrix::kMScaleX]*mat[SkMatrix::kMScaleY] -
527 mat[SkMatrix::kMSkewX]*mat[SkMatrix::kMSkewY]; 510 mat[SkMatrix::kMSkewX]*mat[SkMatrix::kMSkewY];
528 REPORTER_ASSERT(reporter, SkScalarNearlyZero(perpdot)); 511 REPORTER_ASSERT(reporter, SkScalarNearlyZero(perpdot));
529 } 512 }
530 } 513 }
531 514
532 // translation shouldn't affect this 515 // translation shouldn't affect this
533 mat.postTranslate(-1000.f, 1000.f); 516 mat.postTranslate(-1000.f, 1000.f);
534 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 517 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
535 s0 = SkScalarSinCos(rotation0, &c0); 518 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
536 s1 = SkScalarSinCos(rotation1, &c1);
537 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMScale X],
538 scaleX*c0*c1 - scaleY *s0*s1));
539 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMSkewX ],
540 -scaleX*s0*c1 - scale Y*c0*s1));
541 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMSkewY ],
542 scaleX*c0*s1 + scaleY *s0*c1));
543 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMScale Y],
544 -scaleX*s0*s1 + scale Y*c0*c1));
545 519
546 // perspective shouldn't affect this 520 // perspective shouldn't affect this
547 mat[SkMatrix::kMPersp0] = 12.f; 521 mat[SkMatrix::kMPersp0] = 12.f;
548 mat[SkMatrix::kMPersp1] = 4.f; 522 mat[SkMatrix::kMPersp1] = 4.f;
549 mat[SkMatrix::kMPersp2] = 1872.f; 523 mat[SkMatrix::kMPersp2] = 1872.f;
550 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1)); 524 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rota tion2));
551 s0 = SkScalarSinCos(rotation0, &c0); 525 REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2));
552 s1 = SkScalarSinCos(rotation1, &c1);
553 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMScale X],
554 scaleX*c0*c1 - scaleY *s0*s1));
555 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMSkewX ],
556 -scaleX*s0*c1 - scale Y*c0*s1));
557 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMSkewY ],
558 scaleX*c0*s1 + scaleY *s0*c1));
559 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMScale Y],
560 -scaleX*s0*s1 + scale Y*c0*c1));
561
562 // rotation, anisotropic scale + reflection, then different rotation
563 mat.setRotate(kRotation0);
564 mat.postScale(-kScale1, kScale0);
565 mat.postRotate(kRotation1);
566 REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sca leY, &rotation1));
567 s0 = SkScalarSinCos(rotation0, &c0);
568 s1 = SkScalarSinCos(rotation1, &c1);
569 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMScale X],
570 scaleX*c0*c1 - scaleY *s0*s1));
571 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMSkewX ],
572 -scaleX*s0*c1 - scale Y*c0*s1));
573 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMSkewY ],
574 scaleX*c0*s1 + scaleY *s0*c1));
575 REPORTER_ASSERT(reporter, scalar_nearly_equal_relative(mat[SkMatrix::kMScale Y],
576 -scaleX*s0*s1 + scale Y*c0*c1));
577 526
578 // degenerate matrices 527 // degenerate matrices
579 // mostly zero entries 528 // mostly zero entries
580 mat.reset(); 529 mat.reset();
581 mat[SkMatrix::kMScaleX] = 0.f; 530 mat[SkMatrix::kMScaleX] = 0.f;
582 REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sc aleY, &rotation1)); 531 REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation1, &scale, &rot ation2));
583 mat.reset(); 532 mat.reset();
584 mat[SkMatrix::kMScaleY] = 0.f; 533 mat[SkMatrix::kMScaleY] = 0.f;
585 REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sc aleY, &rotation1)); 534 REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation1, &scale, &rot ation2));
586 mat.reset(); 535 mat.reset();
587 // linearly dependent entries 536 // linearly dependent entries
588 mat[SkMatrix::kMScaleX] = 1.f; 537 mat[SkMatrix::kMScaleX] = 1.f;
589 mat[SkMatrix::kMSkewX] = 2.f; 538 mat[SkMatrix::kMSkewX] = 2.f;
590 mat[SkMatrix::kMSkewY] = 4.f; 539 mat[SkMatrix::kMSkewY] = 4.f;
591 mat[SkMatrix::kMScaleY] = 8.f; 540 mat[SkMatrix::kMScaleY] = 8.f;
592 REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation0, &scaleX, &sc aleY, &rotation1)); 541 REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation1, &scale, &rot ation2));
593 } 542 }
594 543
595 // For test_matrix_homogeneous, below. 544 // For test_matrix_homogeneous, below.
596 static bool scalar_array_nearly_equal_relative(const SkScalar a[], const SkScala r b[], int count) { 545 static bool scalar_array_nearly_equal_relative(const SkScalar a[], const SkScala r b[], int count) {
597 for (int i = 0; i < count; ++i) { 546 for (int i = 0; i < count; ++i) {
598 if (!scalar_nearly_equal_relative(a[i], b[i])) { 547 if (!scalar_nearly_equal_relative(a[i], b[i])) {
599 return false; 548 return false;
600 } 549 }
601 } 550 }
602 return true; 551 return true;
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 798
850 test_matrix_max_stretch(reporter); 799 test_matrix_max_stretch(reporter);
851 test_matrix_is_similarity(reporter); 800 test_matrix_is_similarity(reporter);
852 test_matrix_recttorect(reporter); 801 test_matrix_recttorect(reporter);
853 test_matrix_decomposition(reporter); 802 test_matrix_decomposition(reporter);
854 test_matrix_homogeneous(reporter); 803 test_matrix_homogeneous(reporter);
855 } 804 }
856 805
857 #include "TestClassDef.h" 806 #include "TestClassDef.h"
858 DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix) 807 DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix)
OLDNEW
« no previous file with comments | « tests/Matrix44Test.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698