Open
Graph Drawing
Framework

 v.2007.11
 

geometry.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 1.6 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2007-11-08 16:10:37 +0100 (Do, 08 Nov 2007) $ 
00007  ***************************************************************/
00008  
00050 #ifdef _MSC_VER
00051 #pragma once
00052 #endif
00053 
00054 #ifndef OGDF_GEOMETRIC_H
00055 #define OGDF_GEOMETRIC_H
00056 
00057 #include <float.h> // for DBL_MAX
00058 #include <math.h>
00059 
00060 #include <ogdf/basic/List.h>
00061 #include <ogdf/basic/Hashing.h>
00062 
00063 #define GEOMETRIC_CMP_EPS  1e-06
00064 
00065 namespace ogdf {
00066 
00068 enum Orientation {
00069     topToBottom, 
00070     bottomToTop, 
00071     leftToRight, 
00072     rightToLeft  
00073 };
00074 
00075 
00076 
00077 // Important: be careful, if compared values are (+/-)DBL_MAX !!!
00078 inline
00079 bool DIsEqual(const double &a, const double &b, const double eps = GEOMETRIC_CMP_EPS)
00080 {
00081     return (a < (b + eps) && a > (b - eps));
00082 }
00083 
00084 inline
00085 bool DIsGreaterEqual(const double &a, const double &b, const double eps = GEOMETRIC_CMP_EPS)
00086 {
00087     return (a > (b - eps));
00088 }
00089 
00090 inline
00091 bool DIsGreater(const double &a, const double &b, const double eps = GEOMETRIC_CMP_EPS)
00092 {
00093     return (a > (b + eps));
00094 }
00095 
00096 inline
00097 bool DIsLessEqual(const double &a, const double &b, const double eps = GEOMETRIC_CMP_EPS)
00098 {
00099     return (a < (b + eps));
00100 }
00101 
00102 inline
00103 bool DIsLess(const double &a, const double &b, const double eps = GEOMETRIC_CMP_EPS)
00104 {
00105     return (a < (b - eps));
00106 }
00107 
00108 inline
00109 double DRound(const double &d, int prec = 0)
00110 {
00111     if (prec == 0)
00112         return floor(d + 0.5);
00113     double factor = pow(10.0, ((double) prec));
00114     return DRound(d * factor, 0) / factor;
00115 }
00116 
00125 template <class NUMBER>
00126 class GenericPoint 
00127 {
00128 public:
00130     typedef NUMBER numberType;
00131 
00132     NUMBER m_x; 
00133     NUMBER m_y; 
00134 
00136 
00140     GenericPoint() { }
00141 
00143     GenericPoint(NUMBER x, NUMBER y) : m_x(x), m_y(y) { }
00144 
00146     GenericPoint(const GenericPoint &ip) : m_x(ip.m_x), m_y(ip.m_y) { }
00147 
00149     GenericPoint operator=(const GenericPoint &ip) {
00150         m_x = ip.m_x;
00151         m_y = ip.m_y;
00152         return *this;
00153     }
00154 
00156     bool operator==(const GenericPoint &ip) const {
00157         return m_x == ip.m_x && m_y == ip.m_y;
00158     }
00159 
00161     bool operator!=(const GenericPoint &ip) const {
00162         return m_x != ip.m_x || m_y != ip.m_y;
00163     }
00164 
00165 };//class GenericPoint
00166 
00167 
00173 class IPoint : public GenericPoint<int>
00174 {
00175 public:
00177     IPoint() : GenericPoint<int>(0,0) { }
00178 
00180     IPoint(int x, int y) : GenericPoint<int>(x,y) { }
00181 
00183     IPoint(const IPoint &ip) : GenericPoint<int>(ip) { }
00184 
00186     double distance(const IPoint &p) const;
00187 };//class IPoint
00188 
00189 
00191 ostream &operator<<(ostream &os, const IPoint &ip);
00192 
00193 
00194 template<> class DefHashFunc<IPoint>
00195 {
00196 public:
00197     int hash(const IPoint &ip) const {
00198         return 7*ip.m_x + 23*ip.m_y;
00199     }
00200 };
00201 
00202 
00211 class IPolyline : public List<IPoint> {
00212 public:
00214     IPolyline() { }
00215 
00217     IPolyline(const IPolyline &ipl) : List<IPoint>(ipl) { }
00218 
00220     IPolyline &operator=(const IPolyline &ipl) {
00221         List<IPoint>::operator =(ipl);
00222         return *this;
00223     }
00224 
00226     double length() const;
00227 };
00228 
00229 
00230 
00236 class DPoint : public GenericPoint<double>
00237 {
00238 public:
00240     DPoint() : GenericPoint<double>(0,0) { }
00241 
00243     DPoint(double x, double y) : GenericPoint<double>(x,y) { }
00244 
00246     DPoint(const DPoint &dp) : GenericPoint<double>(dp) { }
00247 
00249     bool operator==(const DPoint &dp) const {
00250         return DIsEqual(m_x, dp.m_x) && DIsEqual(m_y,dp.m_y);
00251     }
00252 
00254     DPoint operator+(const DPoint &p) const;
00255 
00257     DPoint operator-(const DPoint &p) const;
00258 
00260     double distance(const DPoint &p) const;
00261 };
00262 
00264 ostream &operator<<(ostream &os, const DPoint &dp);
00265 
00266 
00270 class DVector : public DPoint {
00271 public:
00272 
00274     DVector() : DPoint() { }
00275 
00277     DVector(double x, double y) : DPoint(x, y) { }
00278 
00280     DVector(const DVector &dv) : DPoint(dv) { }
00281 
00283     DVector operator=(const DPoint &ip) {
00284         if (this != &ip)
00285         {
00286             m_x = ip.m_x;
00287             m_y = ip.m_y;
00288         }
00289         return *this;
00290     }
00291 
00293     DVector operator*(const double val) const;
00294 
00296     DVector operator/(const double val) const;
00297 
00299     double length() const;
00300 
00302     double operator^(const DVector &dv) const;
00303 
00305     double operator*(const DVector &dv) const;
00306 
00313     DVector operator++() const;
00314 
00321     DVector operator--() const;
00322 
00323 
00324 };
00325 
00326 
00327 
00335 class DPolyline : public List<DPoint> {
00336     static const double s_prec; 
00337 public:
00339     DPolyline() { }
00340 
00342     DPolyline(const DPolyline &dpl) : List<DPoint>(dpl) { }
00343 
00345     DPolyline &operator=(const DPolyline &dpl) {
00346         List<DPoint>::operator =(dpl);
00347         return *this;
00348     }
00349 
00351     double length() const;
00352 
00360     DPoint position(const double fraction, double len = -1.0) const;
00361 
00363     void writeGML(const char* filename) const;
00364 
00366     void writeGML(ostream &stream) const;
00367 
00369     void unify();
00370 
00372     void normalize();
00373 
00375     void convertToInt();
00376 
00377     //void reConvertToDouble();
00378 };
00379 
00380 
00384 class DLine {
00385 
00386 protected:
00387     DPoint m_start; 
00388     DPoint m_end;   
00389 
00390 public:
00391 
00393     DLine() : m_start(), m_end() {}
00394 
00396     DLine(const DPoint &p1, const DPoint &p2) : m_start(p1), m_end(p2) {}
00397 
00399     DLine(const DLine &dl) : m_start(dl.m_start), m_end(dl.m_end) {}
00400 
00402     DLine(double x1, double y1, double x2, double y2) {
00403         m_start.m_x = x1; m_start.m_y = y1; m_end.m_x = x2; m_end.m_y = y2;
00404     }
00405 
00407     bool operator==(const DLine &dl) const {
00408         return m_start == dl.m_start && m_end == dl.m_end;
00409     }
00410 
00412     bool operator!=(const DLine &dl) const {
00413         return !(*this == dl);
00414     }
00415 
00417     DLine &operator= (const DLine &dl) {
00418         if (this != &dl) { // don't assign myself
00419             m_start = dl.m_start;
00420             m_end   = dl.m_end;
00421         }
00422         return *this;
00423     }
00424 
00426     const DPoint &start() const { return m_start; }
00427 
00429     const DPoint &end() const { return m_end; }
00430 
00432     double dx() const { return m_end.m_x - m_start.m_x; }
00433 
00435     double dy() const { return m_end.m_y - m_start.m_y; }
00436 
00438     double slope() const { return (dx() == 0) ? DBL_MAX : dy()/dx(); }
00439 
00441     double yAbs() const { return (dx() == 0) ? DBL_MAX : m_start.m_y - (slope() * m_start.m_x); }
00442 
00444     bool isVertical()   const { return (DIsEqual(dx(), 0.0)); }
00445 
00447     bool isHorizontal() const { return (DIsEqual(dy(), 0.0)); }
00448 
00456     bool intersection(const DLine &line, DPoint &inter, bool endpoints = true) const;
00457 
00459     bool contains(const DPoint &p) const;
00460 
00462     double length() const {
00463         return m_start.distance(m_end);
00464     }
00465 
00475     int horIntersection(const double horAxis, double &crossing) const;
00476 
00477 // gives the intersection with the vertical axis 'verAxis', returns the number of intersections
00478 // 0 = no, 1 = one, 2 = infinity or both end-points, e.g. parallel on this axis
00488     int verIntersection(const double verAxis, double &crossing) const;
00489 };
00490 
00492 ostream &operator<<(ostream &os, const DLine &dl);
00493 
00494 
00498 class DRect {
00499 
00500 private:
00501     DPoint m_p1; 
00502     DPoint m_p2; 
00503 
00504 public:
00506     DRect() : m_p1(), m_p2() {}
00507 
00509     DRect(const DPoint &p1, const DPoint &p2) : m_p1(p1), m_p2(p2)
00510         { normalize(); }
00511 
00513     DRect(double x1, double y1, double x2, double y2) {
00514         m_p1.m_x = x1; m_p1.m_y = y1; m_p2.m_x = x2; m_p2.m_y = y2;
00515         normalize();
00516     }
00517 
00519     DRect(const DLine &dl) : m_p1(dl.start()), m_p2(dl.end())
00520         { normalize(); }
00521 
00523     DRect(const DRect &dr) : m_p1(dr.m_p1), m_p2(dr.m_p2)
00524         { normalize(); }
00525 
00527     bool operator==(const DRect &dr) const {
00528         return m_p1 == dr.m_p1 && m_p2 == dr.m_p2;
00529     }
00530 
00532     bool operator!=(const DRect &dr) const {
00533         return !(*this == dr);
00534     }
00535 
00537     DRect &operator= (const DRect &dr) {
00538         if (this != &dr) { // don't assign myself
00539             m_p1 = dr.m_p1;
00540             m_p2 = dr.m_p2;
00541         }
00542         return *this;
00543     }
00544 
00546     double width() const {
00547         return m_p2.m_x - m_p1.m_x;
00548     }
00549 
00551     double height() const {
00552         return m_p2.m_y - m_p1.m_y;
00553     }
00554 
00561     void normalize() {
00562         if (width() < 0)  swap(m_p2.m_x, m_p1.m_x);
00563         if (height() < 0) swap(m_p2.m_y, m_p1.m_y);
00564     }
00565 
00567     const DPoint &p1() const { return m_p1; }
00568 
00570     const DPoint &p2() const { return m_p2; }
00571 
00573     const DLine topLine() const {
00574         return DLine( DPoint(m_p1.m_x, m_p2.m_y), DPoint(m_p2.m_x, m_p2.m_y));
00575     }
00576 
00578     const DLine rightLine() const {
00579         return DLine( DPoint(m_p2.m_x, m_p2.m_y), DPoint(m_p2.m_x, m_p1.m_y));
00580     }
00581 
00583     const DLine leftLine() const {
00584         return DLine( DPoint(m_p1.m_x, m_p1.m_y), DPoint(m_p1.m_x, m_p2.m_y));
00585     }
00586 
00588     const DLine bottomLine() const {
00589         return DLine( DPoint(m_p2.m_x, m_p1.m_y), DPoint(m_p1.m_x, m_p1.m_y));
00590     }
00591 
00593     void yInvert() { swap(m_p1.m_y, m_p2.m_y); }
00594 
00596     void xInvert() { swap(m_p1.m_x, m_p2.m_x); }
00597 
00599     bool contains(const DPoint &p) const {
00600         if (DIsLess   (p.m_x, m_p1.m_x) ||
00601             DIsGreater(p.m_x, m_p2.m_x) ||
00602             DIsLess   (p.m_y, m_p1.m_y) ||
00603             DIsGreater(p.m_y, m_p2.m_y))
00604             return false;
00605         return true;
00606     }
00607 };
00608 
00610 ostream &operator<<(ostream &os, const DRect &dr);
00611 
00612 
00616 class DScaler {
00617 
00618 private:
00619 
00620     const DRect *m_from; 
00621     const DRect *m_to; 
00622 
00623     double m_factorX; 
00624     double m_factorY; 
00625     double m_offsetX; 
00626     double m_offsetY; 
00627 
00628 public:
00630     DScaler(const DRect &from, const DRect &to) :
00631         m_from(&from),
00632         m_to(&to),
00633         m_factorX(to.width()/from.width()),
00634         m_factorY(to.height()/from.height()),
00635         m_offsetX(to.p1().m_x - from.p1().m_x * m_factorX),
00636         m_offsetY(to.p1().m_y - from.p1().m_y * m_factorY)
00637         {}
00638 
00639     ~DScaler() {}
00640 
00642     const DRect &from() const { return *m_from; }
00643 
00645     const DRect &to()   const { return *m_to;   }
00646 
00648     double scaleToX(double x) { return x * m_factorX + m_offsetX; }
00649 
00651     double scaleToY(double y) { return y * m_factorY + m_offsetY; }
00652 
00654     double scaleWidth(double width)   { return width  * m_to->width() /m_from->width();  }
00655 
00657     double scaleHeight(double height) { return height * m_to->height()/m_from->height(); }
00658 };
00659 
00661 ostream &operator<<(ostream &os, const DScaler &ds);
00662 
00663 
00667 class DSegment : public DLine {
00668 
00669 protected:
00670 
00671 public:
00672 
00674     DSegment() : DLine() {}
00675 
00677     DSegment(const DPoint &p1, const DPoint &p2) : DLine(p1, p2) {}
00678 
00680     DSegment(const DLine &dl) : DLine(dl) {}
00681 
00683     DSegment(double x1, double y1, double x2, double y2) : DLine(x1, y1, x2, y2) {}
00684 
00686     DSegment(const DSegment &ds) : DLine(ds) {}
00687 
00688 
00695     double det(const DSegment &segment) const {
00696         return (dx() * segment.dy() - dy() * segment.dx());
00697     }
00698 };  
00699 
00700 
00704 class DPolygon : public DPolyline {
00705 
00706 protected:
00707 
00708     bool m_counterclock; 
00709 
00710 public:
00717     DPolygon(bool cc = true) : m_counterclock(cc) { }
00718 
00720     DPolygon(const DRect &rect, bool cc = true) : m_counterclock(cc) {
00721         operator=(rect);
00722     }
00723 
00725     DPolygon(const DPolygon  &dop) : DPolyline(dop), m_counterclock(dop.m_counterclock) { }
00726 
00728     bool counterclock() { return m_counterclock; }
00729 
00731     DPolygon &operator=(const DPolygon &dop) {
00732         List<DPoint>::operator =(dop);
00733         m_counterclock = dop.m_counterclock;
00734         return *this;
00735     }
00736 
00738     DPolygon &operator=(const DRect &rect);
00739 
00741     DSegment segment(ListConstIterator<DPoint> it) const;
00742 
00743 
00745     ListIterator<DPoint> insertPoint(const DPoint &p) {
00746         return insertPoint(p, begin(), begin());
00747     }
00748 
00754     ListIterator<DPoint> insertPoint(const DPoint &p,
00755                                      ListIterator<DPoint> p1,
00756                                      ListIterator<DPoint> p2);
00757 
00759     void insertCrossPoint(const DPoint &p);
00760 
00762     int getCrossPoints(const DPolygon &p, List<DPoint> &crossPoints) const;
00763 
00765     void unify();
00766 
00768     void normalize();
00769 
00771     void writeGML(const char* filename) const;
00772 
00774     void writeGML(ostream &stream)      const;
00775 };
00776 
00778 ostream &operator<<(ostream &os, const DPolygon &dop);
00779 
00780 
00781 
00782 } // end namespace ogdf
00783 
00784 #endif


© 1999-2007 by oreas GmbH, © 2005-2007 by University Dortmund and University Cologne.

Generated on Thu Nov 22 19:40:01 2007 by doxygen 1.5.4.