00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029 #include <utility>
00030
00031 #include "GeomHelper.h"
00032 #include "Boundary.h"
00033 #include "Position2DVector.h"
00034 #include "Position2D.h"
00035
00036 #ifdef CHECK_MEMORY_LEAKS
00037 #include <foreign/nvwa/debug_new.h>
00038 #endif // CHECK_MEMORY_LEAKS
00039
00040
00041
00042
00043
00044 Boundary::Boundary()
00045 : myXmin(10000000000.0), myXmax(-10000000000.0),
00046 myYmin(10000000000.0), myYmax(-10000000000.0),
00047 myWasInitialised(false) {}
00048
00049
00050 Boundary::Boundary(SUMOReal x1, SUMOReal y1, SUMOReal x2, SUMOReal y2)
00051 : myXmin(10000000000.0), myXmax(-10000000000.0),
00052 myYmin(10000000000.0), myYmax(-10000000000.0),
00053 myWasInitialised(false) {
00054 add(x1, y1);
00055 add(x2, y2);
00056 }
00057
00058
00059 Boundary::~Boundary() {}
00060
00061
00062 void
00063 Boundary::reset() {
00064 myXmin = 10000000000.0;
00065 myXmax = -10000000000.0;
00066 myYmin = 10000000000.0;
00067 myYmax = -10000000000.0;
00068 myWasInitialised = false;
00069 }
00070
00071
00072 void
00073 Boundary::add(SUMOReal x, SUMOReal y) {
00074 if (!myWasInitialised) {
00075 myYmin = y;
00076 myYmax = y;
00077 myXmin = x;
00078 myXmax = x;
00079 } else {
00080 myXmin = myXmin < x ? myXmin : x;
00081 myXmax = myXmax > x ? myXmax : x;
00082 myYmin = myYmin < y ? myYmin : y;
00083 myYmax = myYmax > y ? myYmax : y;
00084 }
00085 myWasInitialised = true;
00086 }
00087
00088
00089 void
00090 Boundary::add(const Position2D &p) {
00091 add(p.x(), p.y());
00092 }
00093
00094
00095 void
00096 Boundary::add(const Boundary &p) {
00097 add(p.xmin(), p.ymin());
00098 add(p.xmax(), p.ymax());
00099 }
00100
00101
00102 Position2D
00103 Boundary::getCenter() const {
00104 return Position2D((myXmin+myXmax)/(SUMOReal) 2.0, (myYmin+myYmax)/(SUMOReal) 2.0);
00105 }
00106
00107
00108 SUMOReal
00109 Boundary::xmin() const {
00110 return myXmin;
00111 }
00112
00113
00114 SUMOReal
00115 Boundary::xmax() const {
00116 return myXmax;
00117 }
00118
00119
00120 SUMOReal
00121 Boundary::ymin() const {
00122 return myYmin;
00123 }
00124
00125
00126 SUMOReal
00127 Boundary::ymax() const {
00128 return myYmax;
00129 }
00130
00131
00132 SUMOReal
00133 Boundary::getWidth() const {
00134 return myXmax - myXmin;
00135 }
00136
00137
00138 SUMOReal
00139 Boundary::getHeight() const {
00140 return myYmax - myYmin;
00141 }
00142
00143
00144 bool
00145 Boundary::around(const Position2D &p, SUMOReal offset) const {
00146 return
00147 (p.x()<=myXmax+offset && p.x()>=myXmin-offset) &&
00148 (p.y()<=myYmax+offset && p.y()>=myYmin-offset);
00149 }
00150
00151
00152 bool
00153 Boundary::overlapsWith(const AbstractPoly &p, SUMOReal offset) const {
00154 if (
00155
00156 partialWithin(p, offset) ||
00157
00158 p.partialWithin(*this, offset)) {
00159 return true;
00160 }
00161
00162 return
00163 p.crosses(Position2D(myXmax+offset, myYmax+offset), Position2D(myXmin-offset, myYmax+offset))
00164 ||
00165 p.crosses(Position2D(myXmin-offset, myYmax+offset), Position2D(myXmin-offset, myYmin-offset))
00166 ||
00167 p.crosses(Position2D(myXmin-offset, myYmin-offset), Position2D(myXmax+offset, myYmin-offset))
00168 ||
00169 p.crosses(Position2D(myXmax+offset, myYmin-offset), Position2D(myXmax+offset, myYmax+offset));
00170 }
00171
00172
00173 bool
00174 Boundary::crosses(const Position2D &p1, const Position2D &p2) const {
00175 return
00176 GeomHelper::intersects(p1, p2, Position2D(myXmax, myYmax), Position2D(myXmin, myYmax))
00177 ||
00178 GeomHelper::intersects(p1, p2, Position2D(myXmin, myYmax), Position2D(myXmin, myYmin))
00179 ||
00180 GeomHelper::intersects(p1, p2, Position2D(myXmin, myYmin), Position2D(myXmax, myYmin))
00181 ||
00182 GeomHelper::intersects(p1, p2, Position2D(myXmax, myYmin), Position2D(myXmax, myYmax));
00183 }
00184
00185
00186 bool
00187 Boundary::partialWithin(const AbstractPoly &poly, SUMOReal offset) const {
00188 return
00189 poly.around(Position2D(myXmax, myYmax), offset) ||
00190 poly.around(Position2D(myXmin, myYmax), offset) ||
00191 poly.around(Position2D(myXmax, myYmin), offset) ||
00192 poly.around(Position2D(myXmin, myYmin), offset);
00193 }
00194
00195
00196 Boundary &
00197 Boundary::grow(SUMOReal by) {
00198 myXmax += by;
00199 myYmax += by;
00200 myXmin -= by;
00201 myYmin -= by;
00202 return *this;
00203 }
00204
00205
00206 void
00207 Boundary::flipY() {
00208 myYmin *= -1.0;
00209 myYmax *= -1.0;
00210 SUMOReal tmp = myYmin;
00211 myYmin = myYmax;
00212 myYmax = tmp;
00213 }
00214
00215
00216
00217 std::ostream &
00218 operator<<(std::ostream &os, const Boundary &b) {
00219 os << b.myXmin << "," << b.myYmin << "," << b.myXmax << "," << b.myYmax;
00220 return os;
00221 }
00222
00223
00224 void
00225 Boundary::set(SUMOReal xmin, SUMOReal ymin, SUMOReal xmax, SUMOReal ymax) {
00226 myXmin = xmin;
00227 myYmin = ymin;
00228 myXmax = xmax;
00229 myYmax = ymax;
00230 }
00231
00232
00233 void
00234 Boundary::moveby(SUMOReal x, SUMOReal y) {
00235 myXmin += x;
00236 myYmin += y;
00237 myXmax += x;
00238 myYmax += y;
00239 }
00240
00241
00242
00243
00244