Space-efficient geometric algorithms and data structures

By Ilya Katz and Hervé Brönnimann    

functions.hpp

Go to the documentation of this file.
00001 #ifndef FUNCTIONS_HPP
00002 #define FUNCTIONS_HPP
00003 /*
00004  * Copyright © Ilya Katz and Hervé Brönnimann, 2005.
00005  */
00013 #include "data_node.hpp"
00014 #include "cgl.hpp"
00015 using namespace inplaceds;
00016 
00017 typedef cgl<double>                                     Geometry;
00018 typedef Geometry::line_type                     line_type;
00019 typedef Geometry::point_type                    point_type;
00020 typedef Geometry::coord_type                    coord_type;
00021 
00026 #define slope(x1,y1,x2,y2) ( (y2-y1)/(x2-x1) )
00027 
00032 #define ACCURACY_CUTTOFF 0.000000001
00033 
00034 
00035 
00036 //WORK ON THIS!!!
00037 /*
00038  Consider (14,29)(59,26) and (34,41)(96,52)
00039  Their intersection point is (34,41)
00040 
00041  */
00042 template <class node>
00043 struct event_compare
00044 {
00045   bool operator()(const node& a, const node& b){
00046     //if two data_nodes have the same critical point (intersection)
00047     //priorities are given from left to right
00048     //LEFT_EVENT, INTERSECTION_EVENT , RIGHT_EVENT
00049 
00050     if( (geom.get_x_coordinate(a.point)-geom.get_x_coordinate(b.point))<ACCURACY_CUTTOFF
00051      && (geom.get_x_coordinate(b.point)-geom.get_x_coordinate(a.point))<ACCURACY_CUTTOFF)
00052     {
00053       if(a.myEvent==LEFT_EVENT)
00054       {
00055         return true;
00056       }
00057       else if(b.myEvent==LEFT_EVENT)
00058       {
00059         return false;
00060       }
00061 
00062       if(a.myEvent==INTERSECTION_EVENT)
00063       {
00064         return true;
00065       }
00066       else if(b.myEvent==INTERSECTION_EVENT)
00067       {
00068         return false;
00069       }
00070     }
00071     return geom.less_xy_object()(a.point,b.point);
00072   }
00073 
00074   Geometry geom;
00075 
00076 };
00077 
00078 template <class Node>
00079 struct vertical_compare
00080 {
00081                 typedef cgl<double>    Geometry;
00082   typedef typename Node::line_type       line_type;
00083   typedef typename Node::coord_type     coord_type;
00084   typedef typename Node::point_type     point_type;
00085 
00086 
00087   vertical_compare(Geometry& g, coord_type& p):
00088       geom(g), m_p(p){}
00089 
00090   bool operator()(const Node& a, const Node& b){
00091     return operator()(a.line,b.line);
00092   }
00093 
00094 
00095    //* THE TEST IS DIFFERENT FROM HERVE'S
00096    //* CHECK IT!
00097 
00098   bool operator()(const line_type& l1, const line_type& l2){
00099 
00100     //two lines are equal
00101     if(l1[0][0]==l2[0][0] && l1[0][1]==l2[0][1] &&
00102       l1[1][0]==l2[1][0] && l1[1][1]==l2[1][1]){
00103         return false;
00104       }
00105 
00106     //else, need to check which line is has higher
00107     //y-coordinate at the current sweepline position
00108     coord_type m1 = slope(l1[0][0],l1[0][1], l1[1][0], l1[1][1]),
00109            m2 = slope(l2[0][0],l2[0][1], l2[1][0], l2[1][1]);
00110 
00111     coord_type b1 = l1[0][1]-m1*l1[0][0],
00112          b2 = l2[0][1]-m2*l2[0][0];
00113 
00114     coord_type currentY1 = m1*m_p + b1,
00115            currentY2 = m2*m_p + b2;
00116 
00117     return (currentY1-currentY2)<ACCURACY_CUTTOFF;
00118 
00119   }
00120   private:
00121     Geometry geom;
00122     coord_type& m_p;
00123 };
00124 
00125 
00126 
00138 std::pair<bool, point_type>
00139 intersection(const line_type& l1, const line_type& l2){
00140 
00141   std::pair<bool, point_type> ret(false, point_type());
00142 
00143   coord_type m1 = slope(l1[0][0], l1[0][1], l1[1][0], l1[1][1]),
00144       m2 = slope(l2[0][0], l2[0][1], l2[1][0], l2[1][1]);
00145 
00146   if(m1 == m2){  //lines are parallel
00147     return ret;
00148   }
00149 
00150   coord_type b1 = l1[0][1]-m1*l1[0][0],
00151          b2 = l2[0][1]-m2*l2[0][0];
00152 
00153   coord_type x = (b2-b1)/(m1-m2);
00154 
00155   //originally, the left end point is at position [0]
00156   //but, beacuse of encoding intersection, these positions
00157   //may have changed
00158   if(x<std::min(l1[0][0],l1[1][0]) || x>std::max(l1[0][0],l1[1][0]) ||
00159      x<std::min(l2[0][0],l2[1][0]) || x>std::max(l2[0][0],l2[1][0])){
00160     return ret;
00161   }
00162 
00163   coord_type y1 = m1 * x + b1;
00164   coord_type y2 = m2 * x + b2;
00165 
00166   //if not equal, return false
00167   if(!((y1-y2)<ACCURACY_CUTTOFF)){
00168     return ret;
00169   }
00170 
00171   //special case: if left-end point of a line is the intersection
00172   //point, do not consider it
00173   if(((l1[0][0]-x)<ACCURACY_CUTTOFF && (l1[0][1]-y1)<ACCURACY_CUTTOFF) &&
00174       (x-l1[0][0])<ACCURACY_CUTTOFF && (y1-l1[0][1])<ACCURACY_CUTTOFF )
00175                   {
00176                         return ret;
00177                   }
00178   if(((l2[0][0]-x)<ACCURACY_CUTTOFF && (l2[0][1]-y1)<ACCURACY_CUTTOFF) &&
00179       (x-l2[0][0])<ACCURACY_CUTTOFF && (y1-l2[0][1])<ACCURACY_CUTTOFF )
00180                   {
00181                         return ret;
00182                   }
00183         if(((l1[1][0]-x)<ACCURACY_CUTTOFF && (l1[1][1]-y1)<ACCURACY_CUTTOFF) &&
00184       (x-l1[1][0])<ACCURACY_CUTTOFF && (y1-l1[1][1])<ACCURACY_CUTTOFF )
00185                   {
00186                         return ret;
00187                   }
00188   if(((l2[1][0]-x)<ACCURACY_CUTTOFF && (l2[1][1]-y1)<ACCURACY_CUTTOFF) &&
00189       (x-l2[1][0])<ACCURACY_CUTTOFF && (y1-l2[1][1])<ACCURACY_CUTTOFF )
00190                   {
00191                         return ret;
00192                   }
00193   ret.second[0]=x;
00194   ret.second[1]=y1;
00195   ret.first=true;
00196 
00197   return ret;
00198 }
00199 
00200 
00201 #endif

Code Documentation generated Using Doxygen

Copyright © Ilya Katz and Hervé Brönnimann, 2005, 2006.