quaternion.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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
  3. // found in the LICENSE file.
  4. #ifndef UI_GFX_GEOMETRY_QUATERNION_H_
  5. #define UI_GFX_GEOMETRY_QUATERNION_H_
  6. #include <string>
  7. #include "ui/gfx/geometry/geometry_export.h"
  8. namespace gfx {
  9. class Vector3dF;
  10. class GEOMETRY_EXPORT Quaternion {
  11. public:
  12. constexpr Quaternion() = default;
  13. constexpr Quaternion(double x, double y, double z, double w)
  14. : x_(x), y_(y), z_(z), w_(w) {}
  15. Quaternion(const Vector3dF& axis, double angle);
  16. // Constructs a quaternion representing a rotation between |from| and |to|.
  17. Quaternion(const Vector3dF& from, const Vector3dF& to);
  18. static Quaternion FromAxisAngle(double x, double y, double z, double angle);
  19. constexpr double x() const { return x_; }
  20. void set_x(double x) { x_ = x; }
  21. constexpr double y() const { return y_; }
  22. void set_y(double y) { y_ = y; }
  23. constexpr double z() const { return z_; }
  24. void set_z(double z) { z_ = z; }
  25. constexpr double w() const { return w_; }
  26. void set_w(double w) { w_ = w; }
  27. Quaternion operator+(const Quaternion& q) const {
  28. return {q.x_ + x_, q.y_ + y_, q.z_ + z_, q.w_ + w_};
  29. }
  30. Quaternion operator*(const Quaternion& q) const {
  31. return {w_ * q.x_ + x_ * q.w_ + y_ * q.z_ - z_ * q.y_,
  32. w_ * q.y_ - x_ * q.z_ + y_ * q.w_ + z_ * q.x_,
  33. w_ * q.z_ + x_ * q.y_ - y_ * q.x_ + z_ * q.w_,
  34. w_ * q.w_ - x_ * q.x_ - y_ * q.y_ - z_ * q.z_};
  35. }
  36. Quaternion inverse() const { return {-x_, -y_, -z_, w_}; }
  37. Quaternion flip() const { return {-x_, -y_, -z_, -w_}; }
  38. // Blends with the given quaternion, |q|, via spherical linear interpolation.
  39. // Values of |t| in the range [0, 1] will interpolate between |this| and |q|,
  40. // and values outside that range will extrapolate beyond in either direction.
  41. Quaternion Slerp(const Quaternion& q, double t) const;
  42. // Blends with the given quaternion, |q|, via linear interpolation. This is
  43. // rarely what you want. Use only if you know what you're doing.
  44. // Values of |t| in the range [0, 1] will interpolate between |this| and |q|,
  45. // and values outside that range will extrapolate beyond in either direction.
  46. Quaternion Lerp(const Quaternion& q, double t) const;
  47. double Length() const;
  48. Quaternion Normalized() const;
  49. std::string ToString() const;
  50. private:
  51. double x_ = 0.0;
  52. double y_ = 0.0;
  53. double z_ = 0.0;
  54. double w_ = 1.0;
  55. };
  56. // |s| is an arbitrary, real constant.
  57. inline Quaternion operator*(const Quaternion& q, double s) {
  58. return Quaternion(q.x() * s, q.y() * s, q.z() * s, q.w() * s);
  59. }
  60. // |s| is an arbitrary, real constant.
  61. inline Quaternion operator*(double s, const Quaternion& q) {
  62. return Quaternion(q.x() * s, q.y() * s, q.z() * s, q.w() * s);
  63. }
  64. // |s| is an arbitrary, real constant.
  65. inline Quaternion operator/(const Quaternion& q, double s) {
  66. double inv = 1.0 / s;
  67. return q * inv;
  68. }
  69. // Returns true if the x, y, z, w values of |lhs| and |rhs| are equal. Note that
  70. // two quaternions can represent the same orientation with different values.
  71. // This operator will return false in that scenario.
  72. inline bool operator==(const Quaternion& lhs, const Quaternion& rhs) {
  73. return lhs.x() == rhs.x() && lhs.y() == rhs.y() && lhs.z() == rhs.z() &&
  74. lhs.w() == rhs.w();
  75. }
  76. inline bool operator!=(const Quaternion& lhs, const Quaternion& rhs) {
  77. return !(lhs == rhs);
  78. }
  79. } // namespace gfx
  80. #endif // UI_GFX_GEOMETRY_QUATERNION_H_