SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // A class that stores the 2D geometrical boundary 00010 /****************************************************************************/ 00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00013 /****************************************************************************/ 00014 // 00015 // This file is part of SUMO. 00016 // SUMO is free software: you can redistribute it and/or modify 00017 // it under the terms of the GNU General Public License as published by 00018 // the Free Software Foundation, either version 3 of the License, or 00019 // (at your option) any later version. 00020 // 00021 /****************************************************************************/ 00022 00023 00024 // =========================================================================== 00025 // included modules 00026 // =========================================================================== 00027 #ifdef _MSC_VER 00028 #include <windows_config.h> 00029 #else 00030 #include <config.h> 00031 #endif 00032 #include <utility> 00033 00034 #include "GeomHelper.h" 00035 #include "Boundary.h" 00036 #include "PositionVector.h" 00037 #include "Position.h" 00038 00039 #ifdef CHECK_MEMORY_LEAKS 00040 #include <foreign/nvwa/debug_new.h> 00041 #endif // CHECK_MEMORY_LEAKS 00042 00043 00044 // =========================================================================== 00045 // method definitions 00046 // =========================================================================== 00047 Boundary::Boundary() 00048 : myXmin(10000000000.0), myXmax(-10000000000.0), 00049 myYmin(10000000000.0), myYmax(-10000000000.0), 00050 myWasInitialised(false) {} 00051 00052 00053 Boundary::Boundary(SUMOReal x1, SUMOReal y1, SUMOReal x2, SUMOReal y2) 00054 : myXmin(10000000000.0), myXmax(-10000000000.0), 00055 myYmin(10000000000.0), myYmax(-10000000000.0), 00056 myWasInitialised(false) { 00057 add(x1, y1); 00058 add(x2, y2); 00059 } 00060 00061 00062 Boundary::~Boundary() {} 00063 00064 00065 void 00066 Boundary::reset() { 00067 myXmin = 10000000000.0; 00068 myXmax = -10000000000.0; 00069 myYmin = 10000000000.0; 00070 myYmax = -10000000000.0; 00071 myWasInitialised = false; 00072 } 00073 00074 00075 void 00076 Boundary::add(SUMOReal x, SUMOReal y) { 00077 if (!myWasInitialised) { 00078 myYmin = y; 00079 myYmax = y; 00080 myXmin = x; 00081 myXmax = x; 00082 } else { 00083 myXmin = myXmin < x ? myXmin : x; 00084 myXmax = myXmax > x ? myXmax : x; 00085 myYmin = myYmin < y ? myYmin : y; 00086 myYmax = myYmax > y ? myYmax : y; 00087 } 00088 myWasInitialised = true; 00089 } 00090 00091 00092 void 00093 Boundary::add(const Position& p) { 00094 add(p.x(), p.y()); 00095 } 00096 00097 00098 void 00099 Boundary::add(const Boundary& p) { 00100 add(p.xmin(), p.ymin()); 00101 add(p.xmax(), p.ymax()); 00102 } 00103 00104 00105 Position 00106 Boundary::getCenter() const { 00107 return Position((myXmin + myXmax) / (SUMOReal) 2.0, (myYmin + myYmax) / (SUMOReal) 2.0); 00108 } 00109 00110 00111 SUMOReal 00112 Boundary::xmin() const { 00113 return myXmin; 00114 } 00115 00116 00117 SUMOReal 00118 Boundary::xmax() const { 00119 return myXmax; 00120 } 00121 00122 00123 SUMOReal 00124 Boundary::ymin() const { 00125 return myYmin; 00126 } 00127 00128 00129 SUMOReal 00130 Boundary::ymax() const { 00131 return myYmax; 00132 } 00133 00134 00135 SUMOReal 00136 Boundary::getWidth() const { 00137 return myXmax - myXmin; 00138 } 00139 00140 00141 SUMOReal 00142 Boundary::getHeight() const { 00143 return myYmax - myYmin; 00144 } 00145 00146 00147 bool 00148 Boundary::around(const Position& p, SUMOReal offset) const { 00149 return 00150 (p.x() <= myXmax + offset && p.x() >= myXmin - offset) && 00151 (p.y() <= myYmax + offset && p.y() >= myYmin - offset); 00152 } 00153 00154 00155 bool 00156 Boundary::overlapsWith(const AbstractPoly& p, SUMOReal offset) const { 00157 if ( 00158 // check whether one of my points lies within the given poly 00159 partialWithin(p, offset) || 00160 // check whether the polygon lies within me 00161 p.partialWithin(*this, offset)) { 00162 return true; 00163 } 00164 // check whether the bounderies cross 00165 return 00166 p.crosses(Position(myXmax + offset, myYmax + offset), Position(myXmin - offset, myYmax + offset)) 00167 || 00168 p.crosses(Position(myXmin - offset, myYmax + offset), Position(myXmin - offset, myYmin - offset)) 00169 || 00170 p.crosses(Position(myXmin - offset, myYmin - offset), Position(myXmax + offset, myYmin - offset)) 00171 || 00172 p.crosses(Position(myXmax + offset, myYmin - offset), Position(myXmax + offset, myYmax + offset)); 00173 } 00174 00175 00176 bool 00177 Boundary::crosses(const Position& p1, const Position& p2) const { 00178 return 00179 GeomHelper::intersects(p1, p2, Position(myXmax, myYmax), Position(myXmin, myYmax)) 00180 || 00181 GeomHelper::intersects(p1, p2, Position(myXmin, myYmax), Position(myXmin, myYmin)) 00182 || 00183 GeomHelper::intersects(p1, p2, Position(myXmin, myYmin), Position(myXmax, myYmin)) 00184 || 00185 GeomHelper::intersects(p1, p2, Position(myXmax, myYmin), Position(myXmax, myYmax)); 00186 } 00187 00188 00189 bool 00190 Boundary::partialWithin(const AbstractPoly& poly, SUMOReal offset) const { 00191 return 00192 poly.around(Position(myXmax, myYmax), offset) || 00193 poly.around(Position(myXmin, myYmax), offset) || 00194 poly.around(Position(myXmax, myYmin), offset) || 00195 poly.around(Position(myXmin, myYmin), offset); 00196 } 00197 00198 00199 Boundary& 00200 Boundary::grow(SUMOReal by) { 00201 myXmax += by; 00202 myYmax += by; 00203 myXmin -= by; 00204 myYmin -= by; 00205 return *this; 00206 } 00207 00208 void 00209 Boundary::growWidth(SUMOReal by) { 00210 myXmin -= by; 00211 myXmax += by; 00212 } 00213 00214 00215 void 00216 Boundary::growHeight(SUMOReal by) { 00217 myYmin -= by; 00218 myYmax += by; 00219 } 00220 00221 void 00222 Boundary::flipY() { 00223 myYmin *= -1.0; 00224 myYmax *= -1.0; 00225 SUMOReal tmp = myYmin; 00226 myYmin = myYmax; 00227 myYmax = tmp; 00228 } 00229 00230 00231 00232 std::ostream& 00233 operator<<(std::ostream& os, const Boundary& b) { 00234 os << b.myXmin << "," << b.myYmin << "," << b.myXmax << "," << b.myYmax; 00235 return os; 00236 } 00237 00238 00239 void 00240 Boundary::set(SUMOReal xmin, SUMOReal ymin, SUMOReal xmax, SUMOReal ymax) { 00241 myXmin = xmin; 00242 myYmin = ymin; 00243 myXmax = xmax; 00244 myYmax = ymax; 00245 } 00246 00247 00248 void 00249 Boundary::moveby(SUMOReal x, SUMOReal y) { 00250 myXmin += x; 00251 myYmin += y; 00252 myXmax += x; 00253 myYmax += y; 00254 } 00255 00256 00257 00258 /****************************************************************************/ 00259