1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_QUATERNION_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_QUATERNION_H
18 
19 #include "base/utils/utils.h"
20 
21 namespace OHOS::Ace {
22 
23 class Quaternion {
24 public:
25     Quaternion() = default;
Quaternion(double x,double y,double z,double w)26     Quaternion(double x, double y, double z, double w) : x_(x), y_(y), z_(z), w_(w) {}
27     ~Quaternion() = default;
28 
GetX()29     double GetX() const
30     {
31         return x_;
32     }
GetY()33     double GetY() const
34     {
35         return y_;
36     }
GetZ()37     double GetZ() const
38     {
39         return z_;
40     }
GetW()41     double GetW() const
42     {
43         return w_;
44     }
SetX(double x)45     void SetX(double x)
46     {
47         x_ = x;
48     }
SetY(double y)49     void SetY(double y)
50     {
51         y_ = y;
52     }
SetZ(double z)53     void SetZ(double z)
54     {
55         z_ = z;
56     }
SetW(double w)57     void SetW(double w)
58     {
59         w_ = w;
60     }
61 
62     Quaternion operator+(const Quaternion& q) const
63     {
64         auto x = this->x_ + q.x_;
65         auto y = this->y_ + q.y_;
66         auto z = this->z_ + q.z_;
67         auto w = this->w_ + q.w_;
68         return Quaternion(x, y, z, w);
69     }
70 
71     Quaternion operator*(const Quaternion& q) const
72     {
73         auto x = w_ * q.x_ + x_ * q.w_ + y_ * q.z_ - z_ * q.y_;
74         auto y = w_ * q.y_ - x_ * q.z_ + y_ * q.w_ + z_ * q.x_;
75         auto z = w_ * q.z_ + x_ * q.y_ - y_ * q.x_ + z_ * q.w_;
76         auto w = w_ * q.w_ - x_ * q.x_ - y_ * q.y_ - z_ * q.z_;
77         return Quaternion(x, y, z, w);
78     }
79 
80     bool operator==(const Quaternion& q) const
81     {
82         return NearEqual(x_, q.x_) && NearEqual(y_, q.y_)
83             && NearEqual(z_, q.z_) && NearEqual(w_, q.w_);
84     }
85 
86     bool operator!=(const Quaternion& q) const
87     {
88         return !operator==(q);
89     }
90 
inverse()91     Quaternion inverse() const
92     {
93         return { -x_, -y_, -z_, w_ };
94     }
95 
flip()96     Quaternion flip() const
97     {
98         return { -x_, -y_, -z_, -w_ };
99     }
100 
101     // Blends with the given quaternion, |q|, via spherical linear interpolation.
102     // Values of |t| in the range [0, 1] will interpolate between |this| and |q|,
103     // and values outside that range will extrapolate beyond in either direction.
104     Quaternion Slerp(const Quaternion& q, double t) const;
105 
106 private:
107     double x_ = 0.0;
108     double y_ = 0.0;
109     double z_ = 0.0;
110     double w_ = 0.0;
111 };
112 
113 // |s| is an arbitrary, real constant.
114 inline Quaternion operator*(const Quaternion& q, double s)
115 {
116     return Quaternion(q.GetX() * s, q.GetY() * s, q.GetZ() * s, q.GetW() * s);
117 }
118 
119 // |s| is an arbitrary, real constant.
120 inline Quaternion operator*(double s, const Quaternion& q)
121 {
122     return Quaternion(q.GetX() * s, q.GetY() * s, q.GetZ() * s, q.GetW() * s);
123 }
124 
125 } // namespace OHOS::Ace
126 
127 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_QUATERNION_H
128