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