51 #ifdef CHECK_MEMORY_LEAKS
53 #endif // CHECK_MEMORY_LEAKS
63 std::copy(v.begin(), v.end(), std::back_inserter(*
this));
68 std::copy(beg, end, std::back_inserter(*
this));
89 for (const_iterator i = begin(); i != end() - 1; i++) {
94 (*(i + 1)).x() - p.
x(),
95 (*(i + 1)).y() - p.
y());
99 (*(end() - 1)).x() - p.
x(),
100 (*(end() - 1)).y() - p.
y());
102 (*(begin())).x() - p.
x(),
103 (*(begin())).y() - p.
y());
105 return (!(fabs(angle) <
M_PI));
111 for (const_iterator i = begin(); i != end() - 1; i++) {
112 if (poly.
around(*i, offset)) {
125 for (const_iterator i = begin(); i != end() - 1; i++) {
139 for (const_iterator i = begin(); i != end() - 1; i++) {
150 for (const_iterator i = begin(); i != end() - 1; i++) {
152 if (
intersects(*i, *(i + 1), p1, p2, withinDist, &x, &y, &m)) {
162 for (const_iterator i = begin(); i != end() - 1; i++) {
176 return at((
int)size() + index);
186 return at((
int)size() + index);
193 const_iterator i = begin();
196 const SUMOReal nextLength = (*i).distanceTo(*(i + 1));
197 if (seenLength + nextLength > pos) {
200 seenLength += nextLength;
201 }
while (++i != end() - 1);
208 const_iterator i = begin();
211 const SUMOReal nextLength = (*i).distanceTo2D(*(i + 1));
212 if (seenLength + nextLength > pos) {
215 seenLength += nextLength;
216 }
while (++i != end() - 1);
226 const_iterator i = begin();
232 if (seenLength + nextLength > pos) {
235 seenLength += nextLength;
236 }
while (++i != end() - 1);
251 const_iterator i = begin();
257 if (seenLength + nextLength > pos) {
260 seenLength += nextLength;
261 }
while (++i != end() - 1);
271 if (pos < 0 || dist < pos) {
274 if (lateralOffset != 0) {
279 return p1 + (p2 - p1) * (pos / dist) + offset;
284 return p1 + (p2 - p1) * (pos / dist);
291 if (pos < 0 || dist < pos) {
294 if (lateralOffset != 0) {
299 return p1 + (p2 - p1) * (pos / dist) + offset;
304 return p1 + (p2 - p1) * (pos / dist);
311 for (const_iterator i = begin(); i != end(); i++) {
323 for (const_iterator i = begin(); i != end(); i++) {
336 tmp.push_back(tmp[0]);
338 const int endIndex = (int)tmp.size() - 1;
342 if (tmp.
area() != 0) {
344 for (
int i = 0; i < endIndex; i++) {
345 const SUMOReal z = tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
347 x += (tmp[i].x() + tmp[i + 1].x()) * z;
348 y += (tmp[i].y() + tmp[i + 1].y()) * z;
356 for (
int i = 0; i < endIndex; i++) {
358 x += (tmp[i].x() + tmp[i + 1].x()) * length / 2;
359 y += (tmp[i].y() + tmp[i + 1].y()) * length / 2;
362 if (lengthSum == 0) {
366 return Position(x / lengthSum, y / lengthSum);
374 for (
int i = 0; i < static_cast<int>(size()); i++) {
375 (*this)[i] = centroid + (((*this)[i] - centroid) * factor);
383 for (
int i = 0; i < static_cast<int>(size()); i++) {
384 (*this)[i] = centroid + (((*this)[i] - centroid) + offset);
401 for (const_iterator i = begin(); i != end() - 1; i++) {
402 len += (*i).distanceTo(*(i + 1));
411 for (const_iterator i = begin(); i != end() - 1; i++) {
412 len += (*i).distanceTo2D(*(i + 1));
426 tmp.push_back(tmp[0]);
428 const int endIndex = (int)tmp.size() - 1;
430 for (
int i = 0; i < endIndex; i++) {
431 area += tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
442 for (const_iterator i = begin(); i != end() - 1; i++) {
443 if (poly.
around(*i, offset)) {
457 std::pair<PositionVector, PositionVector>
466 first.push_back((*
this)[0]);
468 const_iterator it = begin() + 1;
469 SUMOReal next = first.back().distanceTo(*it);
473 first.push_back(*it);
475 next = first.back().distanceTo(*it);
477 if (fabs(where - (seen + next)) >
POSITION_EPS || it == end() - 1) {
484 first.push_back(*it);
487 for (; it != end(); it++) {
488 second.push_back(*it);
490 assert(first.size() >= 2);
491 assert(second.size() >= 2);
492 assert(first.back() == second.front());
494 return std::pair<PositionVector, PositionVector>(first, second);
500 for (PositionVector::const_iterator i = geom.begin(); i != geom.end(); i++) {
501 if (i != geom.begin()) {
518 for (
int i = 0; i < static_cast<int>(size()); i++) {
519 (*this)[i].add(xoff, yoff, zoff);
526 add(offset.
x(), offset.
y(), offset.
z());
532 for (
int i = 0; i < static_cast<int>(size()); i++) {
533 (*this)[i].mul(1, -1);
543 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();
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;
807 int removalIndex = 0;
808 for (
int i = 0; i < (int)size(); i++) {
810 if (dist < minDist) {
815 erase(begin() + removalIndex);
820 std::vector<SUMOReal>
822 std::vector<SUMOReal> ret;
823 for (const_iterator i = other.begin(); i != other.end() - 1; i++) {
825 copy(atSegment.begin(), atSegment.end(), back_inserter(ret));
831 std::vector<SUMOReal>
833 std::vector<SUMOReal> ret;
835 for (const_iterator i = begin(); i != end() - 1; i++) {
839 if (
intersects(p1, p2, lp1, lp2, 0., &x, &y, &m)) {
840 ret.push_back(
Position(x, y).distanceTo2D(p1) + pos);
889 for (const_reverse_iterator i = rbegin(); i != rend(); i++) {
899 return Position((beg.
y() - end.
y()) * scale, (end.
x() - beg.
x()) * scale);
912 for (
int i = 0; i < static_cast<int>(size()); i++) {
915 const Position& to = (*this)[i + 1];
916 shape.push_back(from -
sideOffset(from, to, amount));
917 }
else if (i == static_cast<int>(size()) - 1) {
918 const Position& from = (*this)[i - 1];
920 shape.push_back(to -
sideOffset(from, to, amount));
922 const Position& from = (*this)[i - 1];
924 const Position& to = (*this)[i + 1];
927 const SUMOReal extrapolateDev = fromMe[1].distanceTo2D(to);
930 shape.push_back(me -
sideOffset(from, to, amount));
935 shape.push_back(fromMe[1]);
947 shape.back().set(shape.back().x(), shape.back().y(), me.
z());
956 assert((
int)size() > pos + 1);
957 return (*
this)[pos].angleTo2D((*
this)[pos + 1]);
963 if (size() == 0 || (*
this)[0] == back()) {
966 push_back((*
this)[0]);
970 std::vector<SUMOReal>
972 std::vector<SUMOReal> ret;
974 for (i = begin(); i != end(); i++) {
980 for (i = s.begin(); i != s.end(); i++) {
994 }
else if (size() == 1) {
995 return front().distanceTo(p);
1024 return size() >= 2 && (*this)[0] == back();
1031 iterator last = begin();
1032 for (iterator i = begin() + 1; i != end() && (!assertLength || size() > 2);) {
1033 if (last->almostSame(*i, minDist)) {
1046 if (size() == v2.size()) {
1047 for (
int i = 0; i < (int)size(); i++) {
1048 if ((*
this)[i] != v2[i]) {
1064 for (const_iterator i = begin(); i != end() - 1; i++) {
1065 if ((*i).z() != (*(i + 1)).z()) {
1075 const SUMOReal eps = std::numeric_limits<SUMOReal>::epsilon();
1076 const double denominator = (p22.
y() - p21.
y()) * (p12.
x() - p11.
x()) - (p22.
x() - p21.
x()) * (p12.
y() - p11.
y());
1077 const double numera = (p22.
x() - p21.
x()) * (p11.
y() - p21.
y()) - (p22.
y() - p21.
y()) * (p11.
x() - p21.
x());
1078 const double numerb = (p12.
x() - p11.
x()) * (p11.
y() - p21.
y()) - (p12.
y() - p11.
y()) * (p11.
x() - p21.
x());
1080 if (fabs(numera) < eps && fabs(numerb) < eps && fabs(denominator) < eps) {
1086 if (p11.
x() != p12.
x()) {
1087 a1 = p11.
x() < p12.
x() ? p11.
x() : p12.
x();
1088 a2 = p11.
x() < p12.
x() ? p12.
x() : p11.
x();
1089 a3 = p21.
x() < p22.
x() ? p21.
x() : p22.
x();
1090 a4 = p21.
x() < p22.
x() ? p22.
x() : p21.
x();
1092 a1 = p11.
y() < p12.
y() ? p11.
y() : p12.
y();
1093 a2 = p11.
y() < p12.
y() ? p12.
y() : p11.
y();
1094 a3 = p21.
y() < p22.
y() ? p21.
y() : p22.
y();
1095 a4 = p21.
y() < p22.
y() ? p22.
y() : p21.
y();
1097 if (a1 <= a3 && a3 <= a2) {
1104 if (a3 <= a1 && a1 <= a4) {
1113 if (p11.
x() != p12.
x()) {
1114 *mu = (a - p11.
x()) / (p12.
x() - p11.
x());
1116 *y = p11.
y() + (*mu) * (p12.
y() - p11.
y());
1120 if (p12.
y() == p11.
y()) {
1123 *mu = (a - p11.
y()) / (p12.
y() - p11.
y());
1132 if (fabs(denominator) < eps) {
1136 double mua = numera / denominator;
1138 if (fabs(p12.
x() - p22.
x()) < eps && fabs(p12.
y() - p22.
y()) < eps) {
1141 const double offseta = withinDist / p11.
distanceTo2D(p12);
1142 const double offsetb = withinDist / p21.
distanceTo2D(p22);
1143 const double mub = numerb / denominator;
1144 if (mua < -offseta || mua > 1 + offseta || mub < -offsetb || mub > 1 + offsetb) {
1149 *x = p11.
x() + mua * (p12.
x() - p11.
x());
1150 *y = p11.
y() + mua * (p12.
y() - p11.
y());
1161 for (
int i = 0; i < (int)size(); i++) {
1165 const SUMOReal xnew = x * c - y * s;
1166 const SUMOReal ynew = x * s + y * c;
1167 (*this)[i].set(xnew, ynew, z);
1175 bool changed =
true;
1176 while (changed && result.size() > 3) {
1178 for (
int i = 0; i < (int)result.size(); i++) {
1180 const Position& p2 = result[(i + 2) % result.size()];
1181 const int middleIndex = (i + 1) % result.size();
1182 const Position& p0 = result[middleIndex];
1184 const SUMOReal triangleArea2 = fabs((p2.
y() - p1.
y()) * p0.
x() - (p2.
x() - p1.
x()) * p0.
y() + p2.
x() * p1.
y() - p2.
y() * p1.
x());
1188 result.erase(result.begin() + middleIndex);
1208 distToClosest = tmp[tmp.
indexOfClosest(base)].distanceTo2D(base);
1210 result.push_back(p);
1211 result.push_back(base);
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...
clase for increasing Sorter
static Position sideOffset(const Position &beg, const Position &end, const SUMOReal amount)
get a side position of position vector using a offset
bool hasElevation() const
return whether two positions differ in z-coordinate
SUMOReal rotationAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
PositionVector getSubpart2D(SUMOReal beginOffset, SUMOReal endOffset) const
get subpart of a position vector in two dimensions (Z is ignored)
void sortAsPolyCWByAngle()
short as polygon CV by angle
void add(const Position &pos)
Adds the given position to this one.
PositionVector getOrthogonal(const Position &p, SUMOReal extend, SUMOReal &distToClosest) const
return orthogonal through p (extending this vector if necessary)
Position getCentroid() const
Returns the centroid (closes the polygon if unclosed)
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
void scaleRelative(SUMOReal factor)
enlarges/shrinks the polygon by a factor based at the centroid
PositionVector getSubpartByIndex(int beginIndex, int count) const
get subpart of a position vector using index and a cout
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 ...
bool isClosed() const
check if PositionVector is closed
const Position & operator[](int index) const
returns the constat 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)
SUMOReal distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector) ...
PositionVector reverse() const
reverse position vector
SUMOReal slopeDegreeAtOffset(SUMOReal pos) const
Returns the slope at the given length.
void rotate2D(SUMOReal angle)
PositionVector convexHull() const
~PositionVector()
Destructor.
void extrapolate2D(const SUMOReal val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
SUMOReal length2D() const
Returns the length.
std::vector< SUMOReal > distances(const PositionVector &s, bool perpendicular=false) const
distances of all my points to s and all of s points to myself
void push_front_noDoublePos(const Position &p)
insert in front a non double position
PositionVector simplified() const
return the same shape with intermediate colinear points removed
static SUMOReal legacyDegree(const SUMOReal angle, const bool positive=false)
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
index of the closest position to p
int operator()(const Position &p1, const Position &p2) const
comparing operation for sort
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)
inserts p between the two closest positions and returns the insertion index
as_poly_cw_sorter()
constructor
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
void sortByIncreasingXY()
shory by increasing X-Y Psitions
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. Creates an empty position vector.
SUMOReal length() const
Returns the length.
SUMOReal rotationDegreeAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
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
get angle in certain position of position vector
void add(SUMOReal x, SUMOReal y, SUMOReal z=0)
Makes the boundary include the given coordinate.
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.
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
Returns the position of the intersection.
Position getLineCenter() const
get line center
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
void move2side(SUMOReal amount)
move position vector to side using certain ammount
void push_back_noDoublePos(const Position &p)
insert in back a non double position
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
int removeClosest(const Position &p)
removes the point closest to p and return the removal index
PositionVector getSubpart(SUMOReal beginOffset, SUMOReal endOffset) const
get subpart of a position vector
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)
extrapolate position vector
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
get left
std::ostream & operator<<(std::ostream &os, const PositionVector &geom)
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...