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

Unified Diff: cc/base/math_util_unittest.cc

Issue 2551263002: Don't add duplicate points when clipping (Closed)
Patch Set: Add approximate truncation, with tests. Created 4 years 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 side-by-side diff with in-line comments
Download patch
« cc/base/math_util.cc ('K') | « cc/base/math_util.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/base/math_util_unittest.cc
diff --git a/cc/base/math_util_unittest.cc b/cc/base/math_util_unittest.cc
index 446bdf55438abf767ec8a12cc6b11a8e444e8f9a..ce2883a3d0eb3541a60d4055473f414dae2d05e7 100644
--- a/cc/base/math_util_unittest.cc
+++ b/cc/base/math_util_unittest.cc
@@ -11,6 +11,7 @@
#include "cc/test/geometry_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/quad_f.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/transform.h"
@@ -455,5 +456,149 @@ TEST(MathUtilTest, RoundDownUnderflow) {
EXPECT_TRUE(MathUtil::VerifyRoundDown<int16_t>(-123, 50));
}
+// This makes the code in the test read like the code in the implementation
+// despite the defensively named thunk that exposes the functionality for us.
+#define approx(x, y) IsApproximatelyForUnitTesting(x, y)
flackr 2016/12/08 23:31:06 nit: Maybe this should be something like EXPECT_AP
Peter Mayo 2016/12/14 23:13:11 Picked EXPECT_SIMILAR... and EXPECT_DISSIMILAR...
+
+TEST(MathUtilTest, Approximate) {
+ // Same
+ EXPECT_TRUE(approx(0.0f, 0.0f));
+ // Chose sensitivity makes hardware sense.
+ EXPECT_TRUE(approx(1000000.0f, std::nextafter(1000000.0f, 0.0f)));
+ // Arbitrary point close to 1
+ EXPECT_TRUE(approx(1.0f, 1.000001f));
+ // Arbitrary difference close to 1
+ EXPECT_TRUE(approx(10000000.0f, 10000001.0f));
+
+ // Please don't define scales by zero
+ EXPECT_FALSE(approx(0.0f, 1.0f));
+ EXPECT_FALSE(approx(1.0f, 0.0f));
+ // Or have visible differences disappear.
+ EXPECT_FALSE(approx(10000.0f, 10001.0f));
+}
+
+TEST(MathUtilTest, ApproximatePointF) {
+ // Same same.
+ EXPECT_TRUE(approx(gfx::PointF(0.0f, 0.0f), gfx::PointF(0.0f, 0.0f)));
Peter Mayo 2016/12/14 23:13:11 We can use a cover to get rid of the constructor n
+
+ // Not over sensitive on each axis.
+ EXPECT_TRUE(approx(gfx::PointF(1.000001f, 0.0f), gfx::PointF(1.0f, 0.0f)));
+ EXPECT_TRUE(approx(gfx::PointF(0.0f, 1.000001f), gfx::PointF(0.0f, 1.0f)));
+ EXPECT_TRUE(approx(gfx::PointF(1.0f, 0.0f), gfx::PointF(1.000001f, 0.0f)));
+ EXPECT_TRUE(approx(gfx::PointF(0.0f, 1.0f), gfx::PointF(0.0f, 1.000001f)));
+ EXPECT_TRUE(
+ approx(gfx::PointF(0.00000000001f, 0.0f), gfx::PointF(0.0f, 0.0f)));
+
+ // Still sensitive to each axis.
+ EXPECT_FALSE(approx(gfx::PointF(0.0f, 1.0f), gfx::PointF(0.0f, 0.0f)));
+ EXPECT_FALSE(approx(gfx::PointF(1.0f, 0.0f), gfx::PointF(0.0f, 0.0f)));
+ EXPECT_FALSE(approx(gfx::PointF(0.0f, 0.0f), gfx::PointF(1.0f, 0.0f)));
+ EXPECT_FALSE(approx(gfx::PointF(0.0f, 0.0f), gfx::PointF(0.0f, 1.0f)));
+
+ // Not crossed over.
+ EXPECT_TRUE(approx(gfx::PointF(0.0f, 1.0f), gfx::PointF(0.0f, 1.0f)));
+}
+
+TEST(MathUtilTest, ApproximatePoint3F) {
+ // Same same.
+ static const float zeroish = 1.0e-11f;
+ EXPECT_TRUE(
+ approx(gfx::Point3F(0.0f, 0.0f, 0.0f), gfx::Point3F(0.0f, 0.0f, 0.0f)));
+ EXPECT_TRUE(approx(gfx::Point3F(zeroish, 0.0f, 0.0f),
+ gfx::Point3F(0.0f, 0.0f, 0.0f)));
+ EXPECT_TRUE(approx(gfx::Point3F(0.0f, zeroish, 0.0f),
+ gfx::Point3F(0.0f, 0.0f, 0.0f)));
+ EXPECT_TRUE(approx(gfx::Point3F(0.0f, 0.0f, zeroish),
+ gfx::Point3F(0.0f, 0.0f, 0.0f)));
+ EXPECT_TRUE(approx(gfx::Point3F(0.0f, 0.0f, 0.0f),
+ gfx::Point3F(zeroish, 0.0f, 0.0f)));
+ EXPECT_TRUE(approx(gfx::Point3F(0.0f, 0.0f, 0.0f),
+ gfx::Point3F(0.0f, zeroish, 0.0f)));
+ EXPECT_TRUE(approx(gfx::Point3F(0.0f, 0.0f, 0.0f),
+ gfx::Point3F(0.0f, 0.0f, zeroish)));
+
+ // Not crossed over, sensitive on each side of each axis.
+ EXPECT_TRUE(
+ approx(gfx::Point3F(1.0f, 2.0f, 3.0f), gfx::Point3F(1.0f, 2.0f, 3.0f)));
+ EXPECT_FALSE(
+ approx(gfx::Point3F(4.0f, 2.0f, 3.0f), gfx::Point3F(1.0f, 2.0f, 3.0f)));
+ EXPECT_FALSE(
+ approx(gfx::Point3F(1.0f, 4.0f, 3.0f), gfx::Point3F(1.0f, 1.0f, 3.0f)));
+ EXPECT_FALSE(
+ approx(gfx::Point3F(1.0f, 2.0f, 4.0f), gfx::Point3F(1.0f, 2.0f, 1.0f)));
+ EXPECT_FALSE(
+ approx(gfx::Point3F(1.0f, 2.0f, 3.0f), gfx::Point3F(4.0f, 2.0f, 3.0f)));
+ EXPECT_FALSE(
+ approx(gfx::Point3F(1.0f, 2.0f, 3.0f), gfx::Point3F(1.0f, 4.0f, 3.0f)));
+ EXPECT_FALSE(
+ approx(gfx::Point3F(1.0f, 2.0f, 3.0f), gfx::Point3F(1.0f, 2.0f, 4.0f)));
+}
+
+// This takes a quad for which two points, (at x = -99) are behind and below
+// the eypoint and checks to make sure we build a triangle. We used to build
+// a degnerate quad.
+TEST(MathUtilTest, MapClippedQuadDuplicateTriangle) {
+ gfx::Transform transform;
+ transform.MakeIdentity();
+ transform.ApplyPerspectiveDepth(50.0);
+ transform.RotateAboutYAxis(89.0);
+ // We are amost looking along the X-Y plane from (-50, almost 0)
+
+ gfx::QuadF src_quad(gfx::PointF(0.0f, 100.0f), gfx::PointF(0.0f, -100.0f),
+ gfx::PointF(-99.0f, -300.0f),
+ gfx::PointF(-99.0f, -100.0f));
+
+ gfx::PointF clipped_quad[8];
+ int num_vertices_in_clipped_quad;
+
+ MathUtil::MapClippedQuad(transform, src_quad, clipped_quad,
+ &num_vertices_in_clipped_quad);
+
+ EXPECT_EQ(num_vertices_in_clipped_quad, 3);
+}
+
+// This takes a quad for which two points, (at x = -99) are behind and below
+// the eypoint and checks to make sure we build a triangle. We used to build
+// a degnerate quad. The quirk here is that the two shared points are first
+// and last, not sequential.
+TEST(MathUtilTest, MapClippedQuadDuplicateTriangleWrapped) {
+ gfx::Transform transform;
+ transform.MakeIdentity();
+ transform.ApplyPerspectiveDepth(50.0);
+ transform.RotateAboutYAxis(89.0);
+
+ gfx::QuadF src_quad(gfx::PointF(-99.0f, -100.0f), gfx::PointF(0.0f, 100.0f),
+ gfx::PointF(0.0f, -100.0f), gfx::PointF(-99.0f, -300.0f));
+
+ gfx::PointF clipped_quad[8];
+ int num_vertices_in_clipped_quad;
+
+ MathUtil::MapClippedQuad(transform, src_quad, clipped_quad,
+ &num_vertices_in_clipped_quad);
+
+ EXPECT_EQ(num_vertices_in_clipped_quad, 3);
+}
+
+// Here we map and clip a quad with only one point that disappears to infinity
+// behind us. We don't want two verticies at inifinity crossing in and out
+// of w < 0 space.
+TEST(MathUtilTest, MapClippedQuadDuplicateQuad) {
+ gfx::Transform transform;
+ transform.MakeIdentity();
+ transform.ApplyPerspectiveDepth(50.0);
+ transform.RotateAboutYAxis(89.0);
+
+ gfx::QuadF src_quad(gfx::PointF(0.0f, 100.0f), gfx::PointF(400.0f, 0.0f),
+ gfx::PointF(0.0f, -100.0f), gfx::PointF(-99.0f, -300.0f));
+
+ gfx::PointF clipped_quad[8];
+ int num_vertices_in_clipped_quad;
+
+ MathUtil::MapClippedQuad(transform, src_quad, clipped_quad,
+ &num_vertices_in_clipped_quad);
+
+ EXPECT_EQ(num_vertices_in_clipped_quad, 4);
+}
+
} // namespace
} // namespace cc
« cc/base/math_util.cc ('K') | « cc/base/math_util.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698