Main Page | Namespace List | Class List | File List | Namespace Members | Class Members

grid.hh

00001 #ifndef GRID_HH
00002 #define GRID_HH
00003 
00004 #include <math.h>
00005 
00007 namespace grid {
00008 
00009   class LineRT; // Forward declaration for Line::Line(const LineRT &line)
00010 
00011 
00012 
00014   // Point
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   // Line
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); // Defined after the definition of LineRT
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   // LineRT
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   // Conversion functions
00314 
00315   // Documented above
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 /* GRID_HH */

Generated on Wed Feb 16 08:42:26 2005 for Gocam by doxygen 1.3.4