1 #ifndef __GNUC__
2 #pragma once
3 #endif
4 #ifndef __XR_VECTOR2_H__
5 #define __XR_VECTOR2_H__
6
7 #include "xr_types.h"
8 #include "xr_math.h"
9
10 namespace xray_re {
11
12 template<typename T> struct _vector2 {
13 template<typename F> _vector2<T>& set(const _vector2<F>& a);
14
15 _vector2<T>& set(T _x = T(), T _y = T());
16 _vector2<T>& set(const T _xy[2]);
17 void get(T _xy[2]) const;
18 T magnitude() const;
19 T distance(const _vector2<T>& a) const;
20 bool similar(const _vector2<T>& a, T e = T(1e-6)) const;
21 _vector2<T>& min(const _vector2<T>& a);
22 _vector2<T>& max(const _vector2<T>& a);
23 _vector2<T>& add(const _vector2<T>& a);
24 _vector2<T>& sub(const _vector2<T>& a, const _vector2<T>& b);
25 _vector2<T>& mul(T s);
26 int compare(const _vector2<T>& right) const;
27 bool operator<(const _vector2<T>& right) const;
28 bool operator==(const _vector2<T>& right) const;
29 bool operator!=(const _vector2<T>& right) const;
30 T& operator[](size_t i);
31 const T& operator[](size_t i) const;
32
33 union {
34 struct {
35 T x, y;
36 };
37 struct {
38 T u, v;
39 };
40 T xy[2];
41 };
42 };
43
44 typedef _vector2<float> fvector2;
45 typedef _vector2<double> dvector2;
46 typedef _vector2<int32_t> i32vector2;
47
set(const _vector2<F> & a)48 template<typename T> template<typename F> inline _vector2<T>& _vector2<T>::set(const _vector2<F>& a)
49 {
50 x = T(a.x);
51 y = T(a.y);
52 return *this;
53 }
54
set(T _x,T _y)55 template<typename T> inline _vector2<T>& _vector2<T>::set(T _x, T _y) { x = _x; y = _y; return *this; }
56
set(const T _xy[2])57 template<typename T> inline _vector2<T>& _vector2<T>::set(const T _xy[2])
58 {
59 x = _xy[0];
60 y = _xy[1];
61 return *this;
62 }
63
get(T _xy[2])64 template<typename T> inline void _vector2<T>::get(T _xy[2]) const
65 {
66 _xy[0] = x;
67 _xy[1] = y;
68 }
69
magnitude()70 template<typename T> inline T _vector2<T>::magnitude() const { return std::sqrt(x*x + y*y); }
71
distance(const _vector2<T> & a)72 template<typename T> inline T _vector2<T>::distance(const _vector2<T>& a) const
73 {
74 T dx = a.x - x, dy = a.y - y;
75 return std::sqrt(dx*dx + dy*dy);
76 }
77
similar(const _vector2<T> & a,T e)78 template<typename T> bool _vector2<T>::similar(const _vector2<T>& a, T e) const
79 {
80 if (e <= std::abs(a.x - x))
81 return false;
82 if (e <= std::abs(a.y - y))
83 return false;
84 return true;
85 }
86
min(const _vector2<T> & a)87 template<typename T> inline _vector2<T>& _vector2<T>::min(const _vector2<T>& a)
88 {
89 if (x >= a.x)
90 x = a.x;
91 if (y >= a.y)
92 y = a.y;
93 return *this;
94 }
95
max(const _vector2<T> & a)96 template<typename T> inline _vector2<T>& _vector2<T>::max(const _vector2<T>& a)
97 {
98 if (x < a.x)
99 x = a.x;
100 if (y < a.y)
101 y = a.y;
102 return *this;
103 }
104
add(const _vector2<T> & a)105 template<typename T> inline _vector2<T>& _vector2<T>::add(const _vector2<T>& a)
106 {
107 x += a.x;
108 y += a.y;
109 return *this;
110 }
111
sub(const _vector2<T> & a,const _vector2<T> & b)112 template<typename T> inline _vector2<T>& _vector2<T>::sub(const _vector2<T>& a, const _vector2<T>& b)
113 {
114 x = a.x - b.x;
115 y = a.y - b.y;
116 return *this;
117 }
118
mul(T s)119 template<typename T> inline _vector2<T>& _vector2<T>::mul(T s)
120 {
121 x *= s;
122 y *= s;
123 return *this;
124 }
125
126 template<typename T> inline bool _vector2<T>::operator<(const _vector2<T>& right) const
127 {
128 return x < right.x || (x == right.x && y < right.y);
129 }
130
131 template<typename T> inline bool _vector2<T>::operator==(const _vector2<T>& right) const
132 {
133 return (x == right.x && y == right.y);
134 }
135
136 template<typename T> inline bool _vector2<T>::operator!=(const _vector2<T>& right) const
137 {
138 return (x != right.x || y != right.y);
139 }
140
141 template<typename T> inline T& _vector2<T>::operator[](size_t i) { return xy[i]; }
142
143 template<typename T> inline const T& _vector2<T>::operator[](size_t i) const { return xy[i]; }
144
compare(const _vector2<T> & right)145 template<typename T> inline int _vector2<T>::compare(const _vector2<T>& right) const
146 {
147 #if 1
148 return (x < right.x) ? -1 : (x == right.x ? (y < right.y ? -1 : (y == right.y ? 0 : +1)) : +1);
149 #else
150 if (x < right.x)
151 return -1;
152 else if (x > right.x)
153 return +1;
154 if (y < right.y)
155 return -1;
156 else if (y > right.y)
157 return +1;
158 return 0;
159 #endif
160 }
161
162 } // end of namespace xray_re
163
164 #endif
165