point.h File Reference
Go to the documentation of this file.
Source: include/ffw/gui/point.h
/* This file is part of FineFramework project */
#ifndef FFW_GUI_POINT
#define FFW_GUI_POINT
#include <ostream>
#include <limits>
#include <cmath>
#include "constants.h"
namespace ffw {
template <class T> struct Point {
public:
T x;
T y;
inline Point() {
x = T(0);
y = T(0);
}
inline Point(T compx, T compy) {
x = compx;
y = compy;
}
inline Point(T Value) {
x = Value;
y = Value;
}
inline Point(const Point<T>& vec) {
x = vec.x;
y = vec.y;
}
inline Point(std::initializer_list<T> list) {
if (list.size() != 2) {
x = T(0);
y = T(0);
return;
}
x = *(list.begin());
y = *(list.begin() + 1);
}
inline void set(T compx, T compy) {
x = compx;
y = compy;
}
inline void set(T Value) {
x = Value;
y = Value;
}
inline void set(const Point<T>& vec) {
x = vec.x;
y = vec.y;
}
inline void set(const std::initializer_list<T>& list) {
if (list.size() == 2) {
x = *(list.begin());
y = *(list.begin() + 1);
}
}
inline ffw::Point<T> operator - () const {
return Point<T>(-x, -y);
}
inline ffw::Point<T>& operator = (const Point<T>& vec) {
x = vec.x;
y = vec.y;
return *this;
}
inline ffw::Point<T> operator + (const Point<T>& vec) const {
return Point<T>(x + vec.x, y + vec.y);
}
inline ffw::Point<T>& operator += (const Point<T>& vec) {
x += vec.x;
y += vec.y;
return *this;
}
inline ffw::Point<T> operator - (const Point<T>& vec) const {
return Point<T>(x - vec.x, y - vec.y);
}
inline ffw::Point<T>& operator -= (const Point<T>& vec) {
x -= vec.x;
y -= vec.y;
return *this;
}
inline ffw::Point<T> operator / (const Point<T>& vec) const {
return Point<T>(x / vec.x, y / vec.y);
}
inline ffw::Point<T>& operator /= (const Point<T>& vec) {
x /= vec.x;
y /= vec.y;
return *this;
}
inline ffw::Point<T> operator * (const Point<T>& vec) const {
return Point<T>(x * vec.x, y * vec.y);
}
inline ffw::Point<T>& operator *= (const Point<T>& vec) {
x *= vec.x;
y *= vec.y;
return *this;
}
inline ffw::Point<T>& operator = (const T& val) {
x = val;
y = val;
return *this;
}
inline ffw::Point<T> operator + (const T& val) const {
return Point<T>(x + val, y + val);
}
inline ffw::Point<T>& operator += (const T& val) {
x += val;
y += val;
return *this;
}
inline ffw::Point<T> operator - (const T& val) const {
return Point<T>(x - val, y - val);
}
inline ffw::Point<T>& operator -= (const T& val) {
x -= val;
y -= val;
return *this;
}
inline ffw::Point<T> operator / (const T& val) const {
return Point<T>(x / val, y / val);
}
inline ffw::Point<T>& operator /= (const T& val) {
x /= val;
y /= val;
return *this;
}
inline ffw::Point<T> operator * (const T& val) const {
return Point<T>(x * val, y * val);
}
inline ffw::Point<T>& operator *= (const T& val) {
x *= val;
y *= val;
return *this;
}
inline bool operator != (const Point<T>& vec) const {
return !(*this == vec);
}
inline bool operator == (const Point<T>& vec) const {
return (x == vec.x && y == vec.y);
}
inline ffw::Point<T>& rotate(const double deg) {
auto v = *this;
x = T(v.x*std::cos(deg*DEG_TO_RAD) - v.y*std::sin(deg*DEG_TO_RAD));
y = T(v.x*std::sin(deg*DEG_TO_RAD) + v.y*std::cos(deg*DEG_TO_RAD));
return *this;
}
inline ffw::Point<T>& rotateRad(const double rad) {
auto v = *this;
x = T(v.x*std::cos(rad) - v.y*std::sin(rad));
y = T(v.x*std::sin(rad) + v.y*std::cos(rad));
return *this;
}
inline ffw::Point<T>& normalize() {
const auto l = sqrtf(x*x + y * y);
if (l > 0) {
x = T(x / l);
y = T(y / l);
}
return *this;
}
inline ffw::Point<T>& scale(T val) {
x = x * val;
y = y * val;
return *this;
}
inline double length() const {
return sqrt(static_cast<double>(x*x + y * y));
}
inline float lengthf() const {
return sqrtf(static_cast<float>(x*x + y * y));
}
inline T lengthSqrd() const {
return (x*x + y * y);
}
T& operator [] (size_t i) {
return ((T*)&x)[i];
}
const T& operator [] (size_t i) const {
return ((T*)&x)[i];
}
template <class S>
inline operator ffw::Point<S>() const {
return ffw::Point<S>(S(x), S(y));
}
inline Point<T> round() const {
return Point<T>(std::round(x), std::round(y));
}
inline Point<T> floor() const {
return Point<T>(std::floor(x), std::floor(y));
}
inline Point<T> ceil() const {
return Point<T>(std::ceil(x), std::ceil(y));
}
#ifdef FFW_VEC4
inline Point(const Vec2<T>& vec) {
x = vec.x;
y = vec.y;
}
inline operator Vec2<T>() const {
return Vec2<T>(x, y);
}
#endif
};
typedef Point<float> Pointf;
typedef Point<int> Pointi;
typedef Point<double> Pointd;
template <class T>
inline T dot(const ffw::Point<T>& v1, const ffw::Point<T>& v2) {
return (v1.x*v2.x + v1.y*v2.y);
}
template <class T>
inline T distance(const Point<T>& v1, const Point<T>& v2) {
auto v = v2 - v1;
return static_cast<T>(v.length());
}
template <class T>
inline Point<T> middle(const Point<T>& v1, const Point<T>& v2) {
auto v = (v2 - v1) / 2.0;
return v1 + v;
}
template <class T>
inline ffw::Point<T> normalize(const Point<T>& vec) {
auto copy = vec;
copy.normalize();
return copy;
}
template <class T>
inline double angle(const ffw::Point<T>& v1, const ffw::Point<T>& v2) {
const auto dot = (v1.x*v2.x + v1.y*v2.y);
const auto v1Length = std::sqrt(v1.x*v1.x + v1.y*v1.y);
const auto v2Length = std::sqrt(v2.x*v2.x + v2.y*v2.y);
return static_cast<double>(std::acos(dot / (v1Length*v2Length))*RAD_TO_DEG);
}
template <class T>
inline double angleRad(const ffw::Point<T>& v1, const ffw::Point<T>& v2) {
const auto dot = (v1.x*v2.x + v1.y*v2.y);
const auto v1Length = std::sqrt(v1.x*v1.x + v1.y*v1.y);
const auto v2Length = std::sqrt(v2.x*v2.x + v2.y*v2.y);
return static_cast<double>(std::acos(dot / (v1Length*v2Length)));
}
template <class T>
inline std::ostream& operator << (std::ostream& os, const ffw::Point<T>& vec) {
os << vec.x << ", " << vec.y;
return os;
}
};
namespace ffw {
template<>
inline bool ffw::Point<float>::operator == (const Point<float>& vec) const {
if (fabs(x - vec.x) > std::numeric_limits<float>::epsilon())return false;
if (fabs(y - vec.y) > std::numeric_limits<float>::epsilon())return false;
return true;
}
template<>
inline bool ffw::Point<double>::operator == (const Point<double>& vec) const {
if (fabs(x - vec.x) > std::numeric_limits<double>::epsilon())return false;
if (fabs(y - vec.y) > std::numeric_limits<double>::epsilon())return false;
return true;
}
}
#endif