summaryrefslogtreecommitdiff
path: root/ui/gfx/geometry/vector3d_f.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/gfx/geometry/vector3d_f.cc')
-rw-r--r--ui/gfx/geometry/vector3d_f.cc108
1 files changed, 108 insertions, 0 deletions
diff --git a/ui/gfx/geometry/vector3d_f.cc b/ui/gfx/geometry/vector3d_f.cc
new file mode 100644
index 0000000000..749e330f27
--- /dev/null
+++ b/ui/gfx/geometry/vector3d_f.cc
@@ -0,0 +1,108 @@
+// 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/geometry/vector3d_f.h"
+
+#include <cmath>
+
+#include "base/strings/stringprintf.h"
+#include "ui/gfx/geometry/angle_conversions.h"
+
+namespace {
+const double kEpsilon = 1.0e-6;
+}
+
+namespace gfx {
+
+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) {
+ double dx = x_;
+ double dy = y_;
+ double dz = z_;
+ float x = static_cast<float>(dy * other.z() - dz * other.y());
+ float y = static_cast<float>(dz * other.x() - dx * other.z());
+ float z = static_cast<float>(dx * other.y() - dy * other.x());
+ x_ = x;
+ y_ = y;
+ 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();
+}
+
+Vector3dF ScaleVector3d(const Vector3dF& v,
+ float x_scale,
+ float y_scale,
+ float z_scale) {
+ Vector3dF scaled_v(v);
+ scaled_v.Scale(x_scale, y_scale, z_scale);
+ return scaled_v;
+}
+
+float AngleBetweenVectorsInDegrees(const gfx::Vector3dF& base,
+ const gfx::Vector3dF& other) {
+ return gfx::RadToDeg(
+ std::acos(gfx::DotProduct(base, other) / base.Length() / other.Length()));
+}
+
+float ClockwiseAngleBetweenVectorsInDegrees(const gfx::Vector3dF& base,
+ const gfx::Vector3dF& other,
+ const gfx::Vector3dF& normal) {
+ float angle = AngleBetweenVectorsInDegrees(base, other);
+ gfx::Vector3dF cross(base);
+ cross.Cross(other);
+
+ // If the dot product of this cross product is normal, it means that the
+ // shortest angle between |base| and |other| was counterclockwise with respect
+ // to the surface represented by |normal| and this angle must be reversed.
+ if (gfx::DotProduct(cross, normal) > 0.0f)
+ angle = 360.0f - angle;
+ return angle;
+}
+
+} // namespace gfx