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