|
SUMO - Simulation of Urban MObility
|
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 (C) 2001-2011 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 // Position with coordinates {SUMOReal x, y;} 00048 PositionVector 00049 simpleHull_2D(const PositionVector& 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<Position> 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 00078 // incrementally add an exterior vertex to the deque hull 00079 // get the rightmost tangent at the deque bot 00080 while (isLeft(D[bot], D[bot+1], V[i]) <= 0) { 00081 ++bot; // remove bot of deque 00082 if (bot>=(int) D.size()) { 00083 throw ProcessError(); 00084 } 00085 } 00086 if (bot==0) { 00087 throw ProcessError(); 00088 } 00089 D[--bot] = V[i]; // insert V[i] at bot of deque 00090 00091 if (top==0||top>=(int) D.size()) { 00092 throw ProcessError(); 00093 } 00094 // get the leftmost tangent at the deque top 00095 while (isLeft(D[top-1], D[top], V[i]) <= 0) { 00096 --top; // pop top of deque 00097 if (top==0||top>=(int) D.size()) { 00098 throw ProcessError(); 00099 } 00100 } 00101 00102 if (top+1>=(int) D.size()) { 00103 throw ProcessError(); 00104 } 00105 D[++top] = V[i]; // push V[i] onto top of deque 00106 } 00107 00108 // transcribe deque D[] to the output hull array H[] 00109 int h; // hull vertex counter 00110 PositionVector H; 00111 for (h=0; h <= (top-bot); h++) { 00112 if (bot + h>=(int) D.size()) { 00113 throw ProcessError(); 00114 } 00115 H.push_back_noDoublePos(D[bot + h]); 00116 } 00117 return H; 00118 } 00119 00120 00121 00122 /****************************************************************************/ 00123