// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0.If a copy of the MPL was not distributed with this // file, You can obtain one at https ://mozilla.org/MPL/2.0/. #include "Vector2.h" #include "Angle.h" #include "FloatSingle.h" #include "Vector3.h" // #if defined(AVR) // #include // #else #include // #endif /* Vector2::Vector2() { x = 0; y = 0; } Vector2::Vector2(float _x, float _y) { x = _x; y = _y; } // Vector2::Vector2(Vec2 v) { // x = v.x; // y = v.y; // } Vector2::Vector2(Vector3 v) { x = v.Right(); // x; y = v.Forward(); // z; } Vector2::Vector2(PolarSingle p) { float horizontalRad = p.angle.InDegrees() * Deg2Rad; float cosHorizontal = cosf(horizontalRad); float sinHorizontal = sinf(horizontalRad); x = p.distance * sinHorizontal; y = p.distance * cosHorizontal; } Vector2::~Vector2() {} const Vector2 Vector2::zero = Vector2(0, 0); const Vector2 Vector2::one = Vector2(1, 1); const Vector2 Vector2::right = Vector2(1, 0); const Vector2 Vector2::left = Vector2(-1, 0); const Vector2 Vector2::up = Vector2(0, 1); const Vector2 Vector2::down = Vector2(0, -1); const Vector2 Vector2::forward = Vector2(0, 1); const Vector2 Vector2::back = Vector2(0, -1); bool Vector2::operator==(const Vector2& v) { return (this->x == v.x && this->y == v.y); } float Vector2::Magnitude(const Vector2& v) { return sqrtf(v.x * v.x + v.y * v.y); } float Vector2::magnitude() const { return (float)sqrtf(x * x + y * y); } float Vector2::SqrMagnitude(const Vector2& v) { return v.x * v.x + v.y * v.y; } float Vector2::sqrMagnitude() const { return (x * x + y * y); } Vector2 Vector2::Normalize(const Vector2& v) { float num = Vector2::Magnitude(v); Vector2 result = Vector2::zero; if (num > Float::epsilon) { result = v / num; } return result; } Vector2 Vector2::normalized() const { float num = this->magnitude(); Vector2 result = Vector2::zero; if (num > Float::epsilon) { result = ((Vector2) * this) / num; } return result; } Vector2 Vector2::operator-() { return Vector2(-this->x, -this->y); } Vector2 Vector2::operator-(const Vector2& v) const { return Vector2(this->x - v.x, this->y - v.y); } Vector2 Vector2::operator-=(const Vector2& v) { this->x -= v.x; this->y -= v.y; return *this; } Vector2 Vector2::operator+(const Vector2& v) const { return Vector2(this->x + v.x, this->y + v.y); } Vector2 Vector2::operator+=(const Vector2& v) { this->x += v.x; this->y += v.y; return *this; } Vector2 Vector2::Scale(const Vector2& v1, const Vector2& v2) { return Vector2(v1.x * v2.x, v1.y * v2.y); } // Vector2 Passer::LinearAlgebra::operator*(const Vector2 &v, float f) { // return Vector2(v.x * f, v.y * f); // } // Vector2 Passer::LinearAlgebra::operator*(float f, const Vector2 &v) { // return Vector2(v.x * f, v.y * f); // } Vector2 Vector2::operator*=(float f) { this->x *= f; this->y *= f; return *this; } // Vector2 Passer::LinearAlgebra::operator/(const Vector2 &v, float f) { // return Vector2(v.x / f, v.y / f); // } // Vector2 Passer::LinearAlgebra::operator/(float f, const Vector2 &v) { // return Vector2(v.x / f, v.y / f); // } Vector2 Vector2::operator/=(float f) { this->x /= f; this->y /= f; return *this; } float Vector2::Dot(const Vector2& v1, const Vector2& v2) { return v1.x * v2.x + v1.y * v2.y; } float Vector2::Distance(const Vector2& v1, const Vector2& v2) { return Magnitude(v1 - v2); } float Vector2::Angle(const Vector2& v1, const Vector2& v2) { return (float)fabs(SignedAngle(v1, v2)); } float Vector2::SignedAngle(const Vector2& v1, const Vector2& v2) { float sqrMagFrom = v1.sqrMagnitude(); float sqrMagTo = v2.sqrMagnitude(); if (sqrMagFrom == 0 || sqrMagTo == 0) return 0; if (!isfinite(sqrMagFrom) || !isfinite(sqrMagTo)) #if defined(AVR) return NAN; #else return nanf(""); #endif float angleFrom = atan2f(v1.y, v1.x); float angleTo = atan2f(v2.y, v2.x); return -(angleTo - angleFrom) * Rad2Deg; } Vector2 Vector2::Rotate(const Vector2& v, AngleSingle a) { float angleRad = a.InDegrees() * Deg2Rad; #if defined(AVR) float sinValue = sin(angleRad); float cosValue = cos(angleRad); // * Angle::Deg2Rad); #else float sinValue = (float)sinf(angleRad); float cosValue = (float)cosf(angleRad); #endif float tx = v.x; float ty = v.y; Vector2 r = Vector2((cosValue * tx) - (sinValue * ty), (sinValue * tx) + (cosValue * ty)); return r; } Vector2 Vector2::Lerp(const Vector2& v1, const Vector2& v2, float f) { Vector2 v = v1 + (v2 - v1) * f; return v; } */ #pragma region Vector2Of template Vector2Of::Vector2Of() {} template Vector2Of::Vector2Of(T horizontal, T vertical) : horizontal(horizontal), vertical(vertical) {} template Vector2Of Vector2Of::FromPolar(PolarOf p) { float horizontalRad = p.angle.InDegrees() * Deg2Rad; float cosHorizontal = cosf(horizontalRad); float sinHorizontal = sinf(horizontalRad); Vector2Of v; v.horizontal = p.distance * sinHorizontal; v.vertical = p.distance * cosHorizontal; return v; } template const Vector2Of Vector2Of::zero = Vector2Of(T{}, T{}); template const Vector2Of Vector2Of::forward = Vector2Of(T{}, 1); template bool LinearAlgebra::Vector2Of::operator==(const Vector2Of& v) { return (this->horizontal == v.horizontal && this->vertical == v.vertical); } template float Vector2Of::MagnitudeOf(const Vector2Of& v) { T sqr = v.horizontal * v.horizontal + v.vertical * v.vertical; float sqrFloat = static_cast(sqr); return sqrtf(sqrFloat); } template float Vector2Of::Magnitude() const { T sqr = this->horizontal * this->horizontal + this->vertical * this->vertical; float sqrFloat = static_cast(sqr); return sqrtf(sqrFloat); } template float Vector2Of::SqrMagnitudeOf(const Vector2Of& v) { T sqr = v.horizontal * v.horizontal + v.vertical * v.vertical; return static_cast(sqr); } template float Vector2Of::SqrMagnitude() const { T sqr = this->horizontal * this->horizontal + this->vertical * this->vertical; return static_cast(sqr); } template Vector2Of Vector2Of::operator-() { return Vector2Of(-this->horizontal, -this->vertical); } template Vector2Of Vector2Of::operator-(const Vector2Of& v) const { return Vector2Of(this->horizontal - v.horizontal, this->vertical - v.vertical); } template Vector2Of Vector2Of::operator-=(const Vector2Of& v) { this->horizontal -= v.horizontal; this->vertical -= v.vertical; return *this; } template Vector2Of Vector2Of::operator+(const Vector2Of& v) const { return Vector2Of(this->horizontal + v.horizontal, this->vertical + v.vertical); } template Vector2Of Vector2Of::operator+=(const Vector2Of& v) { this->horizontal += v.horizontal; this->vertical += v.vertical; return *this; } template Vector2Of Vector2Of::Scale(const Vector2Of& v1, const Vector2Of& v2) { return Vector2Of(v1.horizontal * v2.horizontal, v1.vertical * v2.vertical); } // template // Vector2Of Vector2Of::operator/=(float f) { // this->x /= f; // this->y /= f; // return *this; // } template T Vector2Of::Dot(const Vector2Of& v1, const Vector2Of& v2) { return v1.horizontal * v2.horizontal + v1.vertical * v2.vertical; } template float Vector2Of::Distance(const Vector2Of& v1, const Vector2Of& v2) { return MagnitudeOf(v1 - v2); } template Vector2Of Vector2Of::Normalize(const Vector2Of& v) { float num = Vector2Of::MagnitudeOf(v); Vector2Of result = Vector2Of::zero; if (num > Float::epsilon) { result = static_cast>(v) / num; } return result; } template AngleOf Vector2Of::UnsignedAngle(const Vector2Of& v1, const Vector2Of& v2) { return AngleOf::Abs(SignedAngle(v1, v2)); } template AngleOf Vector2Of::SignedAngle(const Vector2Of& v1, const Vector2Of& v2) { float sqrMagFrom = v1.SqrMagnitude(); float sqrMagTo = v2.SqrMagnitude(); if (sqrMagFrom == 0 || sqrMagTo == 0) return AngleOf::zero; if (!isfinite(sqrMagFrom) || !isfinite(sqrMagTo)) return AngleOf::zero; // Angle does not support NaN... AngleOf angleFrom = AngleOf::Atan2(static_cast(v1.vertical), static_cast(v1.horizontal)); AngleOf angleTo = AngleOf::Atan2(static_cast(v2.vertical), static_cast(v2.horizontal)); return -(angleTo - angleFrom); } template Vector2Of Vector2Of::Rotate(const Vector2Of& v, AngleOf a) { float sinValue = AngleOf::Sin(a); float cosValue = AngleOf::Cos(a); float tx = static_cast(v.horizontal); float ty = static_cast(v.vertical); Vector2Of r = Vector2Of((cosValue * tx) - (sinValue * ty), (sinValue * tx) + (cosValue * ty)); return r; } template Vector2Of Vector2Of::Lerp(const Vector2Of& v1, const Vector2Of& v2, float f) { Vector2Of v = v1 + static_cast>(v2 - v1) * f; return v; } // float Vector2::Angle(const Vector2& v1, const Vector2& v2) { // return (float)fabs(SignedAngle(v1, v2)); // } // float Vector2::SignedAngle(const Vector2& v1, const Vector2& v2) { // float sqrMagFrom = v1.sqrMagnitude(); // float sqrMagTo = v2.sqrMagnitude(); // if (sqrMagFrom == 0 || sqrMagTo == 0) // return 0; // if (!isfinite(sqrMagFrom) || !isfinite(sqrMagTo)) // #if defined(AVR) // return NAN; // #else // return nanf(""); // #endif // float angleFrom = atan2f(v1.y, v1.x); // float angleTo = atan2f(v2.y, v2.x); // return -(angleTo - angleFrom) * Rad2Deg; // } template Vector2Of Vector2Of::Normalized() const { float num = Vector2Of::MagnitudeOf(*this); Vector2Of result = Vector2Of::zero; if (num > Float::epsilon) { result = static_cast>(*this) / num; } return result; } // Explicit instantiation for int template class Vector2Of; template class Vector2Of; #pragma endregion Vector2Of