00001 #ifndef GRID_HH
00002 #define GRID_HH
00003
00004 #include <math.h>
00005
00007 namespace grid {
00008
00009 class LineRT;
00010
00011
00012
00014
00015
00016
00019 struct Point {
00020
00022 Point() : x(0), y(0) { }
00023
00028 Point(float x, float y) : x(x), y(y) { }
00029
00031 Point& rot90()
00032 {
00033 *this = Point(y, -x);
00034 return *this;
00035 }
00036
00040 Point get_rot90() const
00041 {
00042 return Point(y, -x);
00043 }
00044
00049 float dot(const Point &p) const { return x * p.x + y * p.y; }
00050
00055 Point& add(const Point &p, float scale = 1)
00056 {
00057 x += scale * p.x;
00058 y += scale * p.y;
00059 return *this;
00060 }
00061
00066 Point get_add(const Point &p, float scale = 1) const
00067 {
00068 return Point(x + scale * p.x, y + scale * p.y);
00069 }
00070
00075 Point& sub(const Point &p, float scale = 1)
00076 {
00077 x -= scale * p.x;
00078 y -= scale * p.y;
00079 return *this;
00080 }
00081
00086 Point get_sub(const Point &p, float scale = 1) const
00087 {
00088 return Point(x - scale * p.x, y - scale * p.y);
00089 }
00090
00094 Point& scale(float scale)
00095 {
00096 x *= scale;
00097 y *= scale;
00098 return *this;
00099 }
00100
00108 float angle() const { return atan2(y, x); }
00109
00113 float length() const { return sqrt(x * x + y * y); }
00114
00118 Point& normalize(float length)
00119 {
00120 float len = this->length();
00121 x /= len;
00122 y /= len;
00123 return *this;
00124 }
00125
00127 float x, y;
00128 };
00129
00130
00131
00133
00134
00135
00138 struct Line {
00139
00141 Line() { }
00142
00147 Line(Point a, Point b) : a(a), b(b) { }
00148
00155 Line(float x1, float y1, float x2, float y2) : a(x1, y1), b(x2, y2) { }
00156
00165 Line(const LineRT &line);
00166
00171 Point normal() const
00172 {
00173 return b.get_sub(a).rot90();
00174 }
00175
00180 Point tangent() const
00181 {
00182 return b.get_sub(a);
00183 }
00184
00189 Point intersection(const Line &line) const
00190 {
00191 Point line_normal = line.normal();
00192 Point tangent = this->tangent();
00193 float k = line.a.get_sub(a).dot(line_normal) / tangent.dot(line_normal);
00194 return a.get_add(tangent, k);
00195 }
00196
00202 Line& cut(const Line &line1, const Line &line2)
00203 {
00204 a = this->intersection(line1);
00205 b = this->intersection(line2);
00206 return *this;
00207 }
00208
00214 Line get_cut(const Line &line1, const Line &line2) const
00215 {
00216 return Line(this->intersection(line1), this->intersection(line2));
00217 }
00218
00223 Point closest(const Point &point) const
00224 {
00225 Line line(point, point.get_add(this->normal()));
00226 return this->intersection(line);
00227 }
00228
00229 Point a;
00230 Point b;
00231
00235 Point mirror(const Point &point) const
00236 {
00237 Point mirror_point = this->closest(point);
00238 return point.get_add(mirror_point.sub(point), 2);
00239 }
00240
00244 Line& mirror(const Line &mirror)
00245 {
00246 a = mirror.mirror(a);
00247 b = mirror.mirror(b);
00248 return *this;
00249 }
00250
00254 Line get_mirror(const Line &mirror) const
00255 {
00256 return Line(mirror.mirror(a), mirror.mirror(b));
00257 }
00258 };
00259
00260
00261
00263
00264
00265
00277 struct LineRT {
00278
00280 LineRT() : rho(0), theta(0) { }
00281
00286 LineRT(float rho, float theta) : rho(rho), theta(theta) { }
00287
00291 LineRT(const Line &line)
00292 {
00293 Point p = line.closest(Point(0, 0));
00294 rho = p.length();
00295 theta = p.angle();
00296 }
00297
00299 bool operator<(const LineRT &line) const
00300 {
00301 if (rho < line.rho)
00302 return true;
00303 return false;
00304 }
00305
00306 float rho;
00307 float theta;
00308 };
00309
00310
00311
00313
00314
00315
00316 inline
00317 Line::Line(const LineRT &line)
00318 {
00319 a.x = line.rho * cos(line.theta);
00320 a.y = line.rho * sin(line.theta);
00321 b = a.get_add(a.get_rot90());
00322 }
00323
00328 inline
00329 float rad(float angle) { return angle / 180 * M_PI; }
00330
00335 inline
00336 float deg(float angle) { return angle * 180 / M_PI; }
00337 }
00338
00339 #endif