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++) {
326 for (const_iterator i = begin(); i != end(); i++) {
338 tmp.push_back(tmp[0]);
340 const int endIndex = (int)tmp.size() - 1;
344 if (tmp.
area() != 0) {
346 for (
int i = 0; i < endIndex; i++) {
347 const SUMOReal z = tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
349 x += (tmp[i].x() + tmp[i + 1].x()) * z;
350 y += (tmp[i].y() + tmp[i + 1].y()) * z;
358 for (
int i = 0; i < endIndex; i++) {
360 x += (tmp[i].x() + tmp[i + 1].x()) * length / 2;
361 y += (tmp[i].y() + tmp[i + 1].y()) * length / 2;
364 if (lengthSum == 0) {
368 return Position(x / lengthSum, y / lengthSum);
376 for (
int i = 0; i < static_cast<int>(size()); i++) {
377 (*this)[i] = centroid + (((*this)[i] - centroid) * factor);
385 for (
int i = 0; i < static_cast<int>(size()); i++) {
386 (*this)[i] = centroid + (((*this)[i] - centroid) + offset);
403 for (const_iterator i = begin(); i != end() - 1; i++) {
404 len += (*i).distanceTo(*(i + 1));
412 for (const_iterator i = begin(); i != end() - 1; i++) {
413 len += (*i).distanceTo2D(*(i + 1));
427 tmp.push_back(tmp[0]);
429 const int endIndex = (int)tmp.size() - 1;
431 for (
int i = 0; i < endIndex; i++) {
432 area += tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
443 for (const_iterator i = begin(); i != end() - 1; i++) {
444 if (poly.
around(*i, offset)) {
458 std::pair<PositionVector, PositionVector>
467 first.push_back((*
this)[0]);
469 const_iterator it = begin() + 1;
470 SUMOReal next = first.back().distanceTo(*it);
474 first.push_back(*it);
476 next = first.back().distanceTo(*it);
478 if (fabs(where - (seen + next)) >
POSITION_EPS || it == end() - 1) {
485 first.push_back(*it);
488 for (; it != end(); it++) {
489 second.push_back(*it);
491 assert(first.size() >= 2);
492 assert(second.size() >= 2);
493 assert(first.back() == second.front());
495 return std::pair<PositionVector, PositionVector>(first, second);
501 for (PositionVector::const_iterator i = geom.begin(); i != geom.end(); i++) {
502 if (i != geom.begin()) {
519 for (
int i = 0; i < static_cast<int>(size()); i++) {
520 (*this)[i].add(xoff, yoff, zoff);
527 for (
int i = 0; i < static_cast<int>(size()); i++) {
528 (*this)[i].mul(1, -1);
536 return atan2(p1.
x(), p1.
y()) < atan2(p2.
x(), p2.
y());
555 if (p1.
x() != p2.
x()) {
556 return p1.
x() < p2.
x();
558 return p1.
y() < p2.
y();
566 return (P1.
x() - P0.
x()) * (P2.
y() - P0.
y()) - (P2.
x() - P0.
x()) * (P1.
y() - P0.
y());
580 if (size() > 0 && v.size() > 0 && back().distanceTo(v[0]) < sameThreshold) {
581 copy(v.begin() + 1, v.end(), back_inserter(*
this));
583 copy(v.begin(), v.end(), back_inserter(*
this));
599 ret.push_back(begPos);
602 const_iterator i = begin();
604 while ((i + 1) != end()
606 seen + (*i).distanceTo(*(i + 1)) < beginOffset) {
607 seen += (*i).distanceTo(*(i + 1));
611 while ((i + 1) != end()
613 seen + (*i).distanceTo(*(i + 1)) < endOffset) {
616 seen += (*i).distanceTo(*(i + 1));
636 ret.push_back(begPos);
639 const_iterator i = begin();
641 while ((i + 1) != end()
643 seen + (*i).distanceTo2D(*(i + 1)) < beginOffset) {
644 seen += (*i).distanceTo2D(*(i + 1));
648 while ((i + 1) != end()
650 seen + (*i).distanceTo2D(*(i + 1)) < endOffset) {
653 seen += (*i).distanceTo2D(*(i + 1));
664 if (beginIndex < 0) {
665 beginIndex += (int)size();
668 assert(beginIndex < (
int)size());
669 assert(beginIndex + count <= (
int)size());
671 for (
int i = beginIndex; i < beginIndex + count; ++i) {
672 result.push_back((*
this)[i]);
680 return front().angleTo2D(back());
689 for (const_iterator i = begin(); i != end() - 1; i++) {
693 if (dist < minDist) {
694 nearestPos = pos + seen;
700 if (cornerDist < minDist) {
705 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
707 minDist = cornerDist;
711 seen += (*i).distanceTo2D(*(i + 1));
730 for (const_iterator i = begin(); i != end() - 1; i++) {
734 if (dist < minDist) {
735 nearestPos = pos + seen;
737 sign =
isLeft(*i, *(i + 1), p) >= 0 ? -1 : 1;
742 if (cornerDist < minDist) {
747 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
749 minDist = cornerDist;
750 sign =
isLeft(*(i - 1), *i, p) >= 0 ? -1 : 1;
754 seen += (*i).distanceTo2D(*(i + 1));
756 if (nearestPos != -1) {
757 return Position(nearestPos, sign * minDist);
770 for (
int i = 0; i < (int)size(); i++) {
772 if (dist < minDist) {
784 int insertionIndex = 1;
785 for (
int i = 0; i < (int)size() - 1; i++) {
789 if (dist < minDist) {
790 insertionIndex = i + 1;
794 insert(begin() + insertionIndex, p);
795 return insertionIndex;
799 std::vector<SUMOReal>
801 std::vector<SUMOReal> ret;
802 for (const_iterator i = other.begin(); i != other.end() - 1; i++) {
804 copy(atSegment.begin(), atSegment.end(), back_inserter(ret));
810 std::vector<SUMOReal>
812 std::vector<SUMOReal> ret;
814 for (const_iterator i = begin(); i != end() - 1; i++) {
818 if (
intersects(p1, p2, lp1, lp2, 0., &x, &y, &m)) {
819 ret.push_back(
Position(x, y).distanceTo2D(p1) + pos);
868 for (const_reverse_iterator i = rbegin(); i != rend(); i++) {
878 return Position((beg.
y() - end.
y()) * scale, (end.
x() - beg.
x()) * scale);
888 for (
int i = 0; i < static_cast<int>(size()); i++) {
891 const Position& to = (*this)[i + 1];
892 shape.push_back(from -
sideOffset(from, to, amount));
893 }
else if (i == static_cast<int>(size()) - 1) {
894 const Position& from = (*this)[i - 1];
896 shape.push_back(to -
sideOffset(from, to, amount));
898 const Position& from = (*this)[i - 1];
900 const Position& to = (*this)[i + 1];
903 const SUMOReal extrapolateDev = fromMe[1].distanceTo2D(to);
906 shape.push_back(me -
sideOffset(from, to, amount));
913 shape.push_back(fromMe[1]);
932 assert((
int)size() > pos + 1);
933 return (*
this)[pos].angleTo2D((*
this)[pos + 1]);
939 if (size() == 0 || (*
this)[0] == back()) {
942 push_back((*
this)[0]);
946 std::vector<SUMOReal>
948 std::vector<SUMOReal> ret;
950 for (i = begin(); i != end(); i++) {
956 for (i = s.begin(); i != s.end(); i++) {
970 }
else if (size() == 1) {
971 return front().distanceTo(p);
999 return size() >= 2 && (*this)[0] == back();
1006 iterator last = begin();
1007 for (iterator i = begin() + 1; i != end() && (!assertLength || size() > 2);) {
1008 if (last->almostSame(*i, minDist)) {
1021 if (size() == v2.size()) {
1022 for (
int i = 0; i < (int)size(); i++) {
1023 if ((*
this)[i] != v2[i]) {
1039 for (const_iterator i = begin(); i != end() - 1; i++) {
1040 if ((*i).z() != (*(i + 1)).z()) {
1053 const SUMOReal eps = std::numeric_limits<SUMOReal>::epsilon();
1054 const double denominator = (p22.
y() - p21.
y()) * (p12.
x() - p11.
x()) - (p22.
x() - p21.
x()) * (p12.
y() - p11.
y());
1055 const double numera = (p22.
x() - p21.
x()) * (p11.
y() - p21.
y()) - (p22.
y() - p21.
y()) * (p11.
x() - p21.
x());
1056 const double numerb = (p12.
x() - p11.
x()) * (p11.
y() - p21.
y()) - (p12.
y() - p11.
y()) * (p11.
x() - p21.
x());
1058 if (fabs(numera) < eps && fabs(numerb) < eps && fabs(denominator) < eps) {
1064 if (p11.
x() != p12.
x()) {
1065 a1 = p11.
x() < p12.
x() ? p11.
x() : p12.
x();
1066 a2 = p11.
x() < p12.
x() ? p12.
x() : p11.
x();
1067 a3 = p21.
x() < p22.
x() ? p21.
x() : p22.
x();
1068 a4 = p21.
x() < p22.
x() ? p22.
x() : p21.
x();
1070 a1 = p11.
y() < p12.
y() ? p11.
y() : p12.
y();
1071 a2 = p11.
y() < p12.
y() ? p12.
y() : p11.
y();
1072 a3 = p21.
y() < p22.
y() ? p21.
y() : p22.
y();
1073 a4 = p21.
y() < p22.
y() ? p22.
y() : p21.
y();
1075 if (a1 <= a3 && a3 <= a2) {
1082 if (a3 <= a1 && a1 <= a4) {
1091 if (p11.
x() != p12.
x()) {
1092 *mu = (a - p11.
x()) / (p12.
x() - p11.
x());
1094 *y = p11.
y() + (*mu) * (p12.
y() - p11.
y());
1098 if (p12.
y() == p11.
y()) {
1101 *mu = (a - p11.
y()) / (p12.
y() - p11.
y());
1110 if (fabs(denominator) < eps) {
1114 double mua = numera / denominator;
1116 if (fabs(p12.
x() - p22.
x()) < eps && fabs(p12.
y() - p22.
y()) < eps) {
1119 const double offseta = withinDist / p11.
distanceTo2D(p12);
1120 const double offsetb = withinDist / p21.
distanceTo2D(p22);
1121 const double mub = numerb / denominator;
1122 if (mua < -offseta || mua > 1 + offseta || mub < -offsetb || mub > 1 + offsetb) {
1127 *x = p11.
x() + mua * (p12.
x() - p11.
x());
1128 *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...