Helper_ConvexHull.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Copyright 2002, softSurfer (www.softsurfer.com)
00008 // This code may be freely used and modified for any purpose
00009 // providing that this copyright notice is included with it.
00010 // SoftSurfer makes no warranty for this code, and cannot be held
00011 // liable for any real or imagined damage resulting from its use.
00012 // Users of this code must verify correctness for their application.
00013 /****************************************************************************/
00014 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00015 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00016 /****************************************************************************/
00017 //
00018 //   This program is free software; you can redistribute it and/or modify
00019 //   it under the terms of the GNU General Public License as published by
00020 //   the Free Software Foundation; either version 2 of the License, or
00021 //   (at your option) any later version.
00022 //
00023 /****************************************************************************/
00024 
00025 
00026 // ===========================================================================
00027 // included modules
00028 // ===========================================================================
00029 #ifdef _MSC_VER
00030 #include <windows_config.h>
00031 #else
00032 #include <config.h>
00033 #endif
00034 
00035 #include "Helper_ConvexHull.h"
00036 
00037 
00038 #include <utils/common/UtilExceptions.h>
00039 #include <iostream>
00040 
00041 #ifdef CHECK_MEMORY_LEAKS
00042 #include <foreign/nvwa/debug_new.h>
00043 #endif // CHECK_MEMORY_LEAKS
00044 
00045 
00046 // Assume that a class is already given for the object:
00047 //    Position2D with coordinates {SUMOReal x, y;}
00048 Position2DVector
00049 simpleHull_2D(const Position2DVector &V) {
00050     if (V.size()<3) {
00051         throw ProcessError();
00052     }
00053     // initialize a deque D[] from bottom to top so that the
00054     // 1st three vertices of V[] are a counterclockwise triangle
00055     int n = (int) V.size();
00056     std::vector<Position2D> D(2*n+1);
00057     int bot = n-2, top = bot+3;   // initial bottom and top deque indices
00058     D[bot] = D[top] = V[2];       // 3rd vertex is at both bot and top
00059     if (isLeft(V[0], V[1], V[2]) > 0) {
00060         D[bot+1] = V[0];
00061         D[bot+2] = V[1];          // ccw vertices are: 2,0,1,2
00062     } else {
00063         D[bot+1] = V[1];
00064         D[bot+2] = V[0];          // ccw vertices are: 2,1,0,2
00065     }
00066 
00067     // compute the hull on the deque D[]
00068     for (int i=3; i < n; i++) {   // process the rest of vertices
00069         // test if next vertex is inside the deque hull
00070         if (bot>=(int) D.size()||top-1>=(int) D.size()||i>=(int) V.size()) {
00071             throw ProcessError();
00072         }
00073         if ((isLeft(D[bot], D[bot+1], V[i]) > 0) &&
00074                 (isLeft(D[top-1], D[top], V[i]) > 0))
00075             continue;         // skip an interior vertex
00076 
00077         // incrementally add an exterior vertex to the deque hull
00078         // get the rightmost tangent at the deque bot
00079         while (isLeft(D[bot], D[bot+1], V[i]) <= 0) {
00080             ++bot;                // remove bot of deque
00081             if (bot>=(int) D.size()) {
00082                 throw ProcessError();
00083             }
00084         }
00085         if (bot==0) {
00086             throw ProcessError();
00087         }
00088         D[--bot] = V[i];          // insert V[i] at bot of deque
00089 
00090         if (top==0||top>=(int) D.size()) {
00091             throw ProcessError();
00092         }
00093         // get the leftmost tangent at the deque top
00094         while (isLeft(D[top-1], D[top], V[i]) <= 0) {
00095             --top;                // pop top of deque
00096             if (top==0||top>=(int) D.size()) {
00097                 throw ProcessError();
00098             }
00099         }
00100 
00101         if (top+1>=(int) D.size()) {
00102             throw ProcessError();
00103         }
00104         D[++top] = V[i];          // push V[i] onto top of deque
00105     }
00106 
00107     // transcribe deque D[] to the output hull array H[]
00108     int h;        // hull vertex counter
00109     Position2DVector H;
00110     for (h=0; h <= (top-bot); h++) {
00111         if (bot + h>=(int) D.size()) {
00112             throw ProcessError();
00113         }
00114         H.push_back_noDoublePos(D[bot + h]);
00115     }
00116     return H;
00117 }
00118 
00119 
00120 
00121 /****************************************************************************/
00122 

Generated on Wed May 5 00:06:30 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6