summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorIan Vollick <vollick@chromium.org>2017-06-14 10:11:03 +0900
committerQijiang Fan <fqj@google.com>2020-06-05 06:23:35 +0900
commitb3fafcc9a160d792720269b4d1e73dd134be4a9c (patch)
tree9631480a9a72a06c57f1de470d742f872da42924 /ui
parentb8c2dcd82f6a109c54368ab36dc69f1504fd9294 (diff)
downloadlibchrome-b3fafcc9a160d792720269b4d1e73dd134be4a9c.tar.gz
Add Vector3dF::GetNormalized
This is a common operation that can fail if the vector is too short. Bug: 718004 Change-Id: I8b379249e3d4b2bc8c500d756899064d8fbb74a5 Reviewed-on: https://chromium-review.googlesource.com/535113 Commit-Queue: Ian Vollick <vollick@chromium.org> Reviewed-by: Yash Malik <ymalik@chromium.org> Cr-Commit-Position: refs/heads/master@{#479278} CrOS-Libchrome-Original-Commit: bed672a16779591caaaa3f9f3f1814dbfc48fc16
Diffstat (limited to 'ui')
-rw-r--r--ui/gfx/geometry/vector3d_f.cc10
-rw-r--r--ui/gfx/geometry/vector3d_f.h4
-rw-r--r--ui/gfx/geometry/vector3d_unittest.cc26
3 files changed, 40 insertions, 0 deletions
diff --git a/ui/gfx/geometry/vector3d_f.cc b/ui/gfx/geometry/vector3d_f.cc
index a834047215..c516172eba 100644
--- a/ui/gfx/geometry/vector3d_f.cc
+++ b/ui/gfx/geometry/vector3d_f.cc
@@ -10,6 +10,7 @@
namespace {
const float kRadiansToDegrees = 180.0f / 3.14159265f;
+const double kEpsilon = 1.0e-6;
}
namespace gfx {
@@ -61,6 +62,15 @@ void Vector3dF::Cross(const Vector3dF& other) {
z_ = z;
}
+bool Vector3dF::GetNormalized(Vector3dF* out) const {
+ double length_squared = LengthSquared();
+ *out = *this;
+ if (length_squared < kEpsilon * kEpsilon)
+ return false;
+ out->Scale(1 / sqrt(length_squared));
+ return true;
+}
+
float DotProduct(const Vector3dF& lhs, const Vector3dF& rhs) {
return lhs.x() * rhs.x() + lhs.y() * rhs.y() + lhs.z() * rhs.z();
}
diff --git a/ui/gfx/geometry/vector3d_f.h b/ui/gfx/geometry/vector3d_f.h
index 61e6173060..0bb42b4758 100644
--- a/ui/gfx/geometry/vector3d_f.h
+++ b/ui/gfx/geometry/vector3d_f.h
@@ -71,6 +71,10 @@ class GFX_EXPORT Vector3dF {
// Take the cross product of this vector with |other| and become the result.
void Cross(const Vector3dF& other);
+ // |out| is assigned a unit-length vector in the direction of |this| iff
+ // this function returns true. It can return false if |this| is too short.
+ bool GetNormalized(Vector3dF* out) const;
+
std::string ToString() const;
private:
diff --git a/ui/gfx/geometry/vector3d_unittest.cc b/ui/gfx/geometry/vector3d_unittest.cc
index 1aaebb6a4d..12ee757346 100644
--- a/ui/gfx/geometry/vector3d_unittest.cc
+++ b/ui/gfx/geometry/vector3d_unittest.cc
@@ -318,4 +318,30 @@ TEST(Vector3dTest, ClockwiseAngleBetweenVectorsInDegress) {
}
}
+TEST(Vector3dTest, GetNormalized) {
+ const struct {
+ bool expected;
+ gfx::Vector3dF v;
+ gfx::Vector3dF normalized;
+ } tests[] = {
+ {false, gfx::Vector3dF(0, 0, 0), gfx::Vector3dF(0, 0, 0)},
+ {false,
+ gfx::Vector3dF(std::numeric_limits<float>::min(),
+ std::numeric_limits<float>::min(),
+ std::numeric_limits<float>::min()),
+ gfx::Vector3dF(std::numeric_limits<float>::min(),
+ std::numeric_limits<float>::min(),
+ std::numeric_limits<float>::min())},
+ {true, gfx::Vector3dF(1, 0, 0), gfx::Vector3dF(1, 0, 0)},
+ {true, gfx::Vector3dF(std::numeric_limits<float>::max(), 0, 0),
+ gfx::Vector3dF(1, 0, 0)},
+ };
+
+ for (size_t i = 0; i < arraysize(tests); ++i) {
+ gfx::Vector3dF n;
+ EXPECT_EQ(tests[i].expected, tests[i].v.GetNormalized(&n));
+ EXPECT_EQ(tests[i].normalized.ToString(), n.ToString());
+ }
+}
+
} // namespace gfx