| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/geometry/quaternion.h" | 5 #include "ui/gfx/geometry/quaternion.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 Quaternion Quaternion::Slerp(const Quaternion& q, double t) const { | 59 Quaternion Quaternion::Slerp(const Quaternion& q, double t) const { |
| 60 double dot = x_ * q.x_ + y_ * q.y_ + z_ * q.z_ + w_ * q.w_; | 60 double dot = x_ * q.x_ + y_ * q.y_ + z_ * q.z_ + w_ * q.w_; |
| 61 | 61 |
| 62 // Clamp dot to -1.0 <= dot <= 1.0. | 62 // Clamp dot to -1.0 <= dot <= 1.0. |
| 63 dot = std::min(std::max(dot, -1.0), 1.0); | 63 dot = std::min(std::max(dot, -1.0), 1.0); |
| 64 | 64 |
| 65 // Quaternions are facing the same direction. | 65 // Quaternions are facing the same direction. |
| 66 if (std::abs(dot - 1.0) < kEpsilon || std::abs(dot + 1.0) < kEpsilon) | 66 if (std::abs(dot - 1.0) < kEpsilon || std::abs(dot + 1.0) < kEpsilon) |
| 67 return *this; | 67 return *this; |
| 68 | 68 |
| 69 // TODO(vmpstr): In case the dot is 0, the vectors are exactly opposite | |
| 70 // of each other. In this case, it's technically not correct to just pick one | |
| 71 // of the vectors, we instead need to pick how to interpolate. However, the | |
| 72 // spec isn't clear on this. If we don't handle the -1 case explicitly, it | |
| 73 // results in inf and nans however, which is worse. See crbug.com/506543 for | |
| 74 // more discussion. | |
| 75 if (std::abs(dot) < kEpsilon) | |
| 76 return *this; | |
| 77 | |
| 78 double denom = std::sqrt(1.0 - dot * dot); | 69 double denom = std::sqrt(1.0 - dot * dot); |
| 79 double theta = std::acos(dot); | 70 double theta = std::acos(dot); |
| 80 double w = std::sin(t * theta) * (1.0 / denom); | 71 double w = std::sin(t * theta) * (1.0 / denom); |
| 81 | 72 |
| 82 double s1 = std::cos(t * theta) - dot * w; | 73 double s1 = std::cos(t * theta) - dot * w; |
| 83 double s2 = w; | 74 double s2 = w; |
| 84 | 75 |
| 85 return (s1 * *this) + (s2 * q); | 76 return (s1 * *this) + (s2 * q); |
| 86 } | 77 } |
| 87 | 78 |
| 88 Quaternion Quaternion::Lerp(const Quaternion& q, double t) const { | 79 Quaternion Quaternion::Lerp(const Quaternion& q, double t) const { |
| 89 return (((1.0 - t) * *this) + (t * q)).Normalized(); | 80 return (((1.0 - t) * *this) + (t * q)).Normalized(); |
| 90 } | 81 } |
| 91 | 82 |
| 92 Quaternion Quaternion::Normalized() const { | 83 Quaternion Quaternion::Normalized() const { |
| 93 double length = x_ * x_ + y_ * y_ + z_ * z_ + w_ * w_; | 84 double length = x_ * x_ + y_ * y_ + z_ * z_ + w_ * w_; |
| 94 if (length < kEpsilon) | 85 if (length < kEpsilon) |
| 95 return *this; | 86 return *this; |
| 96 return *this / sqrt(length); | 87 return *this / sqrt(length); |
| 97 } | 88 } |
| 98 | 89 |
| 99 std::string Quaternion::ToString() const { | 90 std::string Quaternion::ToString() const { |
| 100 return base::StringPrintf("[%f %f %f %f]", x_, y_, z_, w_); | 91 return base::StringPrintf("[%f %f %f %f]", x_, y_, z_, w_); |
| 101 } | 92 } |
| 102 | 93 |
| 103 } // namespace gfx | 94 } // namespace gfx |
| OLD | NEW |