123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- // 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("[%g %g %g]", 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) {
- // Clamp the resulting value to prevent potential NANs from floating point
- // precision issues.
- return gfx::RadToDeg(std::acos(fmax(
- fmin(gfx::DotProduct(base, other) / base.Length() / other.Length(), 1.f),
- -1.f)));
- }
- 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
|