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