1 /*
2  * Copyright (c) 2021-2023 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 RENDER_SERVICE_CLIENT_CORE_COMMON_RS_VECTOR2_H
17 #define RENDER_SERVICE_CLIENT_CORE_COMMON_RS_VECTOR2_H
18 #include <cmath>
19 
20 #include "common/rs_common_def.h"
21 
22 namespace OHOS {
23 namespace Rosen {
24 template<typename T>
25 class Vector2 {
26 public:
27     union {
28         struct {
29             T x_;
30             T y_;
31         };
32         T data_[2];
33     };
34 
35     Vector2();
36     Vector2(T x, T y);
37     explicit Vector2(const T* v);
38     virtual ~Vector2();
39 
40     Vector2 Normalized() const;
41     T Dot(const Vector2<T>& other) const;
42     T Cross(const Vector2<T>& other) const;
43     Vector2 operator-() const;
44     Vector2 operator-(const Vector2<T>& other) const;
45     Vector2 operator+(const Vector2<T>& other) const;
46     Vector2 operator/(T scale) const;
47     Vector2 operator*(T scale) const;
48     Vector2 operator*(const Vector2<T>& other) const;
49     Vector2& operator*=(const Vector2<T>& other);
50     Vector2& operator+=(const Vector2<T>& other);
51     Vector2& operator-=(const Vector2<T>& other);
52     Vector2& operator=(const Vector2& other);
53     T operator[](int index) const;
54     T& operator[](int index);
55     bool operator==(const Vector2& other) const;
56     bool operator!=(const Vector2& other) const;
57     bool IsNearEqual(const Vector2& other, T threshold = std::numeric_limits<T>::epsilon()) const;
58 
59     T* GetData();
60 
61     T GetLength() const;
62     T GetSqrLength() const;
63     T Normalize();
64     bool IsInfinite() const;
65     bool IsNaN() const;
66 };
67 
68 typedef Vector2<int> UIPoint;
69 typedef Vector2<float> Vector2f;
70 typedef Vector2<double> Vector2d;
71 template<typename T>
Vector2()72 Vector2<T>::Vector2()
73 {
74     data_[0] = 0;
75     data_[1] = 0;
76 }
77 
78 template<typename T>
Vector2(T x,T y)79 Vector2<T>::Vector2(T x, T y)
80 {
81     data_[0] = x;
82     data_[1] = y;
83 }
84 
85 template<typename T>
Vector2(const T * v)86 Vector2<T>::Vector2(const T* v)
87 {
88     data_[0] = v[0];
89     data_[1] = v[1];
90 }
91 
92 template<typename T>
~Vector2()93 Vector2<T>::~Vector2()
94 {}
95 
96 template<typename T>
Normalized()97 Vector2<T> Vector2<T>::Normalized() const
98 {
99     Vector2<T> rNormalize(*this);
100     rNormalize.Normalize();
101     return rNormalize;
102 }
103 
104 template<typename T>
Dot(const Vector2<T> & other)105 T Vector2<T>::Dot(const Vector2<T>& other) const
106 {
107     const T* oData = other.data_;
108     T sum = data_[0] * oData[0];
109     sum += data_[1] * oData[1];
110     return sum;
111 }
112 
113 template<typename T>
Cross(const Vector2<T> & other)114 T Vector2<T>::Cross(const Vector2<T>& other) const
115 {
116     const T* oData = other.data_;
117 
118     return data_[0] * oData[1] - data_[1] * oData[0];
119 }
120 
121 template<typename T>
122 Vector2<T> Vector2<T>::operator-() const
123 {
124     Vector2<T> rNeg;
125     T* rData = rNeg.data_;
126     rData[0] = -data_[0];
127     rData[1] = -data_[1];
128     return rNeg;
129 }
130 
131 template<typename T>
132 Vector2<T> Vector2<T>::operator-(const Vector2<T>& other) const
133 {
134     Vector2<T> rSub(*this);
135     T* rData = rSub.data_;
136     const T* oData = other.data_;
137     rData[0] -= oData[0];
138     rData[1] -= oData[1];
139     return rSub;
140 }
141 
142 template<typename T>
143 Vector2<T> Vector2<T>::operator+(const Vector2<T>& other) const
144 {
145     Vector2<T> rAdd(*this);
146     return rAdd += other;
147 }
148 
149 template<typename T>
150 Vector2<T> Vector2<T>::operator/(T scale) const
151 {
152     if (ROSEN_EQ<T>(scale, 0)) {
153         return *this;
154     }
155     const T invScale = 1.0f / scale;
156     return (*this) * invScale;
157 }
158 
159 template<typename T>
160 Vector2<T> Vector2<T>::operator*(T scale) const
161 {
162     Vector2<T> rMult(*this);
163     T* rData = rMult.data_;
164 
165     rData[0] *= scale;
166     rData[1] *= scale;
167     return rMult;
168 }
169 
170 template<typename T>
171 Vector2<T> Vector2<T>::operator*(const Vector2<T>& other) const
172 {
173     Vector2<T> rMult(*this);
174     return rMult *= other;
175 }
176 
177 template<typename T>
178 Vector2<T>& Vector2<T>::operator*=(const Vector2<T>& other)
179 {
180     const T* oData = other.data_;
181     data_[0] *= oData[0];
182     data_[1] *= oData[1];
183     return *this;
184 }
185 
186 template<typename T>
187 Vector2<T>& Vector2<T>::operator+=(const Vector2<T>& other)
188 {
189     data_[0] += other.data_[0];
190     data_[1] += other.data_[1];
191     return *this;
192 }
193 
194 template<typename T>
195 Vector2<T>& Vector2<T>::operator-=(const Vector2<T>& other)
196 {
197     data_[0] -= other.data_[0];
198     data_[1] -= other.data_[1];
199     return *this;
200 }
201 
202 template<typename T>
203 Vector2<T>& Vector2<T>::operator=(const Vector2<T>& other)
204 {
205     const T* oData = other.data_;
206     data_[0] = oData[0];
207     data_[1] = oData[1];
208     return *this;
209 }
210 
211 template<typename T>
212 T Vector2<T>::operator[](int index) const
213 {
214     return data_[index];
215 }
216 
217 template<typename T>
218 inline T& Vector2<T>::operator[](int index)
219 {
220     return data_[index];
221 }
222 
223 template<typename T>
224 inline bool Vector2<T>::operator==(const Vector2& other) const
225 {
226     const T* oData = other.data_;
227 
228     return (ROSEN_EQ<T>(data_[0], oData[0])) && (ROSEN_EQ<T>(data_[1], oData[1]));
229 }
230 
231 template<typename T>
232 inline bool Vector2<T>::operator!=(const Vector2& other) const
233 {
234     const T* oData = other.data_;
235 
236     return (!ROSEN_EQ<T>(data_[0], oData[0])) || (!ROSEN_EQ<T>(data_[1], oData[1]));
237 }
238 
239 template<typename T>
IsNearEqual(const Vector2 & other,T threshold)240 bool Vector2<T>::IsNearEqual(const Vector2& other, T threshold) const
241 {
242     const T* otherData = other.data_;
243 
244     return (ROSEN_EQ<T>(data_[0], otherData[0], threshold)) && (ROSEN_EQ<T>(data_[1], otherData[1], threshold));
245 }
246 
247 template<typename T>
GetData()248 inline T* Vector2<T>::GetData()
249 {
250     return data_;
251 }
252 
253 template<typename T>
GetLength()254 T Vector2<T>::GetLength() const
255 {
256     return sqrt(GetSqrLength());
257 }
258 
259 template<typename T>
GetSqrLength()260 T Vector2<T>::GetSqrLength() const
261 {
262     T sum = data_[0] * data_[0];
263     sum += data_[1] * data_[1];
264     return sum;
265 }
266 
267 template<typename T>
Normalize()268 T Vector2<T>::Normalize()
269 {
270     T l = GetLength();
271     if (ROSEN_EQ<T>(l, 0.0)) {
272         return 0.0f;
273     }
274 
275     const T invLen = 1.0f / l;
276 
277     data_[0] *= invLen;
278     data_[1] *= invLen;
279     return l;
280 }
281 
282 template<typename T>
IsInfinite()283 bool Vector2<T>::IsInfinite() const
284 {
285     return std::isinf(data_[0]) || std::isinf(data_[1]);
286 }
287 
288 template<typename T>
IsNaN()289 bool Vector2<T>::IsNaN() const
290 {
291     return IsNan(data_[0]) || IsNan(data_[1]);
292 }
293 } // namespace Rosen
294 } // namespace OHOS
295 #endif // RENDER_SERVICE_CLIENT_CORE_COMMON_RS_VECTOR2_H
296