File NPVector2D.h
File List > core > NPVector2D.h
Go to the documentation of this file
#ifndef NPVector2D_h
#define NPVector2D_h
#include "NPCoordinateType.h"
#include <iostream>
namespace nptool {
template <typename T> class Vector2D {
public:
Vector2D() : m_A(0), m_B(0), m_coord(cartesian){};
Vector2D(T A, T B, coord_type type = cartesian) : m_A(A), m_B(B), m_coord(type){};
~Vector2D(){};
private:
T m_A;
T m_B;
coord_type m_coord;
public:
inline void SetXY(T X, T Y) {
m_coord = cartesian;
m_A = X;
m_B = Y;
};
inline void SetRPhi(T R, T Phi) {
m_coord = polar;
m_A = R;
m_B = Phi;
};
inline const coord_type GetCoordinateSystem() { return m_coord; }
inline T X() const {
if (m_coord == cartesian)
return m_A;
else {
return (m_A * cos(m_B));
}
};
inline T Y() const {
if (m_coord == cartesian)
return m_B;
else {
return (m_A * sin(m_B));
}
};
inline T R() const {
if (m_coord == polar)
return m_A;
else {
return sqrt(m_A * m_A + m_B * m_B);
}
}
inline T Phi() const {
if (m_coord == polar)
return m_B;
else {
return atan(m_A * m_A + m_B * m_B);
}
}
inline Vector2D<T> Unit() const {
auto result = *this;
if (result.m_coord == polar) {
result.m_A = 1;
}
else {
auto R0 = R();
result.m_A /= R0;
result.m_B /= R0;
}
return result;
}
inline void to_polar() {
if (m_coord == polar)
return;
else {
auto R0 = R();
m_B = Phi();
m_A = R0;
m_coord = polar;
}
return;
}
inline void to_cartesian() {
if (m_coord == cartesian)
return;
else {
auto X0 = X();
m_B = Y();
m_A = X0;
m_coord = cartesian;
}
return;
}
template <typename TO> T dot(const Vector2D<TO>& right) { return (X() * right.X()) + (Y() * right.Y()); }
template <typename TO> T cross(const Vector2D<TO>& right) { return (X() * right.Y()) - (Y() * right.X()); }
// Operator
friend std::ostream& operator<<(std::ostream& os, const Vector2D<T>& v) {
if (v.m_coord == cartesian)
os << "(X=" << v.m_A << ";Y=" << v.m_B << ")";
else
os << "(R=" << v.m_A << ";P=" << v.m_B << ")";
return os;
}
// Add
template <typename TO> friend Vector2D<T> operator+(const Vector2D<T>& left, const Vector2D<TO>& right) {
return Vector2D<T>(left.X() + right.X(), left.Y() + right.Y(), cartesian);
}
template <typename TO> friend Vector2D<T>& operator+=(Vector2D<T>& left, const Vector2D<TO>& right) {
auto X0 = left.X() + right.X();
auto Y0 = left.Y() + right.Y();
left.m_coord = cartesian;
left.m_A = X0;
left.m_B = Y0;
return left;
}
// Substract
template <typename TO> friend Vector2D<T> operator-(const Vector2D<T>& left, const Vector2D<TO>& right) {
return Vector2D<T>(left.X() - right.X(), left.Y() - right.Y(), cartesian);
}
template <typename TO> friend Vector2D<T>& operator-=(Vector2D<T>& left, const Vector2D<TO>& right) {
auto X0 = left.X() - right.X();
auto Y0 = left.Y() - right.Y();
left.m_coord = cartesian;
left.m_A = X0;
left.m_B = Y0;
return left;
}
// Scale
template <typename TO> friend Vector2D<T>& operator*=(Vector2D<T>& left, const TO right) {
left.m_A *= right;
if (left.m_coord == cartesian) {
left.m_B *= right;
}
return left;
}
template <typename TO> friend Vector2D<T>& operator/=(Vector2D<T>& left, const TO right) {
left.m_A /= right;
if (left.m_coord == cartesian) {
left.m_B /= right;
}
return left;
}
};
} // namespace nptool
#endif