/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MMI_VECTOR2_H #define MMI_VECTOR2_H #include #include "util.h" namespace OHOS { namespace MMI { template class Vector2 { public: union { struct { T x_; T y_; }; T data_[2]; }; Vector2(); Vector2(T x, T y); explicit Vector2(const T* v); virtual ~Vector2(); Vector2 Normalized() const; T Dot(const Vector2& other) const; T Cross(const Vector2& other) const; Vector2 operator-() const; Vector2 operator-(const Vector2& other) const; Vector2 operator+(const Vector2& other) const; Vector2 operator/(T scale) const; Vector2 operator*(T scale) const; Vector2 operator*(const Vector2& other) const; Vector2& operator*=(const Vector2& other); Vector2& operator+=(const Vector2& other); Vector2& operator=(const Vector2& other); T operator[](int index) const; T& operator[](int index); bool operator==(const Vector2& other) const; bool operator!=(const Vector2& other) const; bool IsNearEqual(const Vector2& other, T threshold = std::numeric_limits::epsilon()) const; T* GetData(); T GetLength() const; T GetSqrLength() const; T Normalize(); bool IsInfinite() const; bool IsNaN() const; }; typedef Vector2 UIPoint; typedef Vector2 Vector2f; typedef Vector2 Vector2d; template Vector2::Vector2() {} template Vector2::Vector2(T x, T y) { data_[0] = x; data_[1] = y; } template Vector2::Vector2(const T* v) { data_[0] = v[0]; data_[1] = v[1]; } template Vector2::~Vector2() {} template Vector2 Vector2::Normalized() const { Vector2 rNormalize(*this); rNormalize.Normalize(); return rNormalize; } template T Vector2::Dot(const Vector2& other) const { const T* oData = other.data_; T sum = data_[0] * oData[0]; sum += data_[1] * oData[1]; return sum; } template T Vector2::Cross(const Vector2& other) const { const T* oData = other.data_; return data_[0] * oData[1] - data_[1] * oData[0]; } template Vector2 Vector2::operator-() const { Vector2 rNeg; T* rData = rNeg.data_; rData[0] = -data_[0]; rData[1] = -data_[1]; return rNeg; } template Vector2 Vector2::operator-(const Vector2& other) const { Vector2 rSub(*this); T* rData = rSub.data_; const T* oData = other.data_; rData[0] -= oData[0]; rData[1] -= oData[1]; return rSub; } template Vector2 Vector2::operator+(const Vector2& other) const { Vector2 rAdd(*this); return rAdd += other; } template Vector2 Vector2::operator/(T scale) const { if (MMI_EQ(scale, 0)) { return *this; } const T invScale = 1.0f / scale; return (*this) * invScale; } template Vector2 Vector2::operator*(T scale) const { Vector2 rMult(*this); T* rData = rMult.data_; rData[0] *= scale; rData[1] *= scale; return rMult; } template Vector2 Vector2::operator*(const Vector2& other) const { Vector2 rMult(*this); return rMult *= other; } template Vector2& Vector2::operator*=(const Vector2& other) { const T* oData = other.data_; data_[0] *= oData[0]; data_[1] *= oData[1]; return *this; } template Vector2& Vector2::operator+=(const Vector2& other) { data_[0] += other.data_[0]; data_[1] += other.data_[1]; return *this; } template Vector2& Vector2::operator=(const Vector2& other) { const T* oData = other.data_; data_[0] = oData[0]; data_[1] = oData[1]; return *this; } template T Vector2::operator[](int index) const { return data_[index]; } template inline T& Vector2::operator[](int index) { return data_[index]; } template inline bool Vector2::operator==(const Vector2& other) const { const T* oData = other.data_; return (MMI_EQ(data_[0], oData[0])) && (MMI_EQ(data_[1], oData[1])); } template inline bool Vector2::operator!=(const Vector2& other) const { const T* oData = other.data_; return (!MMI_EQ(data_[0], oData[0])) || (!MMI_EQ(data_[1], oData[1])); } template bool Vector2::IsNearEqual(const Vector2& other, T threshold) const { const T* otherData = other.data_; return (MMI_EQ(data_[0], otherData[0], threshold)) && (MMI_EQ(data_[1], otherData[1], threshold)); } template inline T* Vector2::GetData() { return data_; } template T Vector2::GetLength() const { return sqrt(GetSqrLength()); } template T Vector2::GetSqrLength() const { T sum = data_[0] * data_[0]; sum += data_[1] * data_[1]; return sum; } template T Vector2::Normalize() { T l = GetLength(); if (MMI_EQ(l, 0.0)) { return 0.0f; } const T invLen = 1.0f / l; data_[0] *= invLen; data_[1] *= invLen; return l; } template bool Vector2::IsInfinite() const { return std::isinf(data_[0]) || std::isinf(data_[1]); } template bool Vector2::IsNaN() const { return IsNan(data_[0]) || IsNan(data_[1]); } } // namespace Rosen } // namespace OHOS #endif // RENDER_SERVICE_CLIENT_CORE_COMMON_RS_VECTOR2_H