OLD | NEW |
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 Loading... |
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 Loading... |
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) |
OLD | NEW |