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

Side by Side Diff: tests/MatrixTest.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
« include/core/SkMatrix.h ('K') | « src/core/SkMatrix.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 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1); 338 mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1);
339 REPORTER_ASSERT(reporter, !mat.isSimilarity()); 339 REPORTER_ASSERT(reporter, !mat.isSimilarity());
340 340
341 // scales zero, only skews 341 // scales zero, only skews
342 mat.setAll(0, SK_Scalar1, 0, 342 mat.setAll(0, SK_Scalar1, 0,
343 SK_Scalar1, 0, 0, 343 SK_Scalar1, 0, 0,
344 0, 0, SkMatrix::I()[8]); 344 0, 0, SkMatrix::I()[8]);
345 REPORTER_ASSERT(reporter, mat.isSimilarity()); 345 REPORTER_ASSERT(reporter, mat.isSimilarity());
346 } 346 }
347 347
348 static void test_matrix_decomposition(skiatest::Reporter* reporter) {
349 SkMatrix mat;//, rotate0, rotate1, uniformScale, anisoScale;
350 SkScalar rotation0, scaleX, scaleY, rotation1;
351
352 const float kRotation0 = 15.5f;
353 const float kRotation1 = -50.f;
354 const float kScale0 = 2000.f;
355 const float kScale1 = 0.001f;
356
357 // identity
358 mat.reset();
359 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
360 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0));
361 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, SK_Scalar1));
362 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, SK_Scalar1));
363 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
364 // make sure it doesn't crash if we pass in NULLs
365 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(NULL, NULL, NULL, NULL));
366
367 // rotation only
368 mat.setRotate(kRotation0);
369 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
370 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( kRotation0)));
371 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, SK_Scalar1));
372 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, SK_Scalar1));
373 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
374
375 // uniform scale only
376 mat.setScale(kScale0, kScale0);
377 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
378 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0));
379 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
380 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0));
381 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
382
383 // anisotropic scale only
384 mat.setScale(kScale0, kScale1);
385 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
386 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0));
387 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
388 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale1));
389 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
390
391 // rotation then uniform scale
392 mat.setRotate(kRotation1);
393 mat.postScale(kScale0, kScale0);
394 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
395 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( kRotation1)));
396 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
397 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0));
398 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
399
400 // uniform scale then rotation
401 mat.setScale(kScale0, kScale0);
402 mat.postRotate(kRotation1);
403 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
404 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( kRotation1)));
405 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
406 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0));
407 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
408
409 // rotation then uniform scale+reflection
410 mat.setRotate(kRotation0);
411 mat.postScale(kScale1, -kScale1);
412 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
413 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( kRotation0)));
414 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale1));
415 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, -kScale1));
416 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
417
418 // uniform scale+reflection, then rotate
419 mat.setScale(kScale0, -kScale0);
420 mat.postRotate(kRotation1);
421 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
422 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0, SkDegreesToRadians( -kRotation1)));
423 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
424 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, -kScale0));
425 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
426
427 // rotation then anisotropic scale
428 mat.setRotate(kRotation1);
429 mat.postScale(kScale1, kScale0);
430 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
431 // because of the shear/skew we won't get the same results, so we need to mu ltiply it out
432 SkMatrix mat2;
433 mat2.setRotate(rotation0*(180.f/SK_ScalarPI));
434 mat2.postScale(scaleX, scaleY);
435 mat2.postRotate(rotation1*(180.f/SK_ScalarPI));
436 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleX],
437 mat2[SkMatrix::kMScaleX]));
438 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewX],
439 mat2[SkMatrix::kMSkewX]));
440 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewY],
441 mat2[SkMatrix::kMSkewY]));
442 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleY],
443 mat2[SkMatrix::kMScaleY]));
444
445 // anisotropic scale then rotation
446 mat.setScale(kScale0, kScale1);
447 mat.postRotate(kRotation0);
448 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
449 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation0));
450 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
451 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale1));
452 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation1, SkDegreesToRadians( kRotation0)));
453
454 // rotation, uniform scale, then different rotation
455 mat.setRotate(kRotation1);
456 mat.postScale(kScale0, kScale0);
457 mat.postRotate(kRotation0);
458 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
459 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(rotation0,
460 SkDegreesToRadians(kRotation0 + kRotation1)));
461 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleX, kScale0));
462 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(scaleY, kScale0));
463 REPORTER_ASSERT(reporter, SkScalarNearlyZero(rotation1));
464
465 // rotation, anisotropic scale, then different rotation
466 mat.setRotate(kRotation0);
467 mat.postScale(kScale1, kScale0);
468 mat.postRotate(kRotation1);
469 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
470 // because of the shear/skew we won't get the same results, so we need to mu ltiply it out
471 mat2.setRotate(rotation0*(180.f/SK_ScalarPI));
472 mat2.postScale(scaleX, scaleY);
473 mat2.postRotate(rotation1*(180.f/SK_ScalarPI));
474 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleX],
475 mat2[SkMatrix::kMScaleX]));
476 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewX],
477 mat2[SkMatrix::kMSkewX]));
478 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewY],
479 mat2[SkMatrix::kMSkewY]));
480 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleY],
481 mat2[SkMatrix::kMScaleY]));
482
483 // translation shouldn't affect this
484 mat.postTranslate(-1000.f, 1000.f);
485 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
486 // because of the shear/skew we won't get the same results, so we need to mu ltiply it out
487 mat2.setRotate(rotation0*(180.f/SK_ScalarPI));
488 mat2.postScale(scaleX, scaleY);
489 mat2.postRotate(rotation1*(180.f/SK_ScalarPI));
490 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleX],
491 mat2[SkMatrix::kMScaleX]));
492 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewX],
493 mat2[SkMatrix::kMSkewX]));
494 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewY],
495 mat2[SkMatrix::kMSkewY]));
496 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleY],
497 mat2[SkMatrix::kMScaleY]));
498
499 // perspective shouldn't affect this
500 mat[SkMatrix::kMPersp0] = 12.0;
501 mat[SkMatrix::kMPersp1] = 4.0;
502 mat[SkMatrix::kMPersp2] = 1872.0;
503 REPORTER_ASSERT(reporter, mat.decomposeUpper2x2(&rotation0, &scaleX, &scaleY , &rotation1));
504 // because of the shear/skew we won't get the same results, so we need to mu ltiply it out
505 mat2.setRotate(rotation0*(180.f/SK_ScalarPI));
506 mat2.postScale(scaleX, scaleY);
507 mat2.postRotate(rotation1*(180.f/SK_ScalarPI));
508 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleX],
509 mat2[SkMatrix::kMScaleX]));
510 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewX],
511 mat2[SkMatrix::kMSkewX]));
512 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMSkewY],
513 mat2[SkMatrix::kMSkewY]));
514 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(mat[SkMatrix::kMScaleY],
515 mat2[SkMatrix::kMScaleY]));
516
517 // degenerate matrices
518 mat.reset();
519 mat[SkMatrix::kMScaleX] = 0.f;
520 REPORTER_ASSERT(reporter, !mat.decomposeUpper2x2(&rotation0, &scaleX, &scale Y, &rotation1));
521 mat.reset();
522 mat[SkMatrix::kMScaleY] = 0.f;
523 REPORTER_ASSERT(reporter, !mat.decomposeUpper2x2(&rotation0, &scaleX, &scale Y, &rotation1));
524 mat.reset();
525 mat[SkMatrix::kMScaleX] = 1.f;
526 mat[SkMatrix::kMSkewX] = 2.f;
527 mat[SkMatrix::kMSkewY] = 4.f;
528 mat[SkMatrix::kMScaleY] = 8.f; // who do we appreciate?
529 REPORTER_ASSERT(reporter, !mat.decomposeUpper2x2(&rotation0, &scaleX, &scale Y, &rotation1));
530 }
531
348 static void TestMatrix(skiatest::Reporter* reporter) { 532 static void TestMatrix(skiatest::Reporter* reporter) {
349 SkMatrix mat, inverse, iden1, iden2; 533 SkMatrix mat, inverse, iden1, iden2;
350 534
351 mat.reset(); 535 mat.reset();
352 mat.setTranslate(SK_Scalar1, SK_Scalar1); 536 mat.setTranslate(SK_Scalar1, SK_Scalar1);
353 REPORTER_ASSERT(reporter, mat.invert(&inverse)); 537 REPORTER_ASSERT(reporter, mat.invert(&inverse));
354 iden1.setConcat(mat, inverse); 538 iden1.setConcat(mat, inverse);
355 REPORTER_ASSERT(reporter, is_identity(iden1)); 539 REPORTER_ASSERT(reporter, is_identity(iden1));
356 540
357 mat.setScale(SkIntToScalar(2), SkIntToScalar(4)); 541 mat.setScale(SkIntToScalar(2), SkIntToScalar(4));
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 // fixed pt doesn't have the property that NaN does not equal itself. 642 // fixed pt doesn't have the property that NaN does not equal itself.
459 #ifdef SK_SCALAR_IS_FIXED 643 #ifdef SK_SCALAR_IS_FIXED
460 REPORTER_ASSERT(reporter, are_equal(reporter, mat, mat2)); 644 REPORTER_ASSERT(reporter, are_equal(reporter, mat, mat2));
461 #else 645 #else
462 REPORTER_ASSERT(reporter, !are_equal(reporter, mat, mat2)); 646 REPORTER_ASSERT(reporter, !are_equal(reporter, mat, mat2));
463 #endif 647 #endif
464 648
465 test_matrix_max_stretch(reporter); 649 test_matrix_max_stretch(reporter);
466 test_matrix_is_similarity(reporter); 650 test_matrix_is_similarity(reporter);
467 test_matrix_recttorect(reporter); 651 test_matrix_recttorect(reporter);
652 test_matrix_decomposition(reporter);
468 } 653 }
469 654
470 #include "TestClassDef.h" 655 #include "TestClassDef.h"
471 DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix) 656 DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix)
OLDNEW
« include/core/SkMatrix.h ('K') | « src/core/SkMatrix.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698