12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/math_util.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cmath> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/geometry_test_utils.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect_f.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/transform.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(MathUtilTest, ProjectionOfPerpendicularPlane) { 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In this case, the m33() element of the transform becomes zero, which could 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // cause a divide-by-zero when projecting points/quads. 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform transform; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.MakeIdentity(); 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) transform.matrix().set(2, 2, 0); 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::RectF rect = gfx::RectF(0, 0, 1, 1); 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::RectF projected_rect = MathUtil::ProjectClippedRect(transform, rect); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, projected_rect.x()); 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, projected_rect.y()); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(projected_rect.IsEmpty()); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(MathUtilTest, EnclosingClippedRectUsesCorrectInitialBounds) { 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HomogeneousCoordinate h1(-100, -100, 0, 1); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HomogeneousCoordinate h2(-10, -10, 0, 1); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HomogeneousCoordinate h3(10, 10, 0, -1); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HomogeneousCoordinate h4(100, 100, 0, -1); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The bounds of the enclosing clipped rect should be -100 to -10 for both x 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and y. However, if there is a bug where the initial xmin/xmax/ymin/ymax are 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // initialized to numeric_limits<float>::min() (which is zero, not -flt_max) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // then the enclosing clipped rect will be computed incorrectly. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::RectF result = MathUtil::ComputeEnclosingClippedRect(h1, h2, h3, h4); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Due to floating point math in ComputeClippedPointForEdge this result 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // is fairly imprecise. 0.15f was empirically determined. 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_RECT_NEAR( 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::RectF(gfx::PointF(-100, -100), gfx::SizeF(90, 90)), result, 0.15f); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(MathUtilTest, EnclosingRectOfVerticesUsesCorrectInitialBounds) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::PointF vertices[3]; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_vertices = 3; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vertices[0] = gfx::PointF(-10, -100); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vertices[1] = gfx::PointF(-100, -10); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vertices[2] = gfx::PointF(-30, -30); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The bounds of the enclosing rect should be -100 to -10 for both x and y. 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // However, if there is a bug where the initial xmin/xmax/ymin/ymax are 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // initialized to numeric_limits<float>::min() (which is zero, not -flt_max) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // then the enclosing clipped rect will be computed incorrectly. 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::RectF result = 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MathUtil::ComputeEnclosingRectOfVertices(vertices, num_vertices); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FLOAT_RECT_EQ(gfx::RectF(gfx::PointF(-100, -100), gfx::SizeF(90, 90)), 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(MathUtilTest, SmallestAngleBetweenVectors) { 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF x(1, 0); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF y(0, 1); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF test_vector(0.5, 0.5); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Orthogonal vectors are at an angle of 90 degress. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(90, MathUtil::SmallestAngleBetweenVectors(x, y)); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A vector makes a zero angle with itself. 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, MathUtil::SmallestAngleBetweenVectors(x, x)); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, MathUtil::SmallestAngleBetweenVectors(y, y)); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, MathUtil::SmallestAngleBetweenVectors(test_vector, test_vector)); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Parallel but reversed vectors are at 180 degrees. 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FLOAT_EQ(180, MathUtil::SmallestAngleBetweenVectors(x, -x)); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FLOAT_EQ(180, MathUtil::SmallestAngleBetweenVectors(y, -y)); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FLOAT_EQ( 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 180, MathUtil::SmallestAngleBetweenVectors(test_vector, -test_vector)); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The test vector is at a known angle. 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FLOAT_EQ( 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 45, std::floor(MathUtil::SmallestAngleBetweenVectors(test_vector, x))); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FLOAT_EQ( 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 45, std::floor(MathUtil::SmallestAngleBetweenVectors(test_vector, y))); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(MathUtilTest, VectorProjection) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF x(1, 0); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF y(0, 1); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF test_vector(0.3f, 0.7f); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Orthogonal vectors project to a zero vector. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), MathUtil::ProjectVector(x, y)); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), MathUtil::ProjectVector(y, x)); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Projecting a vector onto the orthonormal basis gives the corresponding 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // component of the vector. 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_VECTOR_EQ(gfx::Vector2dF(test_vector.x(), 0), 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MathUtil::ProjectVector(test_vector, x)); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_VECTOR_EQ(gfx::Vector2dF(0, test_vector.y()), 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MathUtil::ProjectVector(test_vector, y)); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Finally check than an arbitrary vector projected to another one gives a 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // vector parallel to the second vector. 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF target_vector(0.5, 0.2f); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2dF projected_vector = 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MathUtil::ProjectVector(test_vector, target_vector); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(projected_vector.x() / target_vector.x(), 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) projected_vector.y() / target_vector.y()); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(MathUtilTest, MapEnclosedRectWith2dAxisAlignedTransform) { 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect input(1, 2, 3, 4); 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect output; 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Transform transform; 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Identity. 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output = 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input); 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(input, output); 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Integer translate. 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.Translate(2.0, 3.0); 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output = 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input); 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(gfx::Rect(3, 5, 3, 4), output); 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Non-integer translate. 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.Translate(0.5, 0.5); 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output = 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input); 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(gfx::Rect(4, 6, 2, 3), output); 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Scale. 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform = gfx::Transform(); 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.Scale(2.0, 3.0); 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output = 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input); 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(gfx::Rect(2, 6, 6, 12), output); 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Rotate Z. 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform = gfx::Transform(); 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.Translate(1.0, 2.0); 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.RotateAboutZAxis(90.0); 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.Translate(-1.0, -2.0); 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output = 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input); 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(gfx::Rect(-3, 2, 4, 3), output); 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Rotate X. 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform = gfx::Transform(); 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.RotateAboutXAxis(90.0); 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output = 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input); 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(output.IsEmpty()); 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform = gfx::Transform(); 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.RotateAboutXAxis(180.0); 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output = 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input); 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(gfx::Rect(1, -6, 3, 4), output); 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Rotate Y. 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform = gfx::Transform(); 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.RotateAboutYAxis(90.0); 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output = 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input); 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(output.IsEmpty()); 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform = gfx::Transform(); 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.RotateAboutYAxis(180.0); 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output = 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input); 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(gfx::Rect(-4, 2, 3, 4), output); 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Translate Z. 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform = gfx::Transform(); 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.ApplyPerspectiveDepth(10.0); 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transform.Translate3d(0.0, 0.0, 5.0); 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output = 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input); 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(gfx::Rect(2, 4, 6, 8), output); 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cc 198