]> git.localhorst.tv Git - space.git/blob - src/graphics/Vector.h
added autopilot that sucks
[space.git] / src / graphics / Vector.h
1 #ifndef SPACE_VECTOR_H_
2 #define SPACE_VECTOR_H_
3
4 #include <algorithm>
5 #include <cmath>
6 #include <ostream>
7 #include <SDL.h>
8
9
10 namespace space {
11
12 template<class Scalar>
13 class Vector {
14
15 public:
16         constexpr Vector() : x(0), y(0) { }
17         constexpr Vector(Scalar x, Scalar y) : x(x), y(y) { }
18
19         template<class Other>
20         constexpr Vector(Vector<Other> other) : x(other.x), y(other.y) { }
21
22         static Vector<Scalar> FromPolar(Scalar rad, Scalar az) {
23                 return Vector<Scalar>(rad * std::cos(az), rad * std::sin(az));
24         }
25
26         static constexpr Vector<Scalar> unit45 = Vector<Scalar>(-0.7071, 0.7071);
27
28 public:
29         Vector<Scalar> &operator +=(Vector<Scalar> other) {
30                 x += other.x;
31                 y += other.y;
32                 return *this;
33         }
34         Vector<Scalar> &operator -=(Vector<Scalar> other) {
35                 x -= other.x;
36                 y -= other.y;
37                 return *this;
38         }
39
40         SDL_Point ToPoint() const {
41                 SDL_Point p;
42                 p.x = x;
43                 p.y = y;
44                 return p;
45         }
46
47 public:
48         Scalar x;
49         Scalar y;
50
51 };
52
53 template<class T>
54 constexpr Vector<T> Vector<T>::unit45;
55
56 /// specialization with same layout as SDL_Point
57 template<>
58 class Vector<int>
59 : public SDL_Point {
60
61 public:
62         constexpr Vector() : SDL_Point({0, 0}) { }
63         constexpr Vector(int x, int y) : SDL_Point({x, y}) { }
64
65         template<class Other>
66         constexpr Vector(Vector<Other> other)
67         : SDL_Point({int(other.x), int(other.y)}) { }
68
69 public:
70         Vector<int> &operator +=(Vector<int> other) {
71                 x += other.x;
72                 y += other.y;
73                 return *this;
74         }
75         Vector<int> &operator -=(Vector<int> other) {
76                 x -= other.x;
77                 y -= other.y;
78                 return *this;
79         }
80
81         SDL_Point ToPoint() const {
82                 return *this;
83         }
84
85 };
86
87
88 template<class Scalar>
89 constexpr Vector<Scalar> operator -(Vector<Scalar> v) {
90         return Vector<Scalar>(-v.x, -v.y);
91 }
92
93
94 template<class Scalar>
95 constexpr Vector<Scalar> operator +(Vector<Scalar> lhs, Vector<Scalar> rhs) {
96         return Vector<Scalar>(lhs.x + rhs.x, lhs.y + rhs.y);
97 }
98
99 template<class Scalar>
100 constexpr Vector<Scalar> operator -(Vector<Scalar> lhs, Vector<Scalar> rhs) {
101         return Vector<Scalar>(lhs.x - rhs.x, lhs.y - rhs.y);
102 }
103
104
105 template<class Scalar>
106 constexpr Vector<Scalar> operator *(Vector<Scalar> lhs, Scalar rhs) {
107         return Vector<Scalar>(lhs.x * rhs, lhs.y * rhs);
108 }
109
110 template<class Scalar>
111 constexpr Vector<Scalar> operator *(Scalar lhs, Vector<Scalar> rhs) {
112         return rhs * lhs;
113 }
114 template<class Scalar>
115 constexpr Vector<Scalar> operator *(Vector<Scalar> lhs, Vector<Scalar> rhs) {
116         return Vector<Scalar>(lhs.x * rhs.x, lhs.y * rhs.y);
117 }
118
119
120 template<class Scalar>
121 constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Scalar rhs) {
122         return Vector<Scalar>(lhs.x / rhs, lhs.y / rhs);
123 }
124
125 template<class Scalar>
126 constexpr Vector<Scalar> operator /(Scalar lhs, Vector<Scalar> rhs) {
127         return rhs / lhs;
128 }
129 template<class Scalar>
130 constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Vector<Scalar> rhs) {
131         return Vector<Scalar>(lhs.x / rhs.x, lhs.y / rhs.y);
132 }
133
134
135 template<class Scalar>
136 constexpr bool operator ==(Vector<Scalar> lhs, Vector<Scalar> rhs) {
137         return lhs.x == rhs.x && lhs.y == rhs.y;
138 }
139 template<class Scalar>
140 constexpr bool operator !=(Vector<Scalar> lhs, Vector<Scalar> rhs) {
141         return lhs.x != rhs.x && lhs.y != rhs.y;
142 }
143
144
145 template<class Scalar>
146 constexpr Scalar Cross2D(Vector<Scalar> lhs, Vector<Scalar> rhs) {
147         return (lhs.x * rhs.y) - (lhs.y * rhs.x);
148 }
149 template<class Scalar>
150 constexpr Scalar Dot(Vector<Scalar> lhs, Vector<Scalar> rhs) {
151         return (lhs.x * rhs.x) + (lhs.y * rhs.y);
152 }
153 template<class Scalar>
154 constexpr Scalar Length(Vector<Scalar> v) {
155         return std::sqrt(Dot(v, v));
156 }
157
158 template<class Scalar>
159 constexpr Vector<Scalar> Rotate90(Vector<Scalar> v) {
160         return Vector<Scalar>(-v.y, v.x);
161 }
162 template<class Scalar>
163 constexpr Vector<Scalar> Rotate180(Vector<Scalar> v) {
164         return -v;
165 }
166 template<class Scalar>
167 constexpr Vector<Scalar> Rotate270(Vector<Scalar> v) {
168         return Vector<Scalar>(v.y, -v.x);
169 }
170
171
172 template<class Scalar>
173 inline std::ostream &operator <<(std::ostream &out, Vector<Scalar> v) {
174         return out << '<' << v.x << ',' << v.y << '>';
175 }
176
177 }
178
179
180 namespace std {
181
182 template<class Scalar>
183 constexpr space::Vector<Scalar> min(
184                 space::Vector<Scalar> lhs,
185                 space::Vector<Scalar> rhs
186 ) {
187         return space::Vector<Scalar>(
188                 min(lhs.x, rhs.x),
189                 min(lhs.y, rhs.y)
190         );
191 }
192
193 template<class Scalar>
194 constexpr space::Vector<Scalar> max(
195                 space::Vector<Scalar> lhs,
196                 space::Vector<Scalar> rhs
197 ) {
198         return space::Vector<Scalar>(
199                 max(lhs.x, rhs.x),
200                 max(lhs.y, rhs.y)
201         );
202 }
203
204 }
205
206 #endif