]> git.localhorst.tv Git - l2e.git/blob - src/math/Vector.h
fb07d338986fa2f4b9c0373bc808b911efd18ec0
[l2e.git] / src / math / Vector.h
1 #ifndef MATH_VECTOR_H_
2 #define MATH_VECTOR_H_
3
4 #include <cmath>
5 #include <limits>
6 #include <ostream>
7
8 namespace math {
9
10 /// Basic vector class with emphasis on graphical/computational ease of use
11 /// rather than mathematical accuracy ;) .
12 template<class Scalar>
13 class Vector {
14
15 public:
16         Vector() : x(0), y(0) { }
17         Vector(Scalar x, Scalar y) : x(x), y(y) { }
18         template<class T>
19         Vector(const Vector<T> &other) : x(other.X()), y(other.Y()) { };
20         template<class T>
21         Vector(T x, T y) : x(x), y(y) { }
22
23 public:
24         Scalar X() const { return x; }
25         Scalar Y() const { return y; }
26
27         Scalar &X() { return x; }
28         Scalar &Y() { return y; }
29
30         Scalar Index(Scalar lineLength) const { return Y() * lineLength + X(); }
31         static Vector<Scalar> FromIndex(Scalar index, Scalar lineLength) {
32                 return Vector<Scalar>(index % lineLength, index / lineLength);
33         }
34
35         void Lock(const Vector<Scalar> &to);
36
37 private:
38         Scalar x, y;
39
40 };
41
42
43 template<class T>
44 inline Vector<T> operator +(const Vector<T> &lhs, const Vector<T> &rhs) {
45         return Vector<T>(lhs.X() + rhs.X(), lhs.Y() + rhs.Y());
46 }
47 template<class T, class U>
48 inline Vector<T> operator +(const Vector<T> &lhs, const Vector<U> &rhs) {
49         return Vector<T>(lhs.X() + rhs.X(), lhs.Y() + rhs.Y());
50 }
51
52 template<class T>
53 inline Vector<T> &operator +=(Vector<T> &lhs, const Vector<T> &rhs) {
54         return lhs = lhs + rhs;
55 }
56 template<class T, class U>
57 inline Vector<T> &operator +=(Vector<T> &lhs, const Vector<U> &rhs) {
58         return lhs = lhs + rhs;
59 }
60
61 template<class T>
62 inline Vector<T> operator -(const Vector<T> &lhs, const Vector<T> &rhs) {
63         return Vector<T>(lhs.X() - rhs.X(), lhs.Y() - rhs.Y());
64 }
65 template<class T, class U>
66 inline Vector<T> operator -(const Vector<T> &lhs, const Vector<U> &rhs) {
67         return Vector<T>(lhs.X() - rhs.X(), lhs.Y() - rhs.Y());
68 }
69
70 template<class T>
71 inline Vector<T> &operator -=(Vector<T> &lhs, const Vector<T> &rhs) {
72         return lhs = lhs - rhs;
73 }
74 template<class T, class U>
75 inline Vector<T> &operator -=(Vector<T> &lhs, const Vector<U> &rhs) {
76         return lhs = lhs - rhs;
77 }
78
79 template<class T>
80 inline Vector<T> operator -(const Vector<T> &v) {
81         return Vector<T>(-v.X(), -v.Y());
82 }
83
84 template<class T>
85 inline Vector<T> operator *(const Vector<T> &v1, const Vector<T> &v2) {
86         return Vector<T>(v1.X() * v2.X(), v1.Y() * v2.Y());
87 }
88 template<class T>
89 inline Vector<T> operator *(const Vector<T> &v, T s) {
90         return Vector<T>(v.X() * s, v.Y() * s);
91 }
92 template<class T>
93 inline Vector<T> operator *(T s, const Vector<T> &v) {
94         return Vector<T>(s * v.X(), s * v.Y());
95 }
96
97 template<class T>
98 inline Vector<T> operator /(const Vector<T> &v1, const Vector<T> &v2) {
99         return Vector<T>(v1.X() / v2.X(), v1.Y() / v2.Y());
100 }
101 template<class T>
102 inline Vector<T> operator /(const Vector<T> &v, T s) {
103         return Vector<T>(v.X() / s, v.Y() / s);
104 }
105 template<class T>
106 inline Vector<T> operator /(T s, const Vector<T> &v) {
107         return Vector<T>(s / v.X(), s / v.Y());
108 }
109
110 template<class T>
111 inline Vector<T> operator %(const Vector<T> &v1, const Vector<T> &v2) {
112         return Vector<T>(v1.X() % v2.X(), v1.Y() % v2.Y());
113 }
114 template<>
115 inline Vector<float> operator %(const Vector<float> &v1, const Vector<float> &v2) {
116         return Vector<float>(std::fmod(v1.X(), v2.X()), std::fmod(v1.Y(), v2.Y()));
117 }
118 template<>
119 inline Vector<double> operator %(const Vector<double> &v1, const Vector<double> &v2) {
120         return Vector<double>(std::fmod(v1.X(), v2.X()), std::fmod(v1.Y(), v2.Y()));
121 }
122 template<>
123 inline Vector<long double> operator %(const Vector<long double> &v1, const Vector<long double> &v2) {
124         return Vector<long double>(std::fmod(v1.X(), v2.X()), std::fmod(v1.Y(), v2.Y()));
125 }
126 template<class T>
127 inline Vector<T> operator %(const Vector<T> &v, T s) {
128         return Vector<T>(v.X() % s, v.Y() % s);
129 }
130 template<>
131 inline Vector<float> operator %(const Vector<float> &v, float s) {
132         return Vector<float>(std::fmod(v.X(), s), std::fmod(v.Y(), s));
133 }
134 template<>
135 inline Vector<double> operator %(const Vector<double> &v, double s) {
136         return Vector<double>(std::fmod(v.X(), s), std::fmod(v.Y(), s));
137 }
138 template<>
139 inline Vector<long double> operator %(const Vector<long double> &v, long double s) {
140         return Vector<long double>(std::fmod(v.X(), s), std::fmod(v.Y(), s));
141 }
142
143 template<class T>
144 inline bool operator ==(const Vector<T> &lhs, const Vector<T> &rhs) {
145         return lhs.X() == rhs.X() && lhs.Y() == rhs.Y();
146 }
147
148 template<class T>
149 inline bool operator !=(const Vector<T> &lhs, const Vector<T> &rhs) {
150         return lhs.X() != rhs.X() || lhs.Y() != rhs.Y();
151 }
152
153 template<class T>
154 inline std::ostream &operator <<(std::ostream &out, const Vector<T> &v) {
155         out << '<' << v.X() << ", " << v.Y() << '>';
156         return out;
157 }
158
159
160 template <class Scalar>
161 void Vector<Scalar>::Lock(const Vector<Scalar> &to) {
162         Vector<Scalar> half(to / Scalar(2));
163         Vector<Scalar> dist((*this) % to);
164
165         if (dist.X() > half.X()) {
166                 x += (to.X() - dist.X());
167         } else {
168                 x -= dist.X();
169         }
170
171         if (dist.Y() > half.Y()) {
172                 y += (to.Y() - dist.Y());
173         } else {
174                 y -= dist.Y();
175         }
176 }
177
178
179 }
180
181 #endif /* GEOMETRY_VECTOR_H_ */