A Discrete-Event Network Simulator
API
rectangle.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 #include "rectangle.h"
20 
21 #include "ns3/assert.h"
22 #include "ns3/fatal-error.h"
23 #include "ns3/vector.h"
24 
25 #include <algorithm>
26 #include <cmath>
27 #include <sstream>
28 
29 namespace ns3
30 {
31 
32 Rectangle::Rectangle(double _xMin, double _xMax, double _yMin, double _yMax)
33  : xMin(_xMin),
34  xMax(_xMax),
35  yMin(_yMin),
36  yMax(_yMax)
37 {
38 }
39 
41  : xMin(0.0),
42  xMax(0.0),
43  yMin(0.0),
44  yMax(0.0)
45 {
46 }
47 
48 bool
49 Rectangle::IsInside(const Vector& position) const
50 {
51  return position.x <= this->xMax && position.x >= this->xMin && position.y <= this->yMax &&
52  position.y >= this->yMin;
53 }
54 
56 Rectangle::GetClosestSide(const Vector& position) const
57 {
58  if (IsInside(position))
59  {
60  double xMinDist = std::abs(position.x - this->xMin);
61  double xMaxDist = std::abs(this->xMax - position.x);
62  double yMinDist = std::abs(position.y - this->yMin);
63  double yMaxDist = std::abs(this->yMax - position.y);
64  double minX = std::min(xMinDist, xMaxDist);
65  double minY = std::min(yMinDist, yMaxDist);
66  if (minX < minY)
67  {
68  if (xMinDist < xMaxDist)
69  {
70  return LEFT;
71  }
72  else
73  {
74  return RIGHT;
75  }
76  }
77  else
78  {
79  if (yMinDist < yMaxDist)
80  {
81  return BOTTOM;
82  }
83  else
84  {
85  return TOP;
86  }
87  }
88  }
89  else
90  {
91  if (position.x < this->xMin)
92  {
93  if (position.y < this->yMin)
94  {
95  double yDiff = this->yMin - position.y;
96  double xDiff = this->xMin - position.x;
97  if (yDiff > xDiff)
98  {
99  return BOTTOM;
100  }
101  else
102  {
103  return LEFT;
104  }
105  }
106  else if (position.y < this->yMax)
107  {
108  return LEFT;
109  }
110  else
111  {
112  double yDiff = position.y - this->yMax;
113  double xDiff = this->xMin - position.x;
114  if (yDiff > xDiff)
115  {
116  return TOP;
117  }
118  else
119  {
120  return LEFT;
121  }
122  }
123  }
124  else if (position.x < this->xMax)
125  {
126  if (position.y < this->yMin)
127  {
128  return BOTTOM;
129  }
130  else if (position.y < this->yMax)
131  {
133  "This region should have been reached if the IsInside check was true");
134  return TOP; // silence compiler warning
135  }
136  else
137  {
138  return TOP;
139  }
140  }
141  else
142  {
143  if (position.y < this->yMin)
144  {
145  double yDiff = this->yMin - position.y;
146  double xDiff = position.x - this->xMin;
147  if (yDiff > xDiff)
148  {
149  return BOTTOM;
150  }
151  else
152  {
153  return RIGHT;
154  }
155  }
156  else if (position.y < this->yMax)
157  {
158  return RIGHT;
159  }
160  else
161  {
162  double yDiff = position.y - this->yMax;
163  double xDiff = position.x - this->xMin;
164  if (yDiff > xDiff)
165  {
166  return TOP;
167  }
168  else
169  {
170  return RIGHT;
171  }
172  }
173  }
174  }
175 }
176 
177 Vector
178 Rectangle::CalculateIntersection(const Vector& current, const Vector& speed) const
179 {
180  NS_ASSERT(IsInside(current));
181  double xMaxY = current.y + (this->xMax - current.x) / speed.x * speed.y;
182  double xMinY = current.y + (this->xMin - current.x) / speed.x * speed.y;
183  double yMaxX = current.x + (this->yMax - current.y) / speed.y * speed.x;
184  double yMinX = current.x + (this->yMin - current.y) / speed.y * speed.x;
185  bool xMaxYOk = (xMaxY <= this->yMax && xMaxY >= this->yMin);
186  bool xMinYOk = (xMinY <= this->yMax && xMinY >= this->yMin);
187  bool yMaxXOk = (yMaxX <= this->xMax && yMaxX >= this->xMin);
188  bool yMinXOk = (yMinX <= this->xMax && yMinX >= this->xMin);
189  if (xMaxYOk && speed.x >= 0)
190  {
191  return Vector(this->xMax, xMaxY, 0.0);
192  }
193  else if (xMinYOk && speed.x <= 0)
194  {
195  return Vector(this->xMin, xMinY, 0.0);
196  }
197  else if (yMaxXOk && speed.y >= 0)
198  {
199  return Vector(yMaxX, this->yMax, 0.0);
200  }
201  else if (yMinXOk && speed.y <= 0)
202  {
203  return Vector(yMinX, this->yMin, 0.0);
204  }
205  else
206  {
207  NS_ASSERT(false);
208  // quiet compiler
209  return Vector(0.0, 0.0, 0.0);
210  }
211 }
212 
214 
222 std::ostream&
223 operator<<(std::ostream& os, const Rectangle& rectangle)
224 {
225  os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax;
226  return os;
227 }
228 
236 std::istream&
237 operator>>(std::istream& is, Rectangle& rectangle)
238 {
239  char c1;
240  char c2;
241  char c3;
242  is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 >> rectangle.yMax;
243  if (c1 != '|' || c2 != '|' || c3 != '|')
244  {
245  is.setstate(std::ios_base::failbit);
246  }
247  return is;
248 }
249 
250 } // namespace ns3
#define min(a, b)
Definition: 80211b.c:42
a 2d rectangle
Definition: rectangle.h:35
Side GetClosestSide(const Vector &position) const
Definition: rectangle.cc:56
double yMax
The y coordinate of the top bound of the rectangle.
Definition: rectangle.h:92
bool IsInside(const Vector &position) const
Definition: rectangle.cc:49
double xMax
The x coordinate of the right bound of the rectangle.
Definition: rectangle.h:90
Vector CalculateIntersection(const Vector &current, const Vector &speed) const
Definition: rectangle.cc:178
Side
enum for naming sides
Definition: rectangle.h:41
double xMin
The x coordinate of the left bound of the rectangle.
Definition: rectangle.h:89
Rectangle()
Create a zero-sized rectangle located at coordinates (0.0,0.0)
Definition: rectangle.cc:40
double yMin
The y coordinate of the bottom bound of the rectangle.
Definition: rectangle.h:91
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ATTRIBUTE_HELPER_CPP(Length)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:153
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129