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