OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "cc/math_util.h" | 5 #include "cc/math_util.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "ui/gfx/quad_f.h" | 10 #include "ui/gfx/quad_f.h" |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 if (!h.w) | 350 if (!h.w) |
351 return gfx::PointF(); | 351 return gfx::PointF(); |
352 | 352 |
353 // This return value will be invalid because clipped == true, but (1) users
of this | 353 // This return value will be invalid because clipped == true, but (1) users
of this |
354 // code should be ignoring the return value when clipped == true anyway, and
(2) this | 354 // code should be ignoring the return value when clipped == true anyway, and
(2) this |
355 // behavior is more consistent with existing behavior of WebKit transforms i
f the user | 355 // behavior is more consistent with existing behavior of WebKit transforms i
f the user |
356 // really does not ignore the return value. | 356 // really does not ignore the return value. |
357 return h.cartesianPoint2d(); | 357 return h.cartesianPoint2d(); |
358 } | 358 } |
359 | 359 |
360 void MathUtil::flattenTransformTo2d(gfx::Transform& transform) | |
361 { | |
362 // Set both the 3rd row and 3rd column to (0, 0, 1, 0). | |
363 // | |
364 // One useful interpretation of doing this operation: | |
365 // - For x and y values, the new transform behaves effectively like an orth
ographic | |
366 // projection was added to the matrix sequence. | |
367 // - For z values, the new transform overrides any effect that the transfor
m had on | |
368 // z, and instead it preserves the z value for any points that are transf
ormed. | |
369 // - Because of linearity of transforms, this flattened transform also pres
erves the | |
370 // effect that any subsequent (post-multiplied) transforms would have on
z values. | |
371 // | |
372 transform.matrix().setDouble(2, 0, 0); | |
373 transform.matrix().setDouble(2, 1, 0); | |
374 transform.matrix().setDouble(0, 2, 0); | |
375 transform.matrix().setDouble(1, 2, 0); | |
376 transform.matrix().setDouble(2, 2, 1); | |
377 transform.matrix().setDouble(3, 2, 0); | |
378 transform.matrix().setDouble(2, 3, 0); | |
379 } | |
380 | |
381 static inline float scaleOnAxis(double a, double b, double c) | 360 static inline float scaleOnAxis(double a, double b, double c) |
382 { | 361 { |
383 return std::sqrt(a * a + b * b + c * c); | 362 return std::sqrt(a * a + b * b + c * c); |
384 } | 363 } |
385 | 364 |
386 gfx::Vector2dF MathUtil::computeTransform2dScaleComponents(const gfx::Transform&
transform, float fallbackValue) | 365 gfx::Vector2dF MathUtil::computeTransform2dScaleComponents(const gfx::Transform&
transform, float fallbackValue) |
387 { | 366 { |
388 if (transform.HasPerspective()) | 367 if (transform.HasPerspective()) |
389 return gfx::Vector2dF(fallbackValue, fallbackValue); | 368 return gfx::Vector2dF(fallbackValue, fallbackValue); |
390 float xScale = scaleOnAxis(transform.matrix().getDouble(0, 0), transform.mat
rix().getDouble(1, 0), transform.matrix().getDouble(2, 0)); | 369 float xScale = scaleOnAxis(transform.matrix().getDouble(0, 0), transform.mat
rix().getDouble(1, 0), transform.matrix().getDouble(2, 0)); |
391 float yScale = scaleOnAxis(transform.matrix().getDouble(0, 1), transform.mat
rix().getDouble(1, 1), transform.matrix().getDouble(2, 1)); | 370 float yScale = scaleOnAxis(transform.matrix().getDouble(0, 1), transform.mat
rix().getDouble(1, 1), transform.matrix().getDouble(2, 1)); |
392 return gfx::Vector2dF(xScale, yScale); | 371 return gfx::Vector2dF(xScale, yScale); |
393 } | 372 } |
394 | 373 |
395 float MathUtil::smallestAngleBetweenVectors(gfx::Vector2dF v1, gfx::Vector2dF v2
) | 374 float MathUtil::smallestAngleBetweenVectors(gfx::Vector2dF v1, gfx::Vector2dF v2
) |
396 { | 375 { |
397 double dotProduct = gfx::DotProduct(v1, v2) / v1.Length() / v2.Length(); | 376 double dotProduct = gfx::DotProduct(v1, v2) / v1.Length() / v2.Length(); |
398 // Clamp to compensate for rounding errors. | 377 // Clamp to compensate for rounding errors. |
399 dotProduct = std::max(-1.0, std::min(1.0, dotProduct)); | 378 dotProduct = std::max(-1.0, std::min(1.0, dotProduct)); |
400 return static_cast<float>(Rad2Deg(std::acos(dotProduct))); | 379 return static_cast<float>(Rad2Deg(std::acos(dotProduct))); |
401 } | 380 } |
402 | 381 |
403 gfx::Vector2dF MathUtil::projectVector(gfx::Vector2dF source, gfx::Vector2dF des
tination) | 382 gfx::Vector2dF MathUtil::projectVector(gfx::Vector2dF source, gfx::Vector2dF des
tination) |
404 { | 383 { |
405 float projectedLength = gfx::DotProduct(source, destination) / destination.L
engthSquared(); | 384 float projectedLength = gfx::DotProduct(source, destination) / destination.L
engthSquared(); |
406 return gfx::Vector2dF(projectedLength * destination.x(), projectedLength * d
estination.y()); | 385 return gfx::Vector2dF(projectedLength * destination.x(), projectedLength * d
estination.y()); |
407 } | 386 } |
408 | 387 |
409 void MathUtil::rotateEulerAngles(gfx::Transform* transform, double eulerX, doubl
e eulerY, double eulerZ) | |
410 { | |
411 // TODO (shawnsingh): make this implementation faster and more accurate by | |
412 // hard-coding each matrix instead of calling RotateAbout(). | |
413 gfx::Transform rotationAboutX; | |
414 gfx::Transform rotationAboutY; | |
415 gfx::Transform rotationAboutZ; | |
416 | |
417 rotationAboutX.RotateAboutXAxis(eulerX); | |
418 rotationAboutY.RotateAboutYAxis(eulerY); | |
419 rotationAboutZ.RotateAboutZAxis(eulerZ); | |
420 | |
421 gfx::Transform composite = rotationAboutZ * rotationAboutY * rotationAboutX; | |
422 transform->PreconcatTransform(composite); | |
423 } | |
424 | |
425 gfx::Transform MathUtil::to2dTransform(const gfx::Transform& transform) | |
426 { | |
427 gfx::Transform result = transform; | |
428 SkMatrix44& matrix = result.matrix(); | |
429 matrix.setDouble(0, 2, 0); | |
430 matrix.setDouble(1, 2, 0); | |
431 matrix.setDouble(2, 2, 1); | |
432 matrix.setDouble(3, 2, 0); | |
433 | |
434 matrix.setDouble(2, 0, 0); | |
435 matrix.setDouble(2, 1, 0); | |
436 matrix.setDouble(2, 3, 0); | |
437 | |
438 return result; | |
439 } | |
440 | |
441 gfx::Transform MathUtil::createGfxTransform(double m11, double m12, double m13,
double m14, | |
442 double m21, double m22, double m23,
double m24, | |
443 double m31, double m32, double m33,
double m34, | |
444 double m41, double m42, double m43,
double m44) | |
445 { | |
446 gfx::Transform result; | |
447 SkMatrix44& matrix = result.matrix(); | |
448 | |
449 // Initialize column 1 | |
450 matrix.setDouble(0, 0, m11); | |
451 matrix.setDouble(1, 0, m12); | |
452 matrix.setDouble(2, 0, m13); | |
453 matrix.setDouble(3, 0, m14); | |
454 | |
455 // Initialize column 2 | |
456 matrix.setDouble(0, 1, m21); | |
457 matrix.setDouble(1, 1, m22); | |
458 matrix.setDouble(2, 1, m23); | |
459 matrix.setDouble(3, 1, m24); | |
460 | |
461 // Initialize column 3 | |
462 matrix.setDouble(0, 2, m31); | |
463 matrix.setDouble(1, 2, m32); | |
464 matrix.setDouble(2, 2, m33); | |
465 matrix.setDouble(3, 2, m34); | |
466 | |
467 // Initialize column 4 | |
468 matrix.setDouble(0, 3, m41); | |
469 matrix.setDouble(1, 3, m42); | |
470 matrix.setDouble(2, 3, m43); | |
471 matrix.setDouble(3, 3, m44); | |
472 | |
473 return result; | |
474 } | |
475 | |
476 gfx::Transform MathUtil::createGfxTransform(double a, double b, double c, | |
477 double d, double e, double f) | |
478 { | |
479 gfx::Transform result; | |
480 SkMatrix44& matrix = result.matrix(); | |
481 matrix.setDouble(0, 0, a); | |
482 matrix.setDouble(1, 0, b); | |
483 matrix.setDouble(0, 1, c); | |
484 matrix.setDouble(1, 1, d); | |
485 matrix.setDouble(0, 3, e); | |
486 matrix.setDouble(1, 3, f); | |
487 | |
488 return result; | |
489 } | |
490 | |
491 } // namespace cc | 388 } // namespace cc |
OLD | NEW |