summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-01 17:06:57 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-01 17:06:57 +0000
commit557355eec75ee490edbd81b5035e99a841535066 (patch)
tree393d84679e23ab73073418eee4ec885c96abe05e
parent422bc9048270c1e62feac938def7e16a383ad187 (diff)
downloadchromium_src-557355eec75ee490edbd81b5035e99a841535066.zip
chromium_src-557355eec75ee490edbd81b5035e99a841535066.tar.gz
chromium_src-557355eec75ee490edbd81b5035e99a841535066.tar.bz2
ui: Add the gfx::Vector3dF class.
This class represents a distance along 3 dimensions. It supports operations such as the cross product and dot product between two such vectors, in addition to the standard operations also supported by the Vector2dF class. BUG=147395 R=sky,pkasting Review URL: https://chromiumcodereview.appspot.com/11367025 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@165402 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/gfx/point3_f.cc40
-rw-r--r--ui/gfx/point3_f.h32
-rw-r--r--ui/gfx/point3_unittest.cc43
-rw-r--r--ui/gfx/vector3d_f.cc79
-rw-r--r--ui/gfx/vector3d_f.h101
-rw-r--r--ui/gfx/vector3d_unittest.cc215
-rw-r--r--ui/ui.gyp3
-rw-r--r--ui/ui_unittests.gypi2
8 files changed, 514 insertions, 1 deletions
diff --git a/ui/gfx/point3_f.cc b/ui/gfx/point3_f.cc
new file mode 100644
index 0000000..7d7f349
--- /dev/null
+++ b/ui/gfx/point3_f.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/point3_f.h"
+
+#include "base/stringprintf.h"
+
+namespace gfx {
+
+std::string Point3F::ToString() const {
+ return base::StringPrintf("%f,%f,%f", x_, y_, z_);
+}
+
+Point3F operator+(const Point3F& lhs, const Vector3dF& rhs) {
+ float x = lhs.x() + rhs.x();
+ float y = lhs.y() + rhs.y();
+ float z = lhs.z() + rhs.z();
+ return Point3F(x, y, z);
+}
+
+// Subtract a vector from a point, producing a new point offset by the vector's
+// inverse.
+Point3F operator-(const Point3F& lhs, const Vector3dF& rhs) {
+ float x = lhs.x() - rhs.x();
+ float y = lhs.y() - rhs.y();
+ float z = lhs.z() - rhs.z();
+ return Point3F(x, y, z);
+}
+
+// Subtract one point from another, producing a vector that represents the
+// distances between the two points along each axis.
+Vector3dF operator-(const Point3F& lhs, const Point3F& rhs) {
+ float x = lhs.x() - rhs.x();
+ float y = lhs.y() - rhs.y();
+ float z = lhs.z() - rhs.z();
+ return Vector3dF(x, y, z);
+}
+
+} // namespace gfx
diff --git a/ui/gfx/point3_f.h b/ui/gfx/point3_f.h
index c0aefb5..6c45a7d 100644
--- a/ui/gfx/point3_f.h
+++ b/ui/gfx/point3_f.h
@@ -5,12 +5,16 @@
#ifndef UI_GFX_POINT3_F_H_
#define UI_GFX_POINT3_F_H_
+#include <string>
+
+#include "ui/base/ui_export.h"
#include "ui/gfx/point_f.h"
+#include "ui/gfx/vector3d_f.h"
namespace gfx {
// A point has an x, y and z coordinate.
-class Point3F {
+class UI_EXPORT Point3F {
public:
Point3F() : x_(0), y_(0), z_(0) {}
@@ -44,6 +48,9 @@ class Point3F {
PointF AsPointF() const { return PointF(x_, y_); }
+ // Returns a string representation of 3d point.
+ std::string ToString() const;
+
private:
float x_;
float y_;
@@ -52,6 +59,29 @@ class Point3F {
// copy/assign are allowed.
};
+inline bool operator==(const Point3F& lhs, const Point3F& rhs) {
+ return lhs.x() == rhs.x() && lhs.y() == rhs.y() && lhs.z() == rhs.z();
+}
+
+inline bool operator!=(const Point3F& lhs, const Point3F& rhs) {
+ return !(lhs == rhs);
+}
+
+// Add a vector to a point, producing a new point offset by the vector.
+UI_EXPORT Point3F operator+(const Point3F& lhs, const Vector3dF& rhs);
+
+// Subtract a vector from a point, producing a new point offset by the vector's
+// inverse.
+UI_EXPORT Point3F operator-(const Point3F& lhs, const Vector3dF& rhs);
+
+// Subtract one point from another, producing a vector that represents the
+// distances between the two points along each axis.
+UI_EXPORT Vector3dF operator-(const Point3F& lhs, const Point3F& rhs);
+
+inline Point3F PointAtOffsetFromOrigin(const Vector3dF& offset) {
+ return Point3F(offset.x(), offset.y(), offset.z());
+}
+
} // namespace gfx
#endif // UI_GFX_POINT3_F_H_
diff --git a/ui/gfx/point3_unittest.cc b/ui/gfx/point3_unittest.cc
new file mode 100644
index 0000000..3de4f12
--- /dev/null
+++ b/ui/gfx/point3_unittest.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/point3_f.h"
+
+#include "base/basictypes.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gfx {
+
+TEST(Point3Test, VectorArithmetic) {
+ gfx::Point3F a(1.6f, 5.1f, 3.2f);
+ gfx::Vector3dF v1(3.1f, -3.2f, 9.3f);
+ gfx::Vector3dF v2(-8.1f, 1.2f, 3.3f);
+
+ static const struct {
+ gfx::Point3F expected;
+ gfx::Point3F actual;
+ } tests[] = {
+ { gfx::Point3F(4.7f, 1.9f, 12.5f), a + v1 },
+ { gfx::Point3F(-1.5f, 8.3f, -6.1f), a - v1 },
+ { a, a - v1 + v1 },
+ { a, a + v1 - v1 },
+ { a, a + gfx::Vector3dF() },
+ { gfx::Point3F(12.8f, 0.7f, 9.2f), a + v1 - v2 },
+ { gfx::Point3F(-9.6f, 9.5f, -2.8f), a - v1 + v2 }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i)
+ EXPECT_EQ(tests[i].expected.ToString(),
+ tests[i].actual.ToString());
+}
+
+TEST(Point3Test, VectorFromPoints) {
+ gfx::Point3F a(1.6f, 5.2f, 3.2f);
+ gfx::Vector3dF v1(3.1f, -3.2f, 9.3f);
+
+ gfx::Point3F b(a + v1);
+ EXPECT_EQ((b - a).ToString(), v1.ToString());
+}
+
+} // namespace gfx
diff --git a/ui/gfx/vector3d_f.cc b/ui/gfx/vector3d_f.cc
new file mode 100644
index 0000000..730f00b
--- /dev/null
+++ b/ui/gfx/vector3d_f.cc
@@ -0,0 +1,79 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/vector3d_f.h"
+
+#include <cmath>
+
+#include "base/stringprintf.h"
+
+namespace gfx {
+
+Vector3dF::Vector3dF()
+ : x_(0),
+ y_(0),
+ z_(0) {
+}
+
+Vector3dF::Vector3dF(float x, float y, float z)
+ : x_(x),
+ y_(y),
+ z_(z) {
+}
+
+Vector3dF::Vector3dF(const Vector2dF& other)
+ : x_(other.x()),
+ y_(other.y()),
+ z_(0) {
+}
+
+std::string Vector3dF::ToString() const {
+ return base::StringPrintf("[%f %f %f]", x_, y_, z_);
+}
+
+bool Vector3dF::IsZero() const {
+ return x_ == 0 && y_ == 0 && z_ == 0;
+}
+
+void Vector3dF::Add(const Vector3dF& other) {
+ x_ += other.x_;
+ y_ += other.y_;
+ z_ += other.z_;
+}
+
+void Vector3dF::Subtract(const Vector3dF& other) {
+ x_ -= other.x_;
+ y_ -= other.y_;
+ z_ -= other.z_;
+}
+
+double Vector3dF::LengthSquared() const {
+ return static_cast<double>(x_) * x_ + static_cast<double>(y_) * y_ +
+ static_cast<double>(z_) * z_;
+}
+
+float Vector3dF::Length() const {
+ return static_cast<float>(std::sqrt(LengthSquared()));
+}
+
+void Vector3dF::Scale(float x_scale, float y_scale, float z_scale) {
+ x_ *= x_scale;
+ y_ *= y_scale;
+ z_ *= z_scale;
+}
+
+void Vector3dF::Cross(const Vector3dF& other) {
+ float x = y_ * other.z() - z_ * other.y();
+ float y = z_ * other.x() - x_ * other.z();
+ float z = x_ * other.y() - y_ * other.x();
+ x_ = x;
+ y_ = y;
+ z_ = z;
+}
+
+float DotProduct(const Vector3dF& lhs, const Vector3dF& rhs) {
+ return lhs.x() * rhs.x() + lhs.y() * rhs.y() + lhs.z() * rhs.z();
+}
+
+} // namespace gfx
diff --git a/ui/gfx/vector3d_f.h b/ui/gfx/vector3d_f.h
new file mode 100644
index 0000000..a2845f8
--- /dev/null
+++ b/ui/gfx/vector3d_f.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Defines a simple float vector class. This class is used to indicate a
+// distance in two dimensions between two points. Subtracting two points should
+// produce a vector, and adding a vector to a point produces the point at the
+// vector's distance from the original point.
+
+#ifndef UI_GFX_VECTOR3D_F_H_
+#define UI_GFX_VECTOR3D_F_H_
+
+#include <string>
+
+#include "ui/base/ui_export.h"
+#include "ui/gfx/vector2d_f.h"
+
+namespace gfx {
+
+class UI_EXPORT Vector3dF {
+ public:
+ Vector3dF();
+ Vector3dF(float x, float y, float z);
+
+ explicit Vector3dF(const Vector2dF& other);
+
+ float x() const { return x_; }
+ void set_x(float x) { x_ = x; }
+
+ float y() const { return y_; }
+ void set_y(float y) { y_ = y; }
+
+ float z() const { return z_; }
+ void set_z(float z) { z_ = z; }
+
+ // True if all components of the vector are 0.
+ bool IsZero() const;
+
+ // Add the components of the |other| vector to the current vector.
+ void Add(const Vector3dF& other);
+ // Subtract the components of the |other| vector from the current vector.
+ void Subtract(const Vector3dF& other);
+
+ void operator+=(const Vector3dF& other) { Add(other); }
+ void operator-=(const Vector3dF& other) { Subtract(other); }
+
+ // Gives the square of the diagonal length of the vector.
+ double LengthSquared() const;
+ // Gives the diagonal length of the vector.
+ float Length() const;
+
+ // Scale all components of the vector by |scale|.
+ void Scale(float scale) { Scale(scale, scale, scale); }
+ // Scale the each component of the vector by the given scale factors.
+ void Scale(float x_scale, float y_scale, float z_scale);
+
+ // Take the cross product of this vector with |other| and become the result.
+ void Cross(const Vector3dF& other);
+
+ std::string ToString() const;
+
+ private:
+ float x_;
+ float y_;
+ float z_;
+};
+
+inline bool operator==(const Vector3dF& lhs, const Vector3dF& rhs) {
+ return lhs.x() == rhs.x() && lhs.y() == rhs.y() && lhs.z() == rhs.z();
+}
+
+inline Vector3dF operator-(const Vector3dF& v) {
+ return Vector3dF(-v.x(), -v.y(), -v.z());
+}
+
+inline Vector3dF operator+(const Vector3dF& lhs, const Vector3dF& rhs) {
+ Vector3dF result = lhs;
+ result.Add(rhs);
+ return result;
+}
+
+inline Vector3dF operator-(const Vector3dF& lhs, const Vector3dF& rhs) {
+ Vector3dF result = lhs;
+ result.Add(-rhs);
+ return result;
+}
+
+// Return the cross product of two vectors.
+inline Vector3dF CrossProduct(const Vector3dF& lhs, const Vector3dF& rhs) {
+ Vector3dF result = lhs;
+ result.Cross(rhs);
+ return result;
+}
+
+// Return the dot product of two vectors.
+UI_EXPORT float DotProduct(const Vector3dF& lhs, const Vector3dF& rhs);
+
+
+} // namespace gfx
+
+#endif // UI_GFX_VECTOR3D_F_H_
diff --git a/ui/gfx/vector3d_unittest.cc b/ui/gfx/vector3d_unittest.cc
new file mode 100644
index 0000000..cfac51e
--- /dev/null
+++ b/ui/gfx/vector3d_unittest.cc
@@ -0,0 +1,215 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/vector3d_f.h"
+
+#include <cmath>
+#include <limits>
+
+namespace gfx {
+
+TEST(Vector3dTest, IsZero) {
+ gfx::Vector3dF float_zero(0, 0, 0);
+ gfx::Vector3dF float_nonzero(0.1f, -0.1f, 0.1f);
+
+ EXPECT_TRUE(float_zero.IsZero());
+ EXPECT_FALSE(float_nonzero.IsZero());
+}
+
+TEST(Vector3dTest, Add) {
+ gfx::Vector3dF f1(3.1f, 5.1f, 2.7f);
+ gfx::Vector3dF f2(4.3f, -1.3f, 8.1f);
+
+ const struct {
+ gfx::Vector3dF expected;
+ gfx::Vector3dF actual;
+ } float_tests[] = {
+ { gfx::Vector3dF(3.1F, 5.1F, 2.7f), f1 + gfx::Vector3dF() },
+ { gfx::Vector3dF(3.1f + 4.3f, 5.1f - 1.3f, 2.7f + 8.1f), f1 + f2 },
+ { gfx::Vector3dF(3.1f - 4.3f, 5.1f + 1.3f, 2.7f - 8.1f), f1 - f2 }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_tests); ++i)
+ EXPECT_EQ(float_tests[i].expected.ToString(),
+ float_tests[i].actual.ToString());
+}
+
+TEST(Vector3dTest, Negative) {
+ const struct {
+ gfx::Vector3dF expected;
+ gfx::Vector3dF actual;
+ } float_tests[] = {
+ { gfx::Vector3dF(-0.0f, -0.0f, -0.0f), -gfx::Vector3dF(0, 0, 0) },
+ { gfx::Vector3dF(-0.3f, -0.3f, -0.3f), -gfx::Vector3dF(0.3f, 0.3f, 0.3f) },
+ { gfx::Vector3dF(0.3f, 0.3f, 0.3f), -gfx::Vector3dF(-0.3f, -0.3f, -0.3f) },
+ { gfx::Vector3dF(-0.3f, 0.3f, -0.3f), -gfx::Vector3dF(0.3f, -0.3f, 0.3f) },
+ { gfx::Vector3dF(0.3f, -0.3f, -0.3f), -gfx::Vector3dF(-0.3f, 0.3f, 0.3f) },
+ { gfx::Vector3dF(-0.3f, -0.3f, 0.3f), -gfx::Vector3dF(0.3f, 0.3f, -0.3f) }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_tests); ++i)
+ EXPECT_EQ(float_tests[i].expected.ToString(),
+ float_tests[i].actual.ToString());
+}
+
+TEST(Vector3dTest, Scale) {
+ float triple_values[][6] = {
+ { 4.5f, 1.2f, 1.8f, 3.3f, 5.6f, 4.2f },
+ { 4.5f, -1.2f, -1.8f, 3.3f, 5.6f, 4.2f },
+ { 4.5f, 1.2f, -1.8f, 3.3f, 5.6f, 4.2f },
+ { 4.5f, -1.2f -1.8f, 3.3f, 5.6f, 4.2f },
+
+ { 4.5f, 1.2f, 1.8f, 3.3f, -5.6f, -4.2f },
+ { 4.5f, 1.2f, 1.8f, -3.3f, -5.6f, -4.2f },
+ { 4.5f, 1.2f, -1.8f, 3.3f, -5.6f, -4.2f },
+ { 4.5f, 1.2f, -1.8f, -3.3f, -5.6f, -4.2f },
+
+ { -4.5f, 1.2f, 1.8f, 3.3f, 5.6f, 4.2f },
+ { -4.5f, 1.2f, 1.8f, 0, 5.6f, 4.2f },
+ { -4.5f, 1.2f, -1.8f, 3.3f, 5.6f, 4.2f },
+ { -4.5f, 1.2f, -1.8f, 0, 5.6f, 4.2f },
+
+ { -4.5f, 1.2f, 1.8f, 3.3f, 0, 4.2f },
+ { 4.5f, 0, 1.8f, 3.3f, 5.6f, 4.2f },
+ { -4.5f, 1.2f, -1.8f, 3.3f, 0, 4.2f },
+ { 4.5f, 0, -1.8f, 3.3f, 5.6f, 4.2f },
+ { -4.5f, 1.2f, 1.8f, 3.3f, 5.6f, 0 },
+ { -4.5f, 1.2f, -1.8f, 3.3f, 5.6f, 0 },
+
+ { 0, 1.2f, 0, 3.3f, 5.6f, 4.2f },
+ { 0, 1.2f, 1.8f, 3.3f, 5.6f, 4.2f }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(triple_values); ++i) {
+ gfx::Vector3dF v(triple_values[i][0],
+ triple_values[i][1],
+ triple_values[i][2]);
+ v.Scale(triple_values[i][3], triple_values[i][4], triple_values[i][5]);
+ EXPECT_EQ(v.x(), triple_values[i][0] * triple_values[i][3]);
+ EXPECT_EQ(v.y(), triple_values[i][1] * triple_values[i][4]);
+ EXPECT_EQ(v.z(), triple_values[i][2] * triple_values[i][5]);
+ }
+
+ float single_values[][4] = {
+ { 4.5f, 1.2f, 1.8f, 3.3f },
+ { 4.5f, -1.2f, 1.8f, 3.3f },
+ { 4.5f, 1.2f, -1.8f, 3.3f },
+ { 4.5f, -1.2f, -1.8f, 3.3f },
+ { -4.5f, 1.2f, 3.3f },
+ { -4.5f, 1.2f, 0 },
+ { -4.5f, 1.2f, 1.8f, 3.3f },
+ { -4.5f, 1.2f, 1.8f, 0 },
+ { 4.5f, 0, 1.8f, 3.3f },
+ { 0, 1.2f, 1.8f, 3.3f },
+ { 4.5f, 0, 1.8f, 3.3f },
+ { 0, 1.2f, 1.8f, 3.3f },
+ { 4.5f, 1.2f, 0, 3.3f },
+ { 4.5f, 1.2f, 0, 3.3f }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(single_values); ++i) {
+ gfx::Vector3dF v(single_values[i][0],
+ single_values[i][1],
+ single_values[i][2]);
+ v.Scale(single_values[i][3]);
+ EXPECT_EQ(v.x(), single_values[i][0] * single_values[i][3]);
+ EXPECT_EQ(v.y(), single_values[i][1] * single_values[i][3]);
+ EXPECT_EQ(v.z(), single_values[i][2] * single_values[i][3]);
+ }
+}
+
+TEST(Vector3dTest, Length) {
+ float float_values[][3] = {
+ { 0, 0, 0 },
+ { 10.5f, 20.5f, 8.5f },
+ { 20.5f, 10.5f, 8.5f },
+ { 8.5f, 20.5f, 10.5f },
+ { 10.5f, 8.5f, 20.5f },
+ { -10.5f, -20.5f, -8.5f },
+ { -20.5f, 10.5f, -8.5f },
+ { -8.5f, -20.5f, -10.5f },
+ { -10.5f, -8.5f, -20.5f },
+ { 10.5f, -20.5f, 8.5f },
+ { -10.5f, 20.5f, 8.5f },
+ { 10.5f, -20.5f, -8.5f },
+ { -10.5f, 20.5f, -8.5f },
+ // A large vector that fails if the Length function doesn't use
+ // double precision internally.
+ { 1236278317862780234892374893213178027.12122348904204230f,
+ 335890352589839028212313231225425134332.38123f,
+ 27861786423846742743236423478236784678.236713617231f }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_values); ++i) {
+ double v0 = float_values[i][0];
+ double v1 = float_values[i][1];
+ double v2 = float_values[i][2];
+ double length_squared =
+ static_cast<double>(v0) * v0 +
+ static_cast<double>(v1) * v1 +
+ static_cast<double>(v2) * v2;
+ double length = std::sqrt(length_squared);
+ gfx::Vector3dF vector(v0, v1, v2);
+ EXPECT_EQ(length_squared, vector.LengthSquared());
+ EXPECT_EQ(static_cast<float>(length), vector.Length());
+ }
+}
+
+TEST(Vector3dTest, DotProduct) {
+ const struct {
+ float expected;
+ gfx::Vector3dF input1;
+ gfx::Vector3dF input2;
+ } tests[] = {
+ { 0, gfx::Vector3dF(1, 0, 0), gfx::Vector3dF(0, 1, 1) },
+ { 0, gfx::Vector3dF(0, 1, 0), gfx::Vector3dF(1, 0, 1) },
+ { 0, gfx::Vector3dF(0, 0, 1), gfx::Vector3dF(1, 1, 0) },
+
+ { 3, gfx::Vector3dF(1, 1, 1), gfx::Vector3dF(1, 1, 1) },
+
+ { 1.2f, gfx::Vector3dF(1.2f, -1.2f, 1.2f), gfx::Vector3dF(1, 1, 1) },
+ { 1.2f, gfx::Vector3dF(1, 1, 1), gfx::Vector3dF(1.2f, -1.2f, 1.2f) },
+
+ { 38.72f,
+ gfx::Vector3dF(1.1f, 2.2f, 3.3f), gfx::Vector3dF(4.4f, 5.5f, 6.6f) }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ float actual = gfx::DotProduct(tests[i].input1, tests[i].input2);
+ EXPECT_EQ(tests[i].expected, actual);
+ }
+}
+
+TEST(Vector3dTest, CrossProduct) {
+ const struct {
+ gfx::Vector3dF expected;
+ gfx::Vector3dF input1;
+ gfx::Vector3dF input2;
+ } tests[] = {
+ { Vector3dF(), Vector3dF(), Vector3dF(1, 1, 1) },
+ { Vector3dF(), Vector3dF(1, 1, 1), Vector3dF() },
+ { Vector3dF(), Vector3dF(1, 1, 1), Vector3dF(1, 1, 1) },
+ { Vector3dF(),
+ Vector3dF(1.6f, 10.6f, -10.6f),
+ Vector3dF(1.6f, 10.6f, -10.6f) },
+
+ { Vector3dF(1, -1, 0), Vector3dF(1, 1, 1), Vector3dF(0, 0, 1) },
+ { Vector3dF(-1, 0, 1), Vector3dF(1, 1, 1), Vector3dF(0, 1, 0) },
+ { Vector3dF(0, 1, -1), Vector3dF(1, 1, 1), Vector3dF(1, 0, 0) },
+
+ { Vector3dF(-1, 1, 0), Vector3dF(0, 0, 1), Vector3dF(1, 1, 1) },
+ { Vector3dF(1, 0, -1), Vector3dF(0, 1, 0), Vector3dF(1, 1, 1) },
+ { Vector3dF(0, -1, 1), Vector3dF(1, 0, 0), Vector3dF(1, 1, 1) }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ Vector3dF actual = gfx::CrossProduct(tests[i].input1, tests[i].input2);
+ EXPECT_EQ(tests[i].expected.ToString(), actual.ToString());
+ }
+
+}
+
+} // namespace gfx
diff --git a/ui/ui.gyp b/ui/ui.gyp
index 966bdd7..2006162 100644
--- a/ui/ui.gyp
+++ b/ui/ui.gyp
@@ -447,6 +447,7 @@
'gfx/platform_font_win.h',
'gfx/point.cc',
'gfx/point.h',
+ 'gfx/point3_f.cc',
'gfx/point3_f.h',
'gfx/point_base.h',
'gfx/point_conversions.cc',
@@ -517,6 +518,8 @@
'gfx/vector2d_conversions.h',
'gfx/vector2d_f.cc',
'gfx/vector2d_f.h',
+ 'gfx/vector3d_f.cc',
+ 'gfx/vector3d_f.h',
'gfx/video_decode_acceleration_support_mac.h',
'gfx/video_decode_acceleration_support_mac.mm',
'ui_controls/ui_controls.h',
diff --git a/ui/ui_unittests.gypi b/ui/ui_unittests.gypi
index 891df7a..6f20e42 100644
--- a/ui/ui_unittests.gypi
+++ b/ui/ui_unittests.gypi
@@ -81,6 +81,7 @@
'gfx/image/image_unittest_util_mac.mm',
'gfx/insets_unittest.cc',
'gfx/point_unittest.cc',
+ 'gfx/point3_unittest.cc',
'gfx/rect_unittest.cc',
'gfx/safe_integer_conversions_unittest.cc',
'gfx/screen_unittest.cc',
@@ -89,6 +90,7 @@
'gfx/skbitmap_operations_unittest.cc',
'gfx/skia_util_unittest.cc',
'gfx/vector2d_unittest.cc',
+ 'gfx/vector3d_unittest.cc',
'test/run_all_unittests.cc',
'test/test_suite.cc',
'test/test_suite.h',