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