52 #ifdef CHECK_MEMORY_LEAKS
54 #endif // CHECK_MEMORY_LEAKS
63 std::copy(v.begin(), v.end(), std::back_inserter(*
this));
73 copy(p.begin(), p.end(), back_inserter(*
this));
99 for (const_iterator i = begin(); i != end() - 1; i++) {
104 (*(i + 1)).x() - p.
x(),
105 (*(i + 1)).y() - p.
y());
109 (*(end() - 1)).x() - p.
x(),
110 (*(end() - 1)).y() - p.
y());
112 (*(begin())).x() - p.
x(),
113 (*(begin())).y() - p.
y());
115 return (!(fabs(angle) <
M_PI));
121 for (const_iterator i = begin(); i != end() - 1; i++) {
122 if (poly.
around(*i, offset)) {
135 for (const_iterator i = begin(); i != end() - 1; i++) {
150 for (const_iterator i = begin(); i != end() - 1; i++) {
163 for (const_iterator i = begin(); i != end() - 1; i++) {
174 for (const_iterator i = begin(); i != end() - 1; i++) {
193 return at((
int)size() + index);
203 return at((
int)size() + index);
210 const_iterator i = begin();
213 const SUMOReal nextLength = (*i).distanceTo(*(i + 1));
214 if (seenLength + nextLength > pos) {
217 seenLength += nextLength;
218 }
while (++i != end() - 1);
225 const_iterator i = begin();
228 const SUMOReal nextLength = (*i).distanceTo2D(*(i + 1));
229 if (seenLength + nextLength > pos) {
232 seenLength += nextLength;
233 }
while (++i != end() - 1);
243 const_iterator i = begin();
246 SUMOReal nextLength = (*i).distanceTo(*(i + 1));
247 if (seenLength + nextLength > pos) {
248 Line l(*i, *(i + 1));
251 seenLength += nextLength;
252 }
while (++i != end() - 1);
253 Line l(*(end() - 2), *(end() - 1));
259 const_iterator i = begin();
262 SUMOReal nextLength = (*i).distanceTo(*(i + 1));
263 if (seenLength + nextLength > pos) {
264 Line l(*i, *(i + 1));
267 seenLength += nextLength;
268 }
while (++i != end() - 1);
269 Line l(*(end() - 2), *(end() - 1));
281 if (lateralOffset != 0) {
286 return p1 + (p2 - p1) * (pos / dist);
298 if (lateralOffset != 0) {
303 return p1 + (p2 - p1) * (pos / dist);
310 for (const_iterator i = begin(); i != end(); i++) {
321 for (const_iterator i = begin(); i != end(); i++) {
335 const int endIndex = (int)tmp.size() - 1;
339 if (tmp.
area() != 0) {
341 for (
int i = 0; i < endIndex; i++) {
342 const SUMOReal z = tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
344 x += (tmp[i].x() + tmp[i + 1].x()) * z;
345 y += (tmp[i].y() + tmp[i + 1].y()) * z;
353 for (
int i = 0; i < endIndex; i++) {
355 x += (tmp[i].x() + tmp[i + 1].x()) * length / 2;
356 y += (tmp[i].y() + tmp[i + 1].y()) * length / 2;
359 if (lengthSum == 0) {
363 return Position(x / lengthSum, y / lengthSum);
371 for (
int i = 0; i < static_cast<int>(size()); i++) {
372 (*this)[i] = centroid + (((*this)[i] - centroid) * factor);
380 for (
int i = 0; i < static_cast<int>(size()); i++) {
381 (*this)[i] = centroid + (((*this)[i] - centroid) + offset);
398 for (const_iterator i = begin(); i != end() - 1; i++) {
399 len += (*i).distanceTo(*(i + 1));
407 for (const_iterator i = begin(); i != end() - 1; i++) {
408 len += (*i).distanceTo2D(*(i + 1));
424 const int endIndex = (int)tmp.size() - 1;
426 for (
int i = 0; i < endIndex; i++) {
427 area += tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
438 for (const_iterator i = begin(); i != end() - 1; i++) {
439 if (poly.
around(*i, offset)) {
453 std::pair<PositionVector, PositionVector>
464 const_iterator it = begin() + 1;
465 SUMOReal next = first.back().distanceTo(*it);
471 next = first.back().distanceTo(*it);
473 if (fabs(where - (seen + next)) >
POSITION_EPS || it == end() - 1) {
476 Line tmpL(first.back(), *it);
477 Position p = tmpL.getPositionAtDistance(where - seen);
484 for (; it != end(); it++) {
487 assert(first.size() >= 2);
488 assert(second.size() >= 2);
489 assert(first.back() == second.front());
491 return std::pair<PositionVector, PositionVector>(first, second);
497 for (PositionVector::const_iterator i = geom.begin(); i != geom.end(); i++) {
498 if (i != geom.begin()) {
515 for (
int i = 0; i < static_cast<int>(size()); i++) {
516 (*this)[i].add(xoff, yoff, zoff);
523 for (
int i = 0; i < static_cast<int>(size()); i++) {
524 (*this)[i].mul(1, -1);
531 for (
int i = 0; i < static_cast<int>(size()); i++) {
532 (*this)[i].reshiftRotate(xoff, yoff, rot);
540 return atan2(p1.
x(), p1.
y()) < atan2(p2.
x(), p2.
y());
559 if (p1.
x() != p2.
x()) {
560 return p1.
x() < p2.
x();
562 return p1.
y() < p2.
y();
570 return (P1.
x() - P0.
x()) * (P2.
y() - P0.
y()) - (P2.
x() - P0.
x()) * (P1.
y() - P0.
y());
585 for (const_iterator i = begin(); i != end() - 1; i++) {
588 *i, *(i + 1), line.
p1(), line.
p2()));
597 if (back().distanceTo(v[0]) < 2) {
598 copy(v.begin() + 1, v.end(), back_inserter(*
this));
602 Line l1((*
this)[static_cast<int>(size()) - 2], back());
608 (*this)[
static_cast<int>(size()) - 1] = p;
609 copy(v.begin() + 1, v.end(), back_inserter(*
this));
612 copy(v.begin(), v.end(), back_inserter(*
this));
620 if (size() > 0 && v.size() > 0 && back().distanceTo(v[0]) < sameThreshold) {
621 copy(v.begin() + 1, v.end(), back_inserter(*
this));
623 copy(v.begin(), v.end(), back_inserter(*
this));
642 const_iterator i = begin();
644 while ((i + 1) != end()
646 seen + (*i).distanceTo(*(i + 1)) < beginOffset) {
647 seen += (*i).distanceTo(*(i + 1));
651 while ((i + 1) != end()
653 seen + (*i).distanceTo(*(i + 1)) < endOffset) {
661 seen += (*i).distanceTo(*(i + 1));
684 const_iterator i = begin();
686 while ((i + 1) != end()
688 seen + (*i).distanceTo2D(*(i + 1)) < beginOffset) {
689 seen += (*i).distanceTo2D(*(i + 1));
693 while ((i + 1) != end()
695 seen + (*i).distanceTo2D(*(i + 1)) < endOffset) {
703 seen += (*i).distanceTo2D(*(i + 1));
722 if (currDist >= 0 && currDist < dist) {
727 for (iterator i = begin(); i != end() - 1; i++, currPos++) {
729 if (currDist >= 0 && currDist < dist) {
735 for (
size_t j = 0; j < pos; j++) {
740 (*
this)[0], (*
this)[1], p);
745 if (np != *(begin())) {
747 if (np != *(begin())) {
750 assert(*(begin()) != *(end() - 1));
758 if (beginIndex < 0) {
759 beginIndex += (int)size();
762 assert(beginIndex < (
int)size());
763 assert(beginIndex + count <= (
int)size());
765 for (
int i = beginIndex; i < beginIndex + count; ++i) {
782 if (currDist >= 0 && currDist < dist) {
787 for (reverse_iterator i = rbegin(); i != rend() - 1; i++, currPos++) {
789 if (currDist >= 0 && currDist < dist) {
795 for (
size_t j = 0; j < pos; j++) {
801 (*
this)[static_cast<int>(size()) - 1], (*
this)[static_cast<int>(size()) - 2], p);
807 if (np != *(end() - 1)) {
809 if (np != *(end() - 1)) {
812 assert(*(begin()) != *(end() - 1));
820 Line tmp(front(), back());
840 for (const_iterator i = begin(); i != end() - 1; i++) {
844 if (dist < minDist) {
845 nearestPos = pos + seen;
851 if (cornerDist < minDist) {
856 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
858 minDist = cornerDist;
862 seen += (*i).distanceTo2D(*(i + 1));
881 for (const_iterator i = begin(); i != end() - 1; i++) {
885 if (dist < minDist) {
886 nearestPos = pos + seen;
888 sign =
isLeft(*i, *(i + 1), p) >= 0 ? -1 : 1;
893 if (cornerDist < minDist) {
898 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
900 minDist = cornerDist;
901 sign =
isLeft(*(i - 1), *i, p) >= 0 ? -1 : 1;
905 seen += (*i).distanceTo2D(*(i + 1));
907 if (nearestPos != -1) {
908 return Position(nearestPos, sign * minDist);
921 for (
int i = 0; i < (int)size(); i++) {
923 if (dist < minDist) {
937 int insertionIndex = 1;
938 for (
int i = 0; i < (int)size() - 1; i++) {
940 if (dist < minDist) {
941 insertionIndex = i + 1;
946 return insertionIndex;
950 std::vector<SUMOReal>
952 std::vector<SUMOReal> ret;
953 for (const_iterator i = other.begin(); i != other.end() - 1; i++) {
955 copy(atSegment.begin(), atSegment.end(), back_inserter(ret));
961 std::vector<SUMOReal>
963 std::vector<SUMOReal> ret;
965 for (const_iterator i = begin(); i != end() - 1; i++) {
966 Line l((*i), *(i + 1));
971 ret.push_back(atLength + pos);
986 (*
this)[static_cast<int>(size()) - 2], (*
this)[static_cast<int>(size()) - 1], val);
997 for (const_reverse_iterator i = rbegin(); i != rend(); i++) {
1010 for (
int i = 0; i < static_cast<int>(size()); i++) {
1014 std::pair<SUMOReal, SUMOReal> offsets =
1017 from.
y() - offsets.second, from.
z()));
1018 }
else if (i == static_cast<int>(size()) - 1) {
1021 std::pair<SUMOReal, SUMOReal> offsets =
1024 to.
y() - offsets.second, to.
z()));
1029 Line fromMe(from, me);
1034 std::pair<SUMOReal, SUMOReal> off =
1041 Line fromMe(from, me);
1046 std::pair<SUMOReal, SUMOReal> offsets =
1048 std::pair<SUMOReal, SUMOReal> offsets2 =
1051 Position(from.
x() - offsets.first, from.
y() - offsets.second),
1052 Position(me.
x() - offsets.first, me.
y() - offsets.second));
1055 Position(me.
x() - offsets2.first, me.
y() - offsets2.second),
1056 Position(to.
x() - offsets2.first, to.
y() - offsets2.second));
1098 assert((
int)size() > pos + 1);
1099 return Line((*
this)[pos], (*
this)[pos + 1]);
1111 return lineAt((
int)size() - 2);
1117 if (size() == 0 || (*
this)[0] == back()) {
1124 std::vector<SUMOReal>
1126 std::vector<SUMOReal> ret;
1128 for (i = begin(); i != end(); i++) {
1131 ret.push_back(dist);
1134 for (i = s.begin(); i != s.end(); i++) {
1137 ret.push_back(dist);
1148 }
else if (size() == 1) {
1149 return front().distanceTo(p);
1163 insert(begin() + index, p);
1165 insert(end() + index, p);
1172 assert(index < static_cast<int>(size()));
1173 assert(index + static_cast<int>(size()) >= 0);
1177 (*this)[index +
static_cast<int>(size())] = p;
1200 return size() >= 2 && (*this)[0] == back();
1207 iterator last = begin();
1208 for (iterator i = begin() + 1; i != end() && (!assertLength || size() > 2);) {
1209 if (last->almostSame(*i, minDist)) {
1224 for (iterator i = begin() + 1; i != end() - 1;) {
1238 if (size() == v2.size()) {
1239 for (
int i = 0; i < (int)size(); i++) {
1240 if ((*
this)[i] != v2[i]) {
1256 for (const_iterator i = begin(); i != end() - 1; i++) {
1257 if ((*i).z() != (*(i + 1)).z()) {
SUMOReal length2D() const
SUMOReal atan2DegreeAngle() const
static std::pair< SUMOReal, SUMOReal > getNormal90D_CW(const Position &beg, const Position &end, SUMOReal length, SUMOReal wanted_offset)
const Position & p2() const
static SUMOReal Angle2D(SUMOReal x1, SUMOReal y1, SUMOReal x2, SUMOReal y2)
bool hasElevation() const
return whether two positions differ in z-coordinate
SUMOReal distance(const Position &p, bool perpendicular=false) const
void removeColinearPoints()
void pruneFromBeginAt(const Position &p)
static Position intersection_position2D(const Position &p11, const Position &p12, const Position &p21, const Position &p22)
returns the intersection point of the (infinite) lines p11,p12 and p21,p22. If the given lines are pa...
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
PositionVector getSubpart2D(SUMOReal beginOffset, SUMOReal endOffset) const
void sortAsPolyCWByAngle()
void replaceAt(int index, const Position &by)
SUMOReal intersectsAtLength2D(const Line &v)
returns distance between myP1 and intersection or -1 if line segments do not intersect ...
void insertAt(int index, const Position &p)
SUMOReal atan2DegreeSlope() const
Position getPositionAtDistance2D(SUMOReal offset) const
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.
static Position extrapolate_second(const Position &p1, const Position &p2, SUMOReal length)
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
static Position extrapolate_first(const Position &p1, const Position &p2, SUMOReal length)
SUMOReal beginEndAngle() const
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.
SUMOReal length2D() const
Returns the length.
std::vector< SUMOReal > distances(const PositionVector &s, bool perpendicular=false) const
Position getPositionAtDistance(SUMOReal offset) const
static SUMOReal nearest_offset_on_line_to_point2D(const Position &l1, const Position &l2, const Position &p, bool perpendicular=true)
Line lineAt(int pos) const
static bool intersects(const Position &p11, const Position &p12, const Position &p21, const Position &p22)
return whether given lines intersect
void push_front_noDoublePos(const Position &p)
const Position & p1() const
void reshiftRotate(SUMOReal xoff, SUMOReal yoff, SUMOReal rot)
void mirrorX()
mirror coordinates along the x-axis
A point in 2D or 3D with translation and scaling methods.
Position pop_front()
Removes and returns the position at the fron of the list.
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
void push_front(const Position &p)
Puts the given position at the front of the list.
static SUMOReal distancePointLine(const Position &point, const Position &lineStart, const Position &lineEnd)
void move2side(SUMOReal amount)
SUMOReal z() const
Returns the z-position.
static SUMOReal closestDistancePointLine2D(const Position &point, const Position &lineStart, const Position &lineEnd, Position &outIntersection)
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()
Position intersectsAtPoint(const Position &p1, const Position &p2) const
SUMOReal atan2Angle() const
bool intersects(const Line &l) const
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
void extrapolate(SUMOReal val)
PositionVector()
Constructor.
void extrapolateBy(SUMOReal length)
SUMOReal length() const
Returns the length.
SUMOReal rotationDegreeAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
void push_back(const PositionVector &p)
Appends all positions from the given vector.
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.
PositionVector intersectionPoints2D(const Line &line) const
int appendWithCrossingPoint(const PositionVector &v)
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...
void pruneFromEndAt(const Position &p)
Position getLineCenter() const
void extrapolateBy2D(SUMOReal length)
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::ostream & operator<<(std::ostream &os, const MTRand &mtrand)
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
Position intersectsAt(const Line &l) const
PositionVector getSubpart(SUMOReal beginOffset, SUMOReal endOffset) const
void append(const PositionVector &v, SUMOReal sameThreshold=2.0)
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...