|
Space-efficient geometric algorithms and data structuresBy Ilya Katz and Hervé Brönnimann |
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.