#ifndef _POINT_H_
#define _POINT_H_
#include <vDEC/include/vdec_types.h>
#include <vDEC/include/Vector.h>
#include <iostream>
struct Pt2{ union{
real e[2];
struct{
real x, y;
} component;
}; inline static const Pt2 Origin(); inline static const Pt2 PositiveInfinity(); inline static const Pt2 NegativeInfinity();
inline Pt2();
inline Pt2(const real &a, const real &b);
inline Pt2(const Pt2 &P);
inline Pt2& operator +=(const Vec2 &V);
inline Pt2& operator +=(const Pt2 &Q);
inline Pt2& operator *=(const real &C);
inline Pt2& operator -=(const Vec2 &V);
inline Pt2& operator /=(const real &C); inline operator real*( ); inline operator const real*( ) const; inline static int Order(const Pt2 &P0, const Pt2 &P1);
};
inline bool operator<(const Pt2 &A, const Pt2 &B);
inline bool operator>(const Pt2 &A, const Pt2 &B);
inline Vec2 operator-(const Pt2 &A, const Pt2 &B);
inline Pt2 operator-(const Pt2 &P, const Vec2 &V);
inline Pt2 operator-(const Pt2 &P);
inline Pt2 operator+(const Pt2 &P, const Vec2 &D);
inline Pt2 operator+(const Pt2 &P, const Pt2 &Q);
inline Pt2 operator*(const real &C, const Pt2 &P);
struct Pt3{
union{
real e[3];
struct{
real x, y, z;
} components;
}; inline static const Pt3 Origin(); inline static const Pt3 PositiveInfinity(); inline static const Pt3 NegativeInfinity();
inline Pt3();
inline Pt3(real a, real b, real c);
inline Pt3(const Pt3 &P);
inline Pt3& operator +=(const Vec3 &V);
inline Pt3& operator +=(const Pt3 &Q);
inline Pt3& operator *=(const real &C);
inline Pt3& operator -=(const Vec3 &V);
inline Pt3& operator /=(const real &C); inline operator real*( ); inline operator const real*( ) const;
};
inline Vec3 operator-(const Pt3 &A, const Pt3 &B);
inline Pt3 operator-(const Pt3 &P, const Vec3 &V);
inline Pt3 operator-(const Pt3 &P);
inline Pt3 operator+(const Pt3 &P, const Vec3 &D);
inline Pt3 operator+(const Pt3 &P, const Pt3 &Q);
inline Pt3 operator*(const real &C, const Pt3 &P);
inline std::ostream& operator<< (std::ostream& os, const Pt3 &P);
template <unsigned int N>
struct Pt{
real e[N];
Pt(){ for(unsigned int i = 0; i < N; ++i){ e[i] = 0; } }
Pt(const Pt<N> &P){ for(unsigned int i = 0; i < N; ++i){ e[i] = P.e[i]; } }
Pt<N>& operator +=(const Vec<N> &V){ for(unsigned int i = 0; i < N; ++i){ e[i] += V.e[i]; } return *this; }
Pt<N>& operator +=(const Pt<N> &Q){ for(unsigned int i = 0; i < N; ++i){ e[i] += Q.e[i]; } return *this; }
Pt<N>& operator *=(const real &C){ for(unsigned int i = 0; i < N; ++i){ e[i] *= C; } return *this; }
Pt<N>& operator -=(const Vec<N> &V){ for(unsigned int i = 0; i < N; ++i){ e[i] -= V.e[i]; } return *this; }
Pt<N>& operator /=(const real &C){ for(unsigned int i = 0; i < N; ++i){ e[i] /= C; } return *this; }
};
template <unsigned int N>
Vec<N> operator-(const Pt<N> &A, const Pt<N> &B){
Vec<N> Result;
for(unsigned int i = 0; i < N; ++i){
Result.e[i] = A.e[i] - B.e[i];
}
return Result;
}
template <unsigned int N>
Pt<N> operator-(const Pt<N> &P, const Vec<N> &V){
Pt<N> Result;
for(unsigned int i = 0; i < N; ++i){
Result.e[i] = P.e[i] - V.e[i];
}
return Result;
}
template <unsigned int N>
Pt<N> operator-(const Pt<N> &P){
Pt<N> Result;
for(unsigned int i = 0; i < N; ++i){
Result.e[i] = -P.e[i];
}
return Result;
}
template <unsigned int N>
Pt<N> operator+(const Pt<N> &P, const Vec<N> &D){
Pt<N> Result;
for(unsigned int i = 0; i < N; ++i){
Result.e[i] = P.e[i] + D.e[i];
}
return Result;
}
template <unsigned int N>
Pt<N> operator+(const Pt<N> &P, const Pt<N> &Q){
Pt<N> Result;
for(unsigned int i = 0; i < N; ++i){
Result.e[i] = P.e[i] + Q.e[i];
}
return Result;
}
template <unsigned int N>
Pt<N> operator*(const real &C, const Pt<N> &P){
Pt<N> Result;
for(unsigned int i = 0; i < N; ++i){
Result.e[i] = C * P.e[i];
}
return Result;
}
const Pt2 Pt2::Origin(){ static const Pt2 O(0,0); return O; }
const Pt2 Pt2::PositiveInfinity(){ static const Pt2 inf(REAL_MAX,REAL_MAX); return inf; }
const Pt2 Pt2::NegativeInfinity(){ static const Pt2 inf(-REAL_MAX,-REAL_MAX); return inf; }
Pt2::Pt2(){
e[0] = 0;
e[1] = 0;
}
Pt2::Pt2(const real &a, const real &b){
e[0] = a;
e[1] = b;
}
Pt2::Pt2(const Pt2 &P){
e[0] = P.e[0];
e[1] = P.e[1];
}
Pt2& Pt2::operator +=(const Vec2 &V){ e[0] += V.x; e[1] += V.y; return *this; }
Pt2& Pt2::operator +=(const Pt2 &Q){ e[0] += Q.e[0]; e[1] += Q.e[1]; return *this; }
Pt2& Pt2::operator *=(const real &C){ e[0] *= C; e[1] *= C; return *this; }
Pt2& Pt2::operator -=(const Vec2 &V){ e[0] -= V.x; e[1] -= V.y; return *this; }
Pt2& Pt2::operator /=(const real &C){ e[0] /= C; e[1] /= C; return *this; }
Pt2::operator real*( ){ return (real*)e; }
Pt2::operator const real*( ) const{ return (real*)(const real *)e; }
int Pt2::Order(const Pt2 &P0, const Pt2 &P1){ if (P0.e[0] > P1.e[0]) return 1;
if (P0.e[0] < P1.e[0]) return (-1); if (P0.e[1] > P1.e[1]) return 1;
if (P0.e[1] < P1.e[1]) return (-1); return 0;}
bool operator<(const Pt2 &A, const Pt2 &B){
return (A.e[0] < B.e[0] && A.e[1] < B.e[1]);
}
bool operator>(const Pt2 &A, const Pt2 &B){
return (A.e[0] > B.e[0] && A.e[1] > B.e[1]);
}
Vec2 operator-(const Pt2 &A, const Pt2 &B){
return Vec2(A.e[0]-B.e[0], A.e[1]-B.e[1]);
}
Pt2 operator-(const Pt2 &P, const Vec2 &V){
return Pt2(P.e[0]-V.x, P.e[1]-V.y);
}
Pt2 operator-(const Pt2 &P){
return Pt2(-P.e[0], -P.e[1]);
}
Pt2 operator+(const Pt2 &P, const Vec2 &D){
return Pt2(P.e[0] + D.x, P.e[1] + D.y);
}
Pt2 operator+(const Pt2 &P, const Pt2 &Q){
return Pt2(P.e[0] + Q.e[0], P.e[1] + Q.e[1]);
}
Pt2 operator*(const real &C, const Pt2 &P){
return Pt2(C*P.e[0], C*P.e[1]);
}
const Pt3 Pt3::Origin(){ static const Pt3 O(0,0,0); return O; }
const Pt3 Pt3::PositiveInfinity(){ static const Pt3 inf(REAL_MAX,REAL_MAX,REAL_MAX); return inf; }
const Pt3 Pt3::NegativeInfinity(){ static const Pt3 inf(-REAL_MAX,-REAL_MAX,-REAL_MAX); return inf; }
Pt3::Pt3(){
e[0] = 0;
e[1] = 0;
e[2] = 0;
}
Pt3::Pt3(real a, real b, real c){
e[0] = a;
e[1] = b;
e[2] = c;
}
Pt3::Pt3(const Pt3 &P){
e[0] = P.e[0];
e[1] = P.e[1];
e[2] = P.e[2];
}
Pt3& Pt3::operator +=(const Vec3 &V){ e[0] += V.x; e[1] += V.y; e[2] += V.z; return *this; }
Pt3& Pt3::operator +=(const Pt3 &Q){ e[0] += Q.e[0]; e[1] += Q.e[1]; e[2] += Q.e[2]; return *this; }
Pt3& Pt3::operator *=(const real &C){ e[0] *= C; e[1] *= C; e[2] *= C; return *this; }
Pt3& Pt3::operator -=(const Vec3 &V){ e[0] -= V.x; e[1] -= V.y; e[2] -= V.z; return *this; }
Pt3& Pt3::operator /=(const real &C){ e[0] /= C; e[1] /= C; e[2] /= C; return *this; }
Pt3::operator real*( ){ return (real*)e; }
Pt3::operator const real*( ) const{ return (const real*)(const real *)e; }
Vec3 operator-(const Pt3 &A, const Pt3 &B){
return Vec3(A.e[0]-B.e[0], A.e[1]-B.e[1], A.e[2]-B.e[2]);
}
Pt3 operator-(const Pt3 &P, const Vec3 &V){
return Pt3(P.e[0]-V.x, P.e[1]-V.y, P.e[2]-V.z);
}
Pt3 operator-(const Pt3 &P){
return Pt3(-P.e[0], -P.e[1], -P.e[2]);
}
Pt3 operator+(const Pt3 &P, const Vec3 &D){
return Pt3(P.e[0] + D.x, P.e[1] + D.y, P.e[2] + D.z);
}
Pt3 operator+(const Pt3 &P, const Pt3 &Q){
return Pt3(P.e[0] + Q.e[0], P.e[1] + Q.e[1], P.e[2] + Q.e[2]);
}
Pt3 operator*(const real &C, const Pt3 &P){
return Pt3(C*P.e[0], C*P.e[1], C*P.e[2]);
}
std::ostream& operator<< (std::ostream& os, const Pt3 &P){
os << '(' << P.e[0] << ' ' << P.e[1] << ' ' << P.e[2] << ')';
return os;
}
#endif