Bentley-Otmann Algorithm 2.0
An implementation of Bentley-Ottmann algorithm in order to count the m,n-cubes
bentley_ottmann.cpp
Go to the documentation of this file.
00001 
00101 #include "structures.hpp"
00102 #include "geometry.hpp"
00103 #include "bentley_ottmann.hpp"
00104 #include <iostream>
00105 #include <utility>
00106 #include <iterator>
00107 #include <algorithm>
00108 
00118 map_event bentley_ottmann(std::vector<Segment>& set) {
00119   map_event inter;
00120   //std::cout << "Map : declared\n";
00121   // priority queue : insert all endpoints
00122   PriorityQueue<Event, Segment*> queue;
00123 
00124   std::vector<Segment>::iterator it;
00125   for(it = set.begin(); it != set.end(); it++) {
00126     Event e_left(it->get_left()), e_right(it->get_right());
00127     queue.push(e_left, &(*it)), queue.push(e_right);
00128   }
00129 
00130   // binary search tree : empty
00131   Point p_sweep(rat(I(0)),rat(I(0)));
00132   compare<Segment,Point> comp(&p_sweep);
00133   BST<Segment,Point>::Type btree(comp);
00134 
00135   // treatment of events
00136   while(queue.size()) {
00137     // current event : p event on top of set
00138     Event p = queue.top();
00139     Point point = p.get_point();
00140     vector_seg l_set = queue.begin()->second;    
00141     queue.pop();
00142     
00143     p_sweep.assign(point.get_abscissa(), point.get_ordinate());
00144 
00145     //checking for intersection
00146     std::pair<vector_seg, vector_seg> ir_set = get_sets(point, btree);
00147     
00148     if(l_set.size() + ir_set.first.size() + ir_set.second.size() > 1) {
00149       map_event::iterator it_ev = (inter.insert(pair_event(p, vector_seg()))).first;
00150       
00151       //it_ev->second : union of l_set, ir_set.first and ir_set.second
00152       vector_seg::iterator it_seg = l_set.begin();
00153       for(; it_seg != l_set.end(); it_ev->second.push_back(*it_seg++));
00154       for(it_seg = ir_set.first.begin(); it_seg != ir_set.first.end();
00155           it_ev->second.push_back(*it_seg++));
00156       for(it_seg = ir_set.second.begin(); it_seg != ir_set.second.end();
00157           it_ev->second.push_back(*it_seg++));
00158       //std::cout << it_ev->second << "\n";
00159     }
00160     
00161 
00162     //delete ir_set.first and ir_set.second from btree
00163     vector_seg::iterator it_seg = ir_set.first.begin();
00164     for(; it_seg != ir_set.first.end(); btree.erase(*it_seg++));
00165     for(it_seg = ir_set.second.begin(); it_seg != ir_set.second.end();
00166         btree.erase(*it_seg++));
00167         
00168     //update sl
00169     p_sweep.assign(point.get_abscissa(), point.get_ordinate());
00170     
00171     //insert l_set and ir_set.first in btree
00172     for(it_seg = l_set.begin(); it_seg != l_set.end();
00173         btree.insert(*it_seg++));
00174     for(it_seg = ir_set.first.begin(); it_seg != ir_set.first.end();
00175         btree.insert(*it_seg++));
00176     
00177     //treat new events
00178     if(l_set.size() + ir_set.first.size() == 0) {
00179       //p is only the rightpoint of several segments
00180       Segment* s_a, * s_b;
00181       find_neighboors(point, btree, s_a, s_b); 
00182       
00183       compute_new_events(s_a, s_b, p, queue);
00184     }
00185     
00186     else {
00187       vector_seg v(l_set.size() + ir_set.first.size());
00188       set_union(l_set.begin(), l_set.end(),
00189                 ir_set.first.begin(), ir_set.first.end(), v.begin());
00190       Segment* sl = find_leftmost(v, point), * sr = find_rightmost(v, point);
00191       Segment* s_b = find_left_neighboor(sl, btree), * s_a = find_right_neighboor(sr, btree);
00192       
00193       compute_new_events(sl, s_b, p, queue); compute_new_events(sr, s_a, p, queue);
00194     }
00195   }
00196       
00197   return inter;
00198 }
00199 
00213 void find_neighboors(const Point& p, BST<Segment,Point>::Type& btree,
00214                      Segment*& above, Segment*& below) {
00215   //create a segment of length 0 representing p :
00216   rat x = p.get_abscissa(), y = p.get_ordinate();
00217   Segment s(x, y, x, y);
00218   
00219   //search for upper neighboor
00220   BST<Segment,Point>::Type::iterator it = btree.upper_bound(&s);
00221   
00222   if(it == btree.end())
00223     above = NULL;
00224   else
00225     above = *it;
00226   if(it == btree.begin())
00227     below = NULL;
00228   else 
00229     below = *--it;
00230 }
00231 
00240 Segment* find_leftmost(vector_seg& v, const Point& p) {
00241   //asuming v isn't empty
00242   vector_seg::iterator it = v.begin();
00243   Segment* min = *v.begin();
00244 
00245   while(++it != v.end()) {
00246     if((*it)->less(*min,p))
00247       min = *it;
00248   }
00249   return min;
00250 }
00251 
00260 Segment* find_rightmost(vector_seg& v, const Point& p) {
00261   //assuming v isn't empty
00262   vector_seg::iterator it = v.begin();
00263   Segment* max = *v.begin();
00264   
00265   while(++it != v.end()) {
00266     if(max->less(**it,p))
00267       max = *it;
00268   }
00269   return max;
00270 }
00271 
00278 Segment* find_left_neighboor(Segment* s, BST<Segment,Point>::Type& btree) {
00279   BST<Segment,Point>::Type::iterator it = btree.find(s);
00280   if(it == btree.begin())
00281     return NULL;
00282   else
00283     return *--it;
00284 }
00285 
00292 Segment* find_right_neighboor(Segment* s, BST<Segment,Point>::Type& btree) {
00293   BST<Segment,Point>::Type::iterator it = btree.find(s);
00294   if(++it == btree.end()) 
00295     return NULL;
00296   else
00297     return *it;
00298 }
00299 
00320 std::pair<vector_seg, vector_seg> get_sets(const Point& p, BST<Segment,Point>::Type& btree) {
00321   vector_seg i,r;
00322   if(btree.empty())
00323     return std::pair<vector_seg, vector_seg> (i,r);
00324   //create a segment of lentgh zero representing p :
00325   rat x = p.get_abscissa(), y = p.get_ordinate();
00326   Segment* s = new Segment(x, y, x, y);
00327   
00328   
00329   BST<Segment,Point>::Type::iterator it = btree.upper_bound(s);
00330   std::reverse_iterator<BST<Segment,Point>::Type::iterator> rit(it);
00331 
00332   Point q;
00333   while(rit != btree.rend() && (*rit)->high(p) == y) {
00334     if((*rit)->is_in(p))
00335       i.push_back(*rit);
00336     else if((*rit)->is_rend(p))
00337       r.push_back(*rit);
00338     rit++;
00339   }
00340 
00341   return std::pair<vector_seg, vector_seg> (i,r);
00342 }
00343 
00357 void compute_new_events(Segment* s0, Segment* s1, const Event& p,
00358                         PriorityQueue<Event,Segment*>& q) {
00359   Point i;
00360 
00361   if(s0 && s1 && s0->intersect(*s1, i)) {
00362     Event ev_i(i);
00363     if(p < ev_i && ! q.mem(ev_i))
00364       q.push(ev_i);
00365   }
00366 }
 All Classes Files Functions Variables Typedefs Enumerations