00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "rectangle.h"
00021 #include "vector.h"
00022 #include "ns3/assert.h"
00023 #include "ns3/fatal-error.h"
00024 #include <cmath>
00025 #include <algorithm>
00026 #include <sstream>
00027
00028 namespace ns3 {
00029
00030 Rectangle::Rectangle (double _xMin, double _xMax,
00031 double _yMin, double _yMax)
00032 : xMin (_xMin),
00033 xMax (_xMax),
00034 yMin (_yMin),
00035 yMax (_yMax)
00036 {}
00037
00038 Rectangle::Rectangle ()
00039 : xMin (0.0),
00040 xMax (0.0),
00041 yMin (0.0),
00042 yMax (0.0)
00043 {}
00044
00045 bool
00046 Rectangle::IsInside (const Vector &position) const
00047 {
00048 return
00049 position.x <= this->xMax && position.x >= this->xMin &&
00050 position.y <= this->yMax && position.y >= this->yMin;
00051 }
00052
00053 Rectangle::Side
00054 Rectangle::GetClosestSide (const Vector &position) const
00055 {
00056 double xMinDist = std::abs (position.x - this->xMin);
00057 double xMaxDist = std::abs (this->xMax - position.x);
00058 double yMinDist = std::abs (position.y - this->yMin);
00059 double yMaxDist = std::abs (this->yMax - position.y);
00060 double minX = std::min (xMinDist, xMaxDist);
00061 double minY = std::min (yMinDist, yMaxDist);
00062 if (minX < minY)
00063 {
00064 if (xMinDist < xMaxDist)
00065 {
00066 return LEFT;
00067 }
00068 else
00069 {
00070 return RIGHT;
00071 }
00072 }
00073 else
00074 {
00075 if (yMinDist < yMaxDist)
00076 {
00077 return BOTTOM;
00078 }
00079 else
00080 {
00081 return TOP;
00082 }
00083 }
00084 }
00085
00086 Vector
00087 Rectangle::CalculateIntersection (const Vector ¤t, const Vector &speed) const
00088 {
00089 NS_ASSERT (IsInside (current));
00090 double xMaxY = current.y + (this->xMax - current.x) / speed.x * speed.y;
00091 double xMinY = current.y + (this->xMin - current.x) / speed.x * speed.y;
00092 double yMaxX = current.x + (this->yMax - current.y) / speed.y * speed.x;
00093 double yMinX = current.x + (this->yMin - current.y) / speed.y * speed.x;
00094 bool xMaxYOk = (xMaxY <= this->yMax && xMaxY >= this->yMin);
00095 bool xMinYOk = (xMinY <= this->yMax && xMinY >= this->yMin);
00096 bool yMaxXOk = (yMaxX <= this->xMax && yMaxX >= this->xMin);
00097 bool yMinXOk = (yMinX <= this->xMax && yMinX >= this->xMin);
00098 if (xMaxYOk && speed.x >= 0)
00099 {
00100 return Vector (this->xMax, xMaxY, 0.0);
00101 }
00102 else if (xMinYOk && speed.x <= 0)
00103 {
00104 return Vector (this->xMin, xMinY, 0.0);
00105 }
00106 else if (yMaxXOk && speed.y >= 0)
00107 {
00108 return Vector (yMaxX, this->yMax, 0.0);
00109 }
00110 else if (yMinXOk && speed.y <= 0)
00111 {
00112 return Vector (yMinX, this->yMin, 0.0);
00113 }
00114 else
00115 {
00116 NS_ASSERT (false);
00117
00118 return Vector (0.0, 0.0, 0.0);
00119 }
00120
00121 }
00122
00123 ATTRIBUTE_HELPER_CPP (Rectangle);
00124
00125 std::ostream &
00126 operator << (std::ostream &os, const Rectangle &rectangle)
00127 {
00128 os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax;
00129 return os;
00130 }
00131 std::istream &
00132 operator >> (std::istream &is, Rectangle &rectangle)
00133 {
00134 char c1, c2, c3;
00135 is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 >> rectangle.yMax;
00136 if (c1 != '|' ||
00137 c2 != '|' ||
00138 c3 != '|')
00139 {
00140 is.setstate (std::ios_base::failbit);
00141 }
00142 return is;
00143 }
00144
00145
00146 }