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