51 #ifdef CHECK_MEMORY_LEAKS 53 #endif // CHECK_MEMORY_LEAKS 62 std::copy(v.begin(), v.end(), std::back_inserter(*
this));
67 std::copy(beg, end, std::back_inserter(*
this));
88 for (const_iterator i = begin(); i != end() - 1; i++) {
93 (*(i + 1)).x() - p.
x(),
94 (*(i + 1)).y() - p.
y());
98 (*(end() - 1)).x() - p.
x(),
99 (*(end() - 1)).y() - p.
y());
101 (*(begin())).x() - p.
x(),
102 (*(begin())).y() - p.
y());
104 return (!(fabs(angle) <
M_PI));
110 for (const_iterator i = begin(); i != end() - 1; i++) {
111 if (poly.
around(*i, offset)) {
124 for (const_iterator i = begin(); i != end() - 1; i++) {
138 for (const_iterator i = begin(); i != end() - 1; i++) {
151 for (const_iterator i = begin(); i != end() - 1; i++) {
153 if (
intersects(*i, *(i + 1), p1, p2, withinDist, &x, &y, &m)) {
163 for (const_iterator i = begin(); i != end() - 1; i++) {
177 return at((
int)size() + index);
187 return at((
int)size() + index);
194 const_iterator i = begin();
197 const SUMOReal nextLength = (*i).distanceTo(*(i + 1));
198 if (seenLength + nextLength > pos) {
201 seenLength += nextLength;
202 }
while (++i != end() - 1);
209 const_iterator i = begin();
212 const SUMOReal nextLength = (*i).distanceTo2D(*(i + 1));
213 if (seenLength + nextLength > pos) {
216 seenLength += nextLength;
217 }
while (++i != end() - 1);
227 const_iterator i = begin();
233 if (seenLength + nextLength > pos) {
236 seenLength += nextLength;
237 }
while (++i != end() - 1);
252 const_iterator i = begin();
258 if (seenLength + nextLength > pos) {
261 seenLength += nextLength;
262 }
while (++i != end() - 1);
273 if (pos < 0 || dist < pos) {
276 if (lateralOffset != 0) {
281 return p1 + (p2 - p1) * (pos / dist) + offset;
286 return p1 + (p2 - p1) * (pos / dist);
295 if (pos < 0 || dist < pos) {
298 if (lateralOffset != 0) {
303 return p1 + (p2 - p1) * (pos / dist) + offset;
308 return p1 + (p2 - p1) * (pos / dist);
315 for (const_iterator i = begin(); i != end(); i++) {
327 for (const_iterator i = begin(); i != end(); i++) {
340 tmp.push_back(tmp[0]);
342 const int endIndex = (int)tmp.size() - 1;
346 if (tmp.
area() != 0) {
348 for (
int i = 0; i < endIndex; i++) {
349 const SUMOReal z = tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
351 x += (tmp[i].x() + tmp[i + 1].x()) * z;
352 y += (tmp[i].y() + tmp[i + 1].y()) * z;
360 for (
int i = 0; i < endIndex; i++) {
362 x += (tmp[i].x() + tmp[i + 1].x()) * length / 2;
363 y += (tmp[i].y() + tmp[i + 1].y()) * length / 2;
366 if (lengthSum == 0) {
370 return Position(x / lengthSum, y / lengthSum);
378 for (
int i = 0; i < static_cast<int>(size()); i++) {
379 (*this)[i] = centroid + (((*this)[i] - centroid) * factor);
387 for (
int i = 0; i < static_cast<int>(size()); i++) {
388 (*this)[i] = centroid + (((*this)[i] - centroid) + offset);
405 for (const_iterator i = begin(); i != end() - 1; i++) {
406 len += (*i).distanceTo(*(i + 1));
414 for (const_iterator i = begin(); i != end() - 1; i++) {
415 len += (*i).distanceTo2D(*(i + 1));
429 tmp.push_back(tmp[0]);
431 const int endIndex = (int)tmp.size() - 1;
433 for (
int i = 0; i < endIndex; i++) {
434 area += tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
445 for (const_iterator i = begin(); i != end() - 1; i++) {
446 if (poly.
around(*i, offset)) {
460 std::pair<PositionVector, PositionVector>
469 first.push_back((*
this)[0]);
471 const_iterator it = begin() + 1;
472 SUMOReal next = first.back().distanceTo(*it);
476 first.push_back(*it);
478 next = first.back().distanceTo(*it);
480 if (fabs(where - (seen + next)) >
POSITION_EPS || it == end() - 1) {
487 first.push_back(*it);
490 for (; it != end(); it++) {
491 second.push_back(*it);
493 assert(first.size() >= 2);
494 assert(second.size() >= 2);
495 assert(first.back() == second.front());
497 return std::pair<PositionVector, PositionVector>(first, second);
503 for (PositionVector::const_iterator i = geom.begin(); i != geom.end(); i++) {
504 if (i != geom.begin()) {
521 for (
int i = 0; i < static_cast<int>(size()); i++) {
522 (*this)[i].add(xoff, yoff, zoff);
529 for (
int i = 0; i < static_cast<int>(size()); i++) {
530 (*this)[i].mul(1, -1);
538 return atan2(p1.
x(), p1.
y()) < atan2(p2.
x(), p2.
y());
557 if (p1.
x() != p2.
x()) {
558 return p1.
x() < p2.
x();
560 return p1.
y() < p2.
y();
568 return (P1.
x() - P0.
x()) * (P2.
y() - P0.
y()) - (P2.
x() - P0.
x()) * (P1.
y() - P0.
y());
582 if (size() > 0 && v.size() > 0 && back().distanceTo(v[0]) < sameThreshold) {
583 copy(v.begin() + 1, v.end(), back_inserter(*
this));
585 copy(v.begin(), v.end(), back_inserter(*
this));
601 ret.push_back(begPos);
604 const_iterator i = begin();
606 while ((i + 1) != end()
608 seen + (*i).distanceTo(*(i + 1)) < beginOffset) {
609 seen += (*i).distanceTo(*(i + 1));
613 while ((i + 1) != end()
615 seen + (*i).distanceTo(*(i + 1)) < endOffset) {
618 seen += (*i).distanceTo(*(i + 1));
638 ret.push_back(begPos);
641 const_iterator i = begin();
643 while ((i + 1) != end()
645 seen + (*i).distanceTo2D(*(i + 1)) < beginOffset) {
646 seen += (*i).distanceTo2D(*(i + 1));
650 while ((i + 1) != end()
652 seen + (*i).distanceTo2D(*(i + 1)) < endOffset) {
655 seen += (*i).distanceTo2D(*(i + 1));
666 if (beginIndex < 0) {
667 beginIndex += (int)size();
670 assert(beginIndex < (
int)size());
671 assert(beginIndex + count <= (
int)size());
673 for (
int i = beginIndex; i < beginIndex + count; ++i) {
674 result.push_back((*
this)[i]);
682 return front().angleTo2D(back());
691 for (const_iterator i = begin(); i != end() - 1; i++) {
695 if (dist < minDist) {
696 nearestPos = pos + seen;
702 if (cornerDist < minDist) {
707 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
709 minDist = cornerDist;
713 seen += (*i).distanceTo2D(*(i + 1));
732 for (const_iterator i = begin(); i != end() - 1; i++) {
736 if (dist < minDist) {
737 nearestPos = pos + seen;
739 sign =
isLeft(*i, *(i + 1), p) >= 0 ? -1 : 1;
744 if (cornerDist < minDist) {
749 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
751 minDist = cornerDist;
752 sign =
isLeft(*(i - 1), *i, p) >= 0 ? -1 : 1;
756 seen += (*i).distanceTo2D(*(i + 1));
758 if (nearestPos != -1) {
759 return Position(nearestPos, sign * minDist);
772 for (
int i = 0; i < (int)size(); i++) {
774 if (dist < minDist) {
786 int insertionIndex = 1;
787 for (
int i = 0; i < (int)size() - 1; i++) {
791 if (dist < minDist) {
792 insertionIndex = i + 1;
796 insert(begin() + insertionIndex, p);
797 return insertionIndex;
801 std::vector<SUMOReal>
803 std::vector<SUMOReal> ret;
804 for (const_iterator i = other.begin(); i != other.end() - 1; i++) {
806 copy(atSegment.begin(), atSegment.end(), back_inserter(ret));
812 std::vector<SUMOReal>
814 std::vector<SUMOReal> ret;
816 for (const_iterator i = begin(); i != end() - 1; i++) {
820 if (
intersects(p1, p2, lp1, lp2, 0., &x, &y, &m)) {
821 ret.push_back(
Position(x, y).distanceTo2D(p1) + pos);
870 for (const_reverse_iterator i = rbegin(); i != rend(); i++) {
880 return Position((beg.
y() - end.
y()) * scale, (end.
x() - beg.
x()) * scale);
890 for (
int i = 0; i < static_cast<int>(size()); i++) {
893 const Position& to = (*this)[i + 1];
894 shape.push_back(from -
sideOffset(from, to, amount));
895 }
else if (i == static_cast<int>(size()) - 1) {
896 const Position& from = (*this)[i - 1];
898 shape.push_back(to -
sideOffset(from, to, amount));
900 const Position& from = (*this)[i - 1];
902 const Position& to = (*this)[i + 1];
905 const SUMOReal extrapolateDev = fromMe[1].distanceTo2D(to);
908 shape.push_back(me -
sideOffset(from, to, amount));
913 shape.push_back(fromMe[1]);
925 shape.back().set(shape.back().x(), shape.back().y(), me.
z());
934 assert((
int)size() > pos + 1);
935 return (*
this)[pos].angleTo2D((*
this)[pos + 1]);
941 if (size() == 0 || (*
this)[0] == back()) {
944 push_back((*
this)[0]);
948 std::vector<SUMOReal>
950 std::vector<SUMOReal> ret;
952 for (i = begin(); i != end(); i++) {
958 for (i = s.begin(); i != s.end(); i++) {
972 }
else if (size() == 1) {
973 return front().distanceTo(p);
1001 return size() >= 2 && (*this)[0] == back();
1008 iterator last = begin();
1009 for (iterator i = begin() + 1; i != end() && (!assertLength || size() > 2);) {
1010 if (last->almostSame(*i, minDist)) {
1023 if (size() == v2.size()) {
1024 for (
int i = 0; i < (int)size(); i++) {
1025 if ((*
this)[i] != v2[i]) {
1041 for (const_iterator i = begin(); i != end() - 1; i++) {
1042 if ((*i).z() != (*(i + 1)).z()) {
1055 const SUMOReal eps = std::numeric_limits<SUMOReal>::epsilon();
1056 const double denominator = (p22.
y() - p21.
y()) * (p12.
x() - p11.
x()) - (p22.
x() - p21.
x()) * (p12.
y() - p11.
y());
1057 const double numera = (p22.
x() - p21.
x()) * (p11.
y() - p21.
y()) - (p22.
y() - p21.
y()) * (p11.
x() - p21.
x());
1058 const double numerb = (p12.
x() - p11.
x()) * (p11.
y() - p21.
y()) - (p12.
y() - p11.
y()) * (p11.
x() - p21.
x());
1060 if (fabs(numera) < eps && fabs(numerb) < eps && fabs(denominator) < eps) {
1066 if (p11.
x() != p12.
x()) {
1067 a1 = p11.
x() < p12.
x() ? p11.
x() : p12.
x();
1068 a2 = p11.
x() < p12.
x() ? p12.
x() : p11.
x();
1069 a3 = p21.
x() < p22.
x() ? p21.
x() : p22.
x();
1070 a4 = p21.
x() < p22.
x() ? p22.
x() : p21.
x();
1072 a1 = p11.
y() < p12.
y() ? p11.
y() : p12.
y();
1073 a2 = p11.
y() < p12.
y() ? p12.
y() : p11.
y();
1074 a3 = p21.
y() < p22.
y() ? p21.
y() : p22.
y();
1075 a4 = p21.
y() < p22.
y() ? p22.
y() : p21.
y();
1077 if (a1 <= a3 && a3 <= a2) {
1084 if (a3 <= a1 && a1 <= a4) {
1093 if (p11.
x() != p12.
x()) {
1094 *mu = (a - p11.
x()) / (p12.
x() - p11.
x());
1096 *y = p11.
y() + (*mu) * (p12.
y() - p11.
y());
1100 if (p12.
y() == p11.
y()) {
1103 *mu = (a - p11.
y()) / (p12.
y() - p11.
y());
1112 if (fabs(denominator) < eps) {
1116 double mua = numera / denominator;
1118 if (fabs(p12.
x() - p22.
x()) < eps && fabs(p12.
y() - p22.
y()) < eps) {
1121 const double offseta = withinDist / p11.
distanceTo2D(p12);
1122 const double offsetb = withinDist / p21.
distanceTo2D(p22);
1123 const double mub = numerb / denominator;
1124 if (mua < -offseta || mua > 1 + offseta || mub < -offsetb || mub > 1 + offsetb) {
1129 *x = p11.
x() + mua * (p12.
x() - p11.
x());
1130 *y = p11.
y() + mua * (p12.
y() - p11.
y());
void sub(SUMOReal dx, SUMOReal dy)
Substracts the given position from this one.
static SUMOReal angle2D(const Position &p1, const Position &p2)
Returns the angle between two vectors on a plane The angle is from vector 1 to vector 2...
static Position sideOffset(const Position &beg, const Position &end, const SUMOReal amount)
bool hasElevation() const
return whether two positions differ in z-coordinate
SUMOReal distance(const Position &p, bool perpendicular=false) const
SUMOReal rotationAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
PositionVector getSubpart2D(SUMOReal beginOffset, SUMOReal endOffset) const
void sortAsPolyCWByAngle()
void add(const Position &pos)
Adds the given position to this one.
friend std::ostream & operator<<(std::ostream &os, const PositionVector &geom)
Output operator.
Position getCentroid() const
Returns the centroid (closes the polygon if unclosed)
bool intersects(const Position &p1, const Position &p2) const
void scaleRelative(SUMOReal factor)
enlarges/shrinks the polygon by a factor based at the centroid
PositionVector getSubpartByIndex(int beginIndex, int count) const
bool partialWithin(const AbstractPoly &poly, SUMOReal offset=0) const
Returns the information whether this polygon lies partially within the given polygon.
SUMOReal distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
bool around(const Position &p, SUMOReal offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point ...
bool almostSame(const Position &p2, SUMOReal maxDiv=POSITION_EPS) const
SUMOReal beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position ...
const Position & operator[](int index) const
returns the position at the given index !!! exceptions?
SUMOReal x() const
Returns the x-position.
Position positionAtOffset2D(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
A class that stores a 2D geometrical boundary.
#define WRITE_WARNING(msg)
PositionVector reverse() const
SUMOReal slopeDegreeAtOffset(SUMOReal pos) const
Returns the slope at the given length.
PositionVector convexHull() const
~PositionVector()
Destructor.
void extrapolate2D(const SUMOReal val, const bool onlyFirst=false)
SUMOReal length2D() const
Returns the length.
std::vector< SUMOReal > distances(const PositionVector &s, bool perpendicular=false) const
void push_front_noDoublePos(const Position &p)
static SUMOReal legacyDegree(const SUMOReal angle, const bool positive=false)
void mirrorX()
mirror coordinates along the x-axis
A point in 2D or 3D with translation and scaling methods.
void add(SUMOReal xoff, SUMOReal yoff, SUMOReal zoff)
int indexOfClosest(const Position &p) const
int operator()(const Position &p1, const Position &p2) const
comparing operation
SUMOReal z() const
Returns the z-position.
Position positionAtOffset(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
int insertAtClosest(const Position &p)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
void sortByIncreasingXY()
bool operator==(const PositionVector &v2) const
comparing operation
std::pair< PositionVector, PositionVector > splitAt(SUMOReal where) const
Returns the two lists made when this list vector is splitted at the given point.
virtual bool around(const Position &p, SUMOReal offset=0) const =0
PositionVector()
Constructor.
SUMOReal length() const
Returns the length.
SUMOReal rotationDegreeAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
void add(SUMOReal x, SUMOReal y)
Makes the boundary include the given coordinate.
PositionVector simpleHull_2D(const PositionVector &V)
void removeDoublePoints(SUMOReal minDist=POSITION_EPS, bool assertLength=false)
Removes positions if too near.
SUMOReal angleAt2D(int pos) const
void scaleAbsolute(SUMOReal offset)
enlarges/shrinks the polygon by an absolute offset based at the centroid
SUMOReal y() const
Returns the y-position.
bool overlapsWith(const AbstractPoly &poly, SUMOReal offset=0) const
Returns the information whether the given polygon overlaps with this Again a boundary may be specifie...
static SUMOReal nearest_offset_on_line_to_point2D(const Position &lineStart, const Position &lineEnd, const Position &p, bool perpendicular=true)
Position intersectionPosition2D(const Position &p1, const Position &p2, const SUMOReal withinDist=0.) const
Position getLineCenter() const
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
void move2side(SUMOReal amount)
void push_back_noDoublePos(const Position &p)
int operator()(const Position &p1, const Position &p2) const
comparing operation
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
SUMOReal area() const
Returns the area (0 for non-closed)
std::vector< SUMOReal > intersectsAtLengths2D(const PositionVector &other) const
For all intersections between this vector and other, return the 2D-length of the subvector from this ...
void closePolygon()
ensures that the last position equals the first
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
increasing_x_y_sorter()
constructor
bool crosses(const Position &p1, const Position &p2) const
PositionVector getSubpart(SUMOReal beginOffset, SUMOReal endOffset) const
SUMOReal angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
void append(const PositionVector &v, SUMOReal sameThreshold=2.0)
void extrapolate(const SUMOReal val, const bool onlyFirst=false)
static const SUMOReal INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
SUMOReal isLeft(const Position &P0, const Position &P1, const Position &P2) const
static const Position INVALID
Position transformToVectorCoordinates(const Position &p, bool extend=false) const
return position p within the length-wise coordinate system defined by this position vector...