diff options
author | Ian Vollick <vollick@chromium.org> | 2017-06-14 10:11:03 +0900 |
---|---|---|
committer | Qijiang Fan <fqj@google.com> | 2020-06-05 06:23:35 +0900 |
commit | b3fafcc9a160d792720269b4d1e73dd134be4a9c (patch) | |
tree | 9631480a9a72a06c57f1de470d742f872da42924 /ui | |
parent | b8c2dcd82f6a109c54368ab36dc69f1504fd9294 (diff) | |
download | libchrome-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.cc | 10 | ||||
-rw-r--r-- | ui/gfx/geometry/vector3d_f.h | 4 | ||||
-rw-r--r-- | ui/gfx/geometry/vector3d_unittest.cc | 26 |
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 |