1 #ifndef SFML_EXTRA_VECTOR_UTILS_H
2 #define SFML_EXTRA_VECTOR_UTILS_H
3 
4 #include <math.h>
5 #include <SFML/System.hpp>
6 #include <SFML/Graphics/Color.hpp>
7 /** math.h no longer defines M_PI in C++11. For... reasons? */
8 #ifndef M_PI
9 #define M_PI 3.14159265358979323846f
10 #endif
11 
12 /**
13     SFML is missing a few useful operators on the 2D vectors.
14     These are the missing operators.
15 */
16 
17 namespace sf
18 {
19     /** < and > operators are length compares. Return true or false if the distance is longer/shorter then asked distance. */
20     template <typename T>
21     static inline bool operator > (const Vector2<T>& v, const T& f)
22     {
23         return (v.x * v.x + v.y * v.y) > f * f;
24     }
25 
26     template <typename T>
27     static inline bool operator < (const Vector2<T>& v, const T& f)
28     {
29         return (v.x * v.x + v.y * v.y) < f * f;
30     }
31 
32     template <typename T>
33     static inline bool operator >= (const Vector2<T>& v, const T& f)
34     {
35         return (v.x * v.x + v.y * v.y) >= f * f;
36     }
37 
38     template <typename T>
39     static inline bool operator <= (const Vector2<T>& v, const T& f)
40     {
41         return (v.x * v.x + v.y * v.y) <= f * f;
42     }
43 
44     template <typename T>
45     static inline bool operator > (const Vector2<T>& v, const Vector2<T>& v2)
46     {
47         return (v.x * v.x + v.y * v.y) > (v2.x * v2.x + v2.y * v2.y);
48     }
49 
50     template <typename T>
51     static inline bool operator < (const Vector2<T>& v, const Vector2<T>& v2)
52     {
53         return (v.x * v.x + v.y * v.y) < (v2.x * v2.x + v2.y * v2.y);
54     }
55 
56     template <typename T>
57     static inline bool operator >= (const Vector2<T>& v, const Vector2<T>& v2)
58     {
59         return (v.x * v.x + v.y * v.y) >= (v2.x * v2.x + v2.y * v2.y);
60     }
61 
62     template <typename T>
63     static inline bool operator <= (const Vector2<T>& v, const Vector2<T>& v2)
64     {
65         return (v.x * v.x + v.y * v.y) <= (v2.x * v2.x + v2.y * v2.y);
66     }
67 
68     template <typename T>
vector2FromAngle(const T & angle)69     Vector2<T> vector2FromAngle(const T& angle)
70     {
71         T a = angle / 180.0 * M_PI;
72         return Vector2<T>(cosf(a), sinf(a));
73     }
74 
75     template <typename T>
vector2ToAngle(const Vector2<T> & v)76     T vector2ToAngle(const Vector2<T>& v)
77     {
78         return atan2(v.y, v.x) / M_PI * 180;
79     }
80 
81     /* Return the difference between angle_a and angle_b within a range of -180 and 180 degrees */
82     template <typename T>
angleDifference(const T & angle_a,const T & angle_b)83     T angleDifference(const T& angle_a, const T& angle_b)
84     {
85         T ret = (angle_b - angle_a);
86         while(ret > 180) ret -= 360;
87         while(ret < -180) ret += 360;
88         return ret;
89     }
90 
91     template <typename T>
rotateVector(const Vector2<T> & v,const T & angle)92     Vector2<T> rotateVector(const Vector2<T>& v, const T& angle)
93     {
94         T a = angle / 180.0f * M_PI;
95         return Vector2<T>(cosf(a), sinf(a)) * v.x + Vector2<T>(-sinf(a), cosf(a)) * v.y;
96     }
97 
98     template <typename T>
length(const Vector2<T> & v)99     T length(const Vector2<T>& v)
100     {
101         return sqrtf(v.x*v.x+v.y*v.y);
102     }
103 
104     template <typename T>
normalize(const Vector2<T> & v)105     Vector2<T> normalize(const Vector2<T>& v)
106     {
107         return v / length(v);
108     }
109 
110     template <typename T>
dot(const Vector2<T> & v0,const Vector2<T> & v1)111     T dot(const Vector2<T>& v0, const Vector2<T>& v1)
112     {
113         return v0.x * v1.x + v0.y * v1.y;
114     }
115 
116     //Check if C is left of the infinite line from A to B
117     template <typename T>
isLeft(const Vector2<T> & a,const Vector2<T> & b,const Vector2<T> & c)118     bool isLeft(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& c)
119     {
120         return ((b.x - a.x)*(c.y - a.y) - (b.y - a.y)*(c.x - a.x)) < 0;
121     }
122 
123 	// Return the intersection of the infinite line trough points p0 and p1 and infinite line trough points p2 and p3.
124 	template <typename T>
lineLineIntersection(const Vector2<T> & p0,const Vector2<T> & p1,const Vector2<T> & p2,const Vector2<T> & p3)125     Vector2<T> lineLineIntersection(const Vector2<T>& p0, const Vector2<T>& p1, const Vector2<T>& p2, const Vector2<T>& p3)
126     {
127         T A1 = p1.y - p0.y;
128         T B1 = p0.x - p1.x;
129         T C1 = A1*p0.x + B1*p0.y;
130 
131         T A2 = p3.y - p2.y;
132         T B2 = p2.x - p3.x;
133         T C2 = A2 * p2.x + B2 * p2.y;
134 
135         T det = A1*B2 - A2*B1;
136         if (det == 0)
137             return p0;
138         return Vector2<T>((B2*C1 - B1*C2)/det, (A1 * C2 - A2 * C1) / det);
139     }
140 }
141 
142 namespace sf
143 {
144     /** < and > operators are length compares. Return true or false if the distance is longer/shorter then asked distance. */
145     template <typename T>
146     static inline bool operator > (const Vector3<T>& v, const T& f)
147     {
148         return (v.x * v.x + v.y * v.y + v.z * v.z) > f * f;
149     }
150 
151     template <typename T>
152     static inline bool operator < (const Vector3<T>& v, const T& f)
153     {
154         return (v.x * v.x + v.y * v.y + v.z * v.z) < f * f;
155     }
156 
157     template <typename T>
158     static inline bool operator >= (const Vector3<T>& v, const T& f)
159     {
160         return (v.x * v.x + v.y * v.y + v.z * v.z) >= f * f;
161     }
162 
163     template <typename T>
164     static inline bool operator <= (const Vector3<T>& v, const T& f)
165     {
166         return (v.x * v.x + v.y * v.y + v.z * v.z) <= f * f;
167     }
168 
169     template <typename T>
170     static inline bool operator > (const Vector3<T>& v, const Vector3<T>& v2)
171     {
172         return (v.x * v.x + v.y * v.y + v.z * v.z) > (v2.x * v2.x + v2.y * v2.y + v2.z * v2.z);
173     }
174 
175     template <typename T>
176     static inline bool operator < (const Vector3<T>& v, const Vector3<T>& v2)
177     {
178         return (v.x * v.x + v.y * v.y + v.z * v.z) < (v2.x * v2.x + v2.y * v2.y + v2.z * v2.z);
179     }
180 
181     template <typename T>
182     static inline bool operator >= (const Vector3<T>& v, const Vector3<T>& v2)
183     {
184         return (v.x * v.x + v.y * v.y + v.z * v.z) >= (v2.x * v2.x + v2.y * v2.y + v2.z * v2.z);
185     }
186 
187     template <typename T>
188     static inline bool operator <= (const Vector3<T>& v, const Vector3<T>& v2)
189     {
190         return (v.x * v.x + v.y * v.y + v.z * v.z) <= (v2.x * v2.x + v2.y * v2.y + v2.z * v2.z);
191     }
192 
193     template <typename T>
length(const Vector3<T> & v)194     T length(const Vector3<T>& v)
195     {
196         return sqrtf(v.x*v.x+v.y*v.y+v.z*v.z);
197     }
198 
199     template <typename T>
normalize(const Vector3<T> & v)200     Vector3<T> normalize(const Vector3<T>& v)
201     {
202         return v / length(v);
203     }
204 
205     template <typename T>
dot(const Vector3<T> & v0,const Vector3<T> & v1)206     T dot(const Vector3<T>& v0, const Vector3<T>& v1)
207     {
208         return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
209     }
210 
211     template <typename T>
cross(const Vector3<T> & v0,const Vector3<T> & v1)212     Vector3<T> cross(const Vector3<T>& v0, const Vector3<T>& v1)
213     {
214         return Vector3<T>(v0.y * v1.z - v1.y * v0.z, v1.x*v0.z - v0.x*v1.z, v0.x*v1.y - v0.y*v1.x);
215     }
216 }
217 
218 #endif//SFML_EXTRA_VECTOR_UTILS_H
219