BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Triangle_2_Iso_rectangle_2_intersection.h
Go to the documentation of this file.
00001 // Copyright (c) 2002-2004  INRIA Sophia-Antipolis (France).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License as
00006 // published by the Free Software Foundation; version 2.1 of the License.
00007 // See the file LICENSE.LGPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Intersections_2/include/CGAL/Triangle_2_Iso_rectangle_2_intersection.h $
00016 // $Id: Triangle_2_Iso_rectangle_2_intersection.h 41387 2008-01-01 16:50:33Z spion $
00017 // 
00018 //
00019 // Author(s)     : Radu Ursu
00020 
00021 #ifndef CGAL_TRIANGLE_2_ISO_RECTANGLE_2_INTERSECTION_H
00022 #define CGAL_TRIANGLE_2_ISO_RECTANGLE_2_INTERSECTION_H
00023 
00024 #include "CGAL/Point_2.h"
00025 #include "CGAL/Segment_2.h"
00026 #include "CGAL/Triangle_2.h"
00027 #include "CGAL/Iso_rectangle_2.h"
00028 #include "CGAL/Segment_2_Segment_2_intersection.h"
00029 
00030 #include <vector>
00031 #include <list>
00032 
00033 namespace CGAL{
00034   template <class R>
00035   Object
00036   intersection(const Triangle_2<R> &t, const Iso_rectangle_2<R> &r)
00037   {
00038     typedef typename R::FT FT;
00039     typedef Segment_2<R> Segment;
00040     typedef Point_2<R>   Point;
00041 
00042     FT xr1, yr1, xr2, yr2;  
00043     bool position[3][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};
00044     bool is_inside[3] = {false, false, false}; //true when a vertex is inside rectangle
00045 
00046     xr1 = r.xmin(); xr2 = r.xmax();
00047     yr1 = r.ymax(); yr2 = r.ymin();
00048 
00049     Point upper_left, lower_right;
00050     Point p[3]; //the vertices of triangle
00051 
00052     upper_left = Point(xr1, yr1); //upper left
00053     lower_right = Point(xr2, yr2); //lower right    
00054     
00055     p[0] = t.vertex(0);
00056     p[1] = t.vertex(1);
00057     p[2] = t.vertex(2);  
00058 
00059     //check the points of the triangle
00060     for(int i=0; i<3; i++){
00061       if(!(compare_x(p[i], upper_left) == SMALLER))
00062         if(!(compare_x(p[i], lower_right) == LARGER))
00063           if(!(compare_y(p[i], upper_left) == LARGER))
00064             if(!(compare_y(p[i], lower_right) == SMALLER))        
00065               is_inside[i] = true; //the point is inside       
00066             else        
00067               position[i][2] = true; //South        
00068           else      
00069             position[i][0] = true; //North      
00070         else
00071         {
00072           position[i][3] = true; //East
00073           if(compare_y(p[i], upper_left) == LARGER)
00074             position[i][0] = true; //North
00075           else if(compare_y(p[i], lower_right) == SMALLER)
00076             position[i][2] = true; //South
00077         }
00078       else
00079       {
00080         position[i][1] = true;  //West
00081         if(compare_y(p[i], upper_left) == LARGER)
00082           position[i][0] = true; //North
00083         else if(compare_y(p[i], lower_right) == SMALLER)
00084           position[i][2] = true; //South
00085 
00086       }
00087     }
00088 
00089     //test if the triangle is completely to the left, right, below or above the rectangle
00090     bool intersection = true; //true if it could be a intersection with the rectangle
00091     for(int j=0; j<4; j++)
00092       if(position[0][j] && position[1][j] && position[2][j] ){
00093         intersection = false;
00094         break;
00095       }
00096 
00097     if(intersection){
00098       Segment s[4]; //the segments that identify the N, W, S, E  
00099       bool outside = false;
00100       bool status_in_list[3] = {false, false, false}; //true if the triangle's points are in the result vector
00101       std::list<int> last_intersected;
00102       int last_intersected_segment = 5; //could be 0=N, 1=W, 2=S, 3=E
00103       last_intersected.push_back(5);
00104       int status_intersected[4] = {0, 0, 0, 0}; //the number of intersections for each segment
00105       CGAL::Object obj;
00106       std::vector<Point> result; //the vector containing the result vertices
00107       int next; //the index of the next vertex
00108 
00109       s[0] = Segment(Point(xr2, yr1), Point(xr1, yr1)); //N
00110       s[1] = Segment(Point(xr1, yr1), Point(xr1, yr2)); //W  
00111       s[2] = Segment(Point(xr1, yr2), Point(xr2, yr2)); //S
00112       s[3] = Segment(Point(xr2, yr2), Point(xr2, yr1)); //E
00113         
00114       //assign to p[i] the vertices of the triangle in ccw order
00115       if(t.orientation() == CGAL::CLOCKWISE)
00116       {
00117         p[0] = t.vertex(2);
00118         p[2] = t.vertex(0);
00119         
00120         is_inside[0] = is_inside[2] ^ is_inside[0];
00121         is_inside[2] = is_inside[2] ^ is_inside[0];
00122         is_inside[0] = is_inside[0] ^ is_inside[2];
00123 
00124         for(int i=0; i<4; i++){
00125           position[0][i] = position[2][i] ^ position[0][i];
00126           position[2][i] = position[2][i] ^ position[0][i];
00127           position[0][i] = position[0][i] ^ position[2][i];
00128         }
00129       }
00130 
00131       for(int index=0; index<3; index++) //for each vertex
00132       {
00133         next=(index+1)%3;
00134         if(is_inside[index]){ // true if first is inside
00135           if(!status_in_list[index]){  //if is not yet in the list
00136             result.push_back(p[index]);
00137             status_in_list[index] = true;
00138           }
00139           if(is_inside[next]){ //true if second is inside
00140             //add the points in the vector    
00141             if(!status_in_list[next]){ // if is not yet in the list
00142               result.push_back(p[next]);
00143               status_in_list[next] = true;
00144             }
00145           } else { //I'm going out, the second is outside
00146             for(int j=0; j<4; j++) // for all directions
00147               if(position[next][j]) // if it's a second point direction
00148               {
00149                 //test for intersection
00150                 obj = CGAL::intersection(Segment(p[index], p[next]), s[j]);
00151                 if(const Point *p_obj = object_cast<Point>(&obj))
00152                 {
00153                   //intersection found
00154                   outside = true;
00155                   result.push_back(*p_obj); //add the intersection point
00156                   if(last_intersected.back()!=j)
00157                     last_intersected.push_back(j);
00158                   status_intersected[j]++;
00159                 }
00160               }
00161           }
00162         } else { //the first point is outside      
00163           for(int j=0; j<4; j++) // for all directions
00164             if(position[index][j]) //watch only the first point directions
00165             {
00166               //test for intersection
00167               obj = CGAL::intersection(Segment(p[index], p[next]), s[j]);
00168               if(const Point *p_obj = object_cast<Point>(&obj))
00169               {
00170                 //intersection found
00171                 outside = false;
00172                 last_intersected_segment = last_intersected.back();
00173                 if(last_intersected_segment != 5 && last_intersected_segment != j && status_intersected[j] == 0){
00174                   //add the target of each rectangle segment in the list
00175                   if(last_intersected_segment < j)
00176                     while(last_intersected_segment < j){
00177                       result.push_back(s[last_intersected_segment].target());
00178                       last_intersected_segment++;
00179                     }
00180                   else{
00181                     while(last_intersected_segment < 4){
00182                       result.push_back(s[last_intersected_segment].target());
00183                       last_intersected_segment++;
00184                     }
00185                     last_intersected_segment = 0;
00186                     while(last_intersected_segment < j){
00187                       result.push_back(s[last_intersected_segment].target());
00188                       last_intersected_segment++;
00189                     }
00190                   }
00191                 }
00192                 result.push_back(*p_obj); //add the intersection point in the list
00193                 if(last_intersected.back()!=j)
00194                   last_intersected.push_back(j);
00195                 status_intersected[j]++;
00196                 if(!is_inside[next]){ //if the second point is not inside search a second intersection point
00197                   for(j=0; j<4; j++) // for all directions
00198                     if(position[next][j])
00199                     {
00200                       //test for intersection
00201                       obj = CGAL::intersection(Segment(p[index], p[next]), s[j]);
00202                       if(const Point *p_obj = object_cast<Point>(&obj))
00203                            //found the second intersection
00204                       {
00205                         outside = true;
00206                         result.push_back(*p_obj);
00207                         if(last_intersected.back()!=j)
00208                           last_intersected.push_back(j);
00209                         status_intersected[j]++;
00210                       }
00211                     }
00212                 }//end if the second point is not inside
00213               } 
00214             }
00215         }//end else (the first point is outside)
00216       }//endfor
00217       if(outside){
00218         std::list<int>::const_iterator it = last_intersected.begin();
00219         while(*it == 5)
00220           it++;
00221         last_intersected_segment = *it;
00222         int j = last_intersected.back();
00223         if(last_intersected_segment != 5 && last_intersected_segment != j){
00224           //add the target of each rectangle segment in the list
00225           if(last_intersected_segment > j)
00226             while(last_intersected_segment > j){
00227               result.push_back(s[j].target());
00228               j++;
00229             }
00230           else{
00231             while(j<4){
00232               result.push_back(s[j].target());
00233               j++;
00234             }
00235             j = 0;
00236             while(j<last_intersected_segment){
00237               result.push_back(s[j].target());
00238               j++;
00239             }
00240           }
00241         }
00242       }//end if(outside)
00243 
00244       //test if were not intersections 
00245       //between the triangle and the rectangle
00246       if(status_intersected[0] == 0 && status_intersected[1] == 0 && 
00247         status_intersected[2] == 0 && status_intersected[3] == 0)
00248       {
00249         //should test if the rectangle is inside the triangle
00250         if(t.bounded_side(upper_left) == CGAL::ON_BOUNDED_SIDE){
00251           for(int k=0; k<4; k++)
00252             result.push_back(s[k].source());
00253         }
00254       }
00255 
00256       switch(result.size()){
00257         case 0:
00258           return Object();
00259         case 1:
00260           return make_object(result[0]);
00261         case 2:
00262           return make_object(Segment(result[0], result[1]));
00263         case 3:
00264           return make_object(Triangle_2<R>(result[0], result[1], result[2]));
00265         default:
00266           return make_object(result);
00267       }
00268 
00269     }//end if(intersection)
00270     return Object();
00271   }//end intersection
00272 }//end namespace
00273 
00274 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines