1 #ifndef GWORM_VECTOR_H_
2 #define GWORM_VECTOR_H_
13 template<class Scalar>
17 constexpr Vector() : x(0), y(0) { }
18 constexpr Vector(Scalar x, Scalar y) : x(x), y(y) { }
21 constexpr Vector(Vector<Other> other) : x(other.x), y(other.y) { }
23 static Vector<Scalar> FromPolar(Scalar rad, Scalar az) {
24 return Vector<Scalar>(rad * std::cos(az), rad * std::sin(az));
27 static constexpr Vector<Scalar> unit45 = Vector<Scalar>(-0.7071, 0.7071);
30 Vector<Scalar> &operator +=(Vector<Scalar> other) {
35 Vector<Scalar> &operator -=(Vector<Scalar> other) {
40 Vector<Scalar> &operator *=(Scalar factor) {
45 Vector<Scalar> &operator /=(Scalar factor) {
51 SDL_Point ToPoint() const {
65 constexpr Vector<T> Vector<T>::unit45;
67 /// specialization with same layout as SDL_Point
73 constexpr Vector() : SDL_Point({0, 0}) { }
74 constexpr Vector(int x, int y) : SDL_Point({x, y}) { }
77 constexpr Vector(Vector<Other> other)
78 : SDL_Point({int(other.x), int(other.y)}) { }
81 Vector<int> &operator +=(Vector<int> other) {
86 Vector<int> &operator -=(Vector<int> other) {
92 SDL_Point ToPoint() const {
99 template<class Scalar>
100 constexpr Vector<Scalar> operator -(Vector<Scalar> v) {
101 return Vector<Scalar>(-v.x, -v.y);
105 template<class Scalar>
106 constexpr Vector<Scalar> operator +(Vector<Scalar> lhs, Vector<Scalar> rhs) {
107 return Vector<Scalar>(lhs.x + rhs.x, lhs.y + rhs.y);
110 template<class Scalar>
111 constexpr Vector<Scalar> operator -(Vector<Scalar> lhs, Vector<Scalar> rhs) {
112 return Vector<Scalar>(lhs.x - rhs.x, lhs.y - rhs.y);
116 template<class Scalar>
117 constexpr Vector<Scalar> operator *(Vector<Scalar> lhs, Scalar rhs) {
118 return Vector<Scalar>(lhs.x * rhs, lhs.y * rhs);
121 template<class Scalar>
122 constexpr Vector<Scalar> operator *(Scalar lhs, Vector<Scalar> rhs) {
125 template<class Scalar>
126 constexpr Vector<Scalar> operator *(Vector<Scalar> lhs, Vector<Scalar> rhs) {
127 return Vector<Scalar>(lhs.x * rhs.x, lhs.y * rhs.y);
131 template<class Scalar>
132 constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Scalar rhs) {
133 return Vector<Scalar>(lhs.x / rhs, lhs.y / rhs);
136 template<class Scalar>
137 constexpr Vector<Scalar> operator /(Scalar lhs, Vector<Scalar> rhs) {
140 template<class Scalar>
141 constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Vector<Scalar> rhs) {
142 return Vector<Scalar>(lhs.x / rhs.x, lhs.y / rhs.y);
146 template<class Scalar>
147 constexpr bool operator ==(Vector<Scalar> lhs, Vector<Scalar> rhs) {
148 return lhs.x == rhs.x && lhs.y == rhs.y;
150 template<class Scalar>
151 constexpr bool operator !=(Vector<Scalar> lhs, Vector<Scalar> rhs) {
152 return lhs.x != rhs.x && lhs.y != rhs.y;
156 template<class Scalar>
157 constexpr bool IsZero(Vector<Scalar> v) {
158 return std::abs(v.x) < std::numeric_limits<Scalar>::epsilon()
159 && std::abs(v.y) < std::numeric_limits<Scalar>::epsilon();
163 template<class Scalar>
164 constexpr Scalar Cross2D(Vector<Scalar> lhs, Vector<Scalar> rhs) {
165 return (lhs.x * rhs.y) - (lhs.y * rhs.x);
167 template<class Scalar>
168 constexpr Scalar Dot(Vector<Scalar> lhs, Vector<Scalar> rhs) {
169 return (lhs.x * rhs.x) + (lhs.y * rhs.y);
171 template<class Scalar>
172 constexpr Scalar Length(Vector<Scalar> v) {
173 return std::sqrt(Dot(v, v));
175 template<class Scalar>
176 constexpr Vector<Scalar> Norm(Vector<Scalar> v) {
177 return v / Length(v);
180 template<class Scalar>
181 constexpr Vector<Scalar> Rotate90(Vector<Scalar> v) {
182 return Vector<Scalar>(-v.y, v.x);
184 template<class Scalar>
185 constexpr Vector<Scalar> Rotate180(Vector<Scalar> v) {
188 template<class Scalar>
189 constexpr Vector<Scalar> Rotate270(Vector<Scalar> v) {
190 return Vector<Scalar>(v.y, -v.x);
192 template<class Scalar, class Float>
193 inline Vector<Scalar> Rotate(Vector<Scalar> v, Float by) {
194 Float sine(std::sin(by));
195 Float cosine(std::cos(by));
196 return Vector<Scalar>(v.x * cosine - v.y * sine, v.x * sine + v.y * cosine);
199 /// reflect v along normalized n
200 template<class Scalar>
201 inline Vector<Scalar> Reflect(Vector<Scalar> v, Vector<Scalar> n) {
202 const Scalar dd = Scalar(2) * Dot(v, n);
203 return Vector<Scalar>(v.x - (dd * n.x), v.y - (dd * n.y));
207 template<class Scalar>
208 inline std::ostream &operator <<(std::ostream &out, Vector<Scalar> v) {
209 return out << '<' << v.x << ',' << v.y << '>';
217 template<class Scalar>
218 constexpr gworm::Vector<Scalar> min(
219 gworm::Vector<Scalar> lhs,
220 gworm::Vector<Scalar> rhs
222 return gworm::Vector<Scalar>(
228 template<class Scalar>
229 constexpr gworm::Vector<Scalar> max(
230 gworm::Vector<Scalar> lhs,
231 gworm::Vector<Scalar> rhs
233 return gworm::Vector<Scalar>(