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