root / trunk / tbeta / Linux / addons / ofxNCore / src / Calibration / vector2d.h @ 164

View | Annotate | Download (7.4 KB)

1
#ifndef __TOUCHLIB_VECTOR2D__
2
#define __TOUCHLIB_VECTOR2D__
3
4
5
#include <math.h>
6
7
        // The following code was originally written by Nikolaus Gebhardt as part of Irrlicht.
8
        // See www.irrlicht3d.org
9
10
    // The Irrlicht Engine License
11
    // Copyright © 2002-2005 Nikolaus Gebhardt
12
    // This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held 
13
    // liable for any damages arising from the use of this software.
14
    //
15
    // Permission is granted to anyone to use this software for any purpose, including commercial applications, and to 
16
    // alter it and redistribute it freely, subject to the following restrictions:
17
    //
18
    // 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. 
19
    //    If you use this software in a product, an acknowledgment in the product documentation would be appreciated but 
20
    //    is not required.
21
    // 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
22
    // 3. This notice may not be removed or altered from any source distribution.
23
24
25
        const float  GRAD_PI = 180.0f / 3.14159f;
26
        const float  GRAD_PI2 = 3.14159f / 180.0f;
27
        //const float  PI = 3.14159f;
28
        const float  ROUNDING_ERROR = 0.0001f;
29
30
31
        template <class T> 
32
        class vector2d
33
        {
34
        public:
35
36
                vector2d(): X(0), Y(0) {};
37
                vector2d(T nx, T ny) : X(nx), Y(ny) {};
38
                vector2d(const vector2d<T>& other)        :X(other.X), Y(other.Y) {};
39
40
                // operators
41
42
                vector2d<T> operator-() const { return vector2d<T>(-X, -Y);   }
43
44
                vector2d<T>& operator=(const vector2d<T>& other)        { X = other.X; Y = other.Y; return *this; }
45
46
                vector2d<T> operator+(const vector2d<T>& other) const { return vector2d<T>(X + other.X, Y + other.Y);        }
47
                vector2d<T>& operator+=(const vector2d<T>& other)        { X+=other.X; Y+=other.Y; return *this; }
48
49
                vector2d<T> operator-(const vector2d<T>& other) const { return vector2d<T>(X - other.X, Y - other.Y);        }
50
                vector2d<T>& operator-=(const vector2d<T>& other)        { X-=other.X; Y-=other.Y; return *this; }
51
52
                vector2d<T> operator*(const vector2d<T>& other) const { return vector2d<T>(X * other.X, Y * other.Y);        }
53
                vector2d<T>& operator*=(const vector2d<T>& other)        { X*=other.X; Y*=other.Y; return *this; }
54
                vector2d<T> operator*(const T v) const { return vector2d<T>(X * v, Y * v);        }
55
                vector2d<T>& operator*=(const T v) { X*=v; Y*=v; return *this; }
56
57
                vector2d<T> operator/(const vector2d<T>& other) const { return vector2d<T>(X / other.X, Y / other.Y);        }
58
                vector2d<T>& operator/=(const vector2d<T>& other)        { X/=other.X; Y/=other.Y; return *this; }
59
                vector2d<T> operator/(const T v) const { return vector2d<T>(X / v, Y / v);        }
60
                vector2d<T>& operator/=(const T v) { X/=v; Y/=v; return *this; }
61
62
                bool operator==(const vector2d<T>& other) const { return other.X==X && other.Y==Y; }
63
                bool operator!=(const vector2d<T>& other) const { return other.X!=X || other.Y!=Y; }
64
65
                // functions
66
67
                void set(const T& nx, const T& ny) {X=nx; Y=ny; }
68
                void set(const vector2d<T>& p) { X=p.X; Y=p.Y;}
69
70
                //! Returns the length of the vector
71
                //! \return Returns the length of the vector.
72
                float getLength() const { return sqrt(X*X + Y*Y); }
73
                float getLengthSQ() const { return (X*X + Y*Y); }
74
75
                //! Returns the dot product of this vector with an other.
76
                T dotProduct(const vector2d<T>& other) const
77
                {
78
                        return X*other.X + Y*other.Y;
79
                }
80
81
                //! Calculates the cross product with another vector
82
                T crossProduct(const vector2d<T>& p) const
83
                {
84
                        return X * p.Y - Y * p.X;
85
                }
86
87
88
                //! Returns distance from an other point. Here, the vector is interpreted as
89
                //! point in 2 dimensional space.
90
                float getDistanceFrom(const vector2d<T>& other) const
91
                {
92
                        float vx = X - other.X; float vy = Y - other.Y;
93
                        return sqrt(vx*vx + vy*vy);
94
                }
95
96
                //! Returns distance from an other point. Here, the vector is interpreted as
97
                //! point in 2 dimensional space.
98
                float getDistanceFromSQ(const vector2d<T>& other) const
99
                {
100
                        float vx = X - other.X; 
101
                        float vy = Y - other.Y;
102
103
                        return (vx*vx + vy*vy);
104
                }
105
106
                //! rotates the point around a center by an amount of degrees.
107
                void rotateBy(float degrees, const vector2d<T>& center)
108
                {
109
                        degrees *= GRAD_PI2;
110
                        T cs = (T)cos(degrees);
111
                        T sn = (T)sin(degrees);
112
113
                        X -= center.X;
114
                        Y -= center.Y;
115
116
                        set(X*cs - Y*sn, X*sn + Y*cs);
117
118
                        X += center.X;
119
                        Y += center.Y;
120
                }
121
122
                //! normalizes the vector.
123
                vector2d<T>& normalize()
124
                {
125
                        T l = (T)getLength();
126
                        if (l == 0)
127
                                return *this;
128
129
                        l = (T)1.0 / l;
130
                        X *= l;
131
                        Y *= l;
132
                        return *this;
133
                }
134
135
                //! Calculates the angle of this vector in grad in the trigonometric sense.
136
                //! This method has been suggested by Pr3t3nd3r.
137
                //! \return Returns a value between 0 and 360.
138
                inline float getAngleTrig() const
139
                {
140
                        if (X == 0.0)
141
                                return Y < 0.0 ? 270.0 : 90.0;
142
                        else
143
                        if (Y == 0)
144
                                return X < 0.0 ? 180.0 : 0.0;
145
146
                        if ( Y > 0.0)
147
                                if (X > 0.0)
148
                                        return atan(Y/X) * GRAD_PI;
149
                                else
150
                                        return 180.0-atan(Y/-X) * GRAD_PI;
151
                        else
152
                                if (X > 0.0)
153
                                        return 360.0-atan(-Y/X) * GRAD_PI;
154
                                else
155
                                        return 180.0+atan(-Y/-X) * GRAD_PI;
156
                } 
157
158
                //! Calculates the angle of this vector in grad in the counter trigonometric sense.
159
                //! \return Returns a value between 0 and 360.
160
                inline float getAngle() const
161
                {
162
                        if (Y == 0.0)  // corrected thanks to a suggestion by Jox
163
                                return X < 0.0 ? 180.0 : 0.0; 
164
                        else if (X == 0.0) 
165
                                return Y < 0.0 ? 90.0 : 270.0;
166
167
                        float tmp = Y / sqrt(X*X + Y*Y);
168
                        tmp = atan(sqrt(1 - tmp*tmp) / tmp) * GRAD_PI;
169
170
                        if (X>0.0 && Y>0.0)
171
                                return tmp + 270;
172
                        else
173
                        if (X>0.0 && Y<0.0)
174
                                return tmp + 90;
175
                        else
176
                        if (X<0.0 && Y<0.0)
177
                                return 90 - tmp;
178
                        else
179
                        if (X<0.0 && Y>0.0)
180
                                return 270 - tmp;
181
182
                        return tmp;
183
                }
184
185
                //! Calculates the angle between this vector and another one in grad.
186
                //! \return Returns a value between 0 and 90.
187
                inline float getAngleWith(const vector2d<T>& b) const
188
                {
189
                        float tmp = X*b.X + Y*b.Y;
190
191
                        if (tmp == 0.0)
192
                                return 90.0;
193
194
                        tmp = tmp / sqrt((X*X + Y*Y) * (b.X*b.X + b.Y*b.Y));
195
                        if (tmp < 0.0) tmp = -tmp;
196
197
                        return atan(sqrt(1 - tmp*tmp) / tmp) * GRAD_PI;
198
                }
199
200
201
                //! returns interpolated vector
202
                //! \param other: other vector to interpolate between
203
                //! \param d: value between 0.0f and 1.0f.
204
                vector2d<T> getInterpolated(const vector2d<T>& other, float d) const
205
                {
206
                        float inv = 1.0f - d;
207
                        return vector2d<T>(other.X*inv + X*d,
208
                                                           other.Y*inv + Y*d);
209
                }
210
211
                //! Returns if this vector interpreted as a point is on a line between two other points.
212
                /** It is assumed that the point is on the line. */
213
                bool isBetweenPoints(const vector2d<T>& begin, const vector2d<T>& end) const
214
                {
215
                        float f = (float)(end - begin).getLengthSQ();
216
                        return (float)getDistanceFromSQ(begin) < f && 
217
                                (float)getDistanceFromSQ(end) < f;
218
                }
219
220
                static bool isOnSameSide(vector2d<T> p1, vector2d<T> p2, vector2d<T> a, vector2d<T> b)
221
                {
222
                        vector2d<T> ba = b - a;
223
224
                        float cp1 = ba.crossProduct(p1-a);
225
                        float cp2 = ba.crossProduct(p2-a);
226
227
                        if (cp1*cp2 >= 0.0f) 
228
                                return true;
229
                        else 
230
                                return false;
231
                }
232
233
234
                // member variables
235
                T X, Y;
236
        };
237
238
        //! Typedef for float 2d vector.
239
        typedef vector2d<float> vector2df;
240
        //! Typedef for integer 2d vector.
241
        typedef vector2d<int> vector2di;
242
243
#endif