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)) {
124 for (const_iterator i = begin(); i != end() - 1; i++) {
127 if (fabs(closest.
z() - (*i).z()) < zThreshold) {
133 for (const_iterator i = poly.begin(); i != poly.end() - 1; i++) {
136 if (fabs(closest.
z() - (*i).z()) < zThreshold) {
150 for (const_iterator i = begin(); i != end() - 1; i++) {
164 for (const_iterator i = begin(); i != end() - 1; i++) {
175 for (const_iterator i = begin(); i != end() - 1; i++) {
177 if (
intersects(*i, *(i + 1), p1, p2, withinDist, &x, &y, &m)) {
187 for (const_iterator i = begin(); i != end() - 1; i++) {
201 return at((
int)size() + index);
211 return at((
int)size() + index);
219 const_iterator i = begin();
222 const SUMOReal nextLength = (*i).distanceTo(*(i + 1));
223 if (seenLength + nextLength > pos) {
226 seenLength += nextLength;
227 }
while (++i != end() - 1);
228 if (lateralOffset == 0 || size() < 2) {
231 return positionAtOffset(*(end() - 2), *(end() - 1), (*(end() - 2)).distanceTo(*(end() - 1)), lateralOffset);
238 const_iterator i = begin();
241 const SUMOReal nextLength = (*i).distanceTo2D(*(i + 1));
242 if (seenLength + nextLength > pos) {
245 seenLength += nextLength;
246 }
while (++i != end() - 1);
256 const_iterator i = begin();
262 if (seenLength + nextLength > pos) {
265 seenLength += nextLength;
266 }
while (++i != end() - 1);
281 const_iterator i = begin();
287 if (seenLength + nextLength > pos) {
290 seenLength += nextLength;
291 }
while (++i != end() - 1);
301 if (pos < 0 || dist < pos) {
304 if (lateralOffset != 0) {
309 return p1 + (p2 - p1) * (pos / dist) + offset;
314 return p1 + (p2 - p1) * (pos / dist);
321 if (pos < 0 || dist < pos) {
324 if (lateralOffset != 0) {
329 return p1 + (p2 - p1) * (pos / dist) + offset;
334 return p1 + (p2 - p1) * (pos / dist);
341 for (const_iterator i = begin(); i != end(); i++) {
353 for (const_iterator i = begin(); i != end(); i++) {
366 tmp.push_back(tmp[0]);
368 const int endIndex = (int)tmp.size() - 1;
372 if (tmp.
area() != 0) {
374 for (
int i = 0; i < endIndex; i++) {
375 const SUMOReal z = tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
377 x += (tmp[i].x() + tmp[i + 1].x()) * z;
378 y += (tmp[i].y() + tmp[i + 1].y()) * z;
386 for (
int i = 0; i < endIndex; i++) {
388 x += (tmp[i].x() + tmp[i + 1].x()) * length / 2;
389 y += (tmp[i].y() + tmp[i + 1].y()) * length / 2;
392 if (lengthSum == 0) {
396 return Position(x / lengthSum, y / lengthSum);
404 for (
int i = 0; i < static_cast<int>(size()); i++) {
405 (*this)[i] = centroid + (((*this)[i] - centroid) * factor);
413 for (
int i = 0; i < static_cast<int>(size()); i++) {
414 (*this)[i] = centroid + (((*this)[i] - centroid) + offset);
431 for (const_iterator i = begin(); i != end() - 1; i++) {
432 len += (*i).distanceTo(*(i + 1));
441 for (const_iterator i = begin(); i != end() - 1; i++) {
442 len += (*i).distanceTo2D(*(i + 1));
456 tmp.push_back(tmp[0]);
458 const int endIndex = (int)tmp.size() - 1;
460 for (
int i = 0; i < endIndex; i++) {
461 area += tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
472 for (const_iterator i = begin(); i != end() - 1; i++) {
473 if (poly.
around(*i, offset)) {
487 std::pair<PositionVector, PositionVector>
496 first.push_back((*
this)[0]);
498 const_iterator it = begin() + 1;
499 SUMOReal next = first.back().distanceTo(*it);
503 first.push_back(*it);
505 next = first.back().distanceTo(*it);
507 if (fabs(where - (seen + next)) >
POSITION_EPS || it == end() - 1) {
514 first.push_back(*it);
517 for (; it != end(); it++) {
518 second.push_back(*it);
520 assert(first.size() >= 2);
521 assert(second.size() >= 2);
522 assert(first.back() == second.front());
524 return std::pair<PositionVector, PositionVector>(first, second);
530 for (PositionVector::const_iterator i = geom.begin(); i != geom.end(); i++) {
531 if (i != geom.begin()) {
548 for (
int i = 0; i < static_cast<int>(size()); i++) {
549 (*this)[i].add(xoff, yoff, zoff);
556 add(offset.
x(), offset.
y(), offset.
z());
562 for (
int i = 0; i < static_cast<int>(size()); i++) {
563 (*this)[i].mul(1, -1);
573 return atan2(p1.
x(), p1.
y()) < atan2(p2.
x(), p2.
y());
589 if (p1.
x() != p2.
x()) {
590 return p1.
x() < p2.
x();
592 return p1.
y() < p2.
y();
598 return (P1.
x() - P0.
x()) * (P2.
y() - P0.
y()) - (P2.
x() - P0.
x()) * (P1.
y() - P0.
y());
612 if (size() > 0 && v.size() > 0 && back().distanceTo(v[0]) < sameThreshold) {
613 copy(v.begin() + 1, v.end(), back_inserter(*
this));
615 copy(v.begin(), v.end(), back_inserter(*
this));
631 ret.push_back(begPos);
634 const_iterator i = begin();
636 while ((i + 1) != end()
638 seen + (*i).distanceTo(*(i + 1)) < beginOffset) {
639 seen += (*i).distanceTo(*(i + 1));
643 while ((i + 1) != end()
645 seen + (*i).distanceTo(*(i + 1)) < endOffset) {
648 seen += (*i).distanceTo(*(i + 1));
653 if (ret.size() == 1) {
654 ret.push_back(endPos);
671 ret.push_back(begPos);
674 const_iterator i = begin();
676 while ((i + 1) != end()
678 seen + (*i).distanceTo2D(*(i + 1)) < beginOffset) {
679 seen += (*i).distanceTo2D(*(i + 1));
683 while ((i + 1) != end()
685 seen + (*i).distanceTo2D(*(i + 1)) < endOffset) {
688 seen += (*i).distanceTo2D(*(i + 1));
693 if (ret.size() == 1) {
694 ret.push_back(endPos);
702 if (beginIndex < 0) {
703 beginIndex += (int)size();
706 assert(beginIndex < (
int)size());
707 assert(beginIndex + count <= (
int)size());
709 for (
int i = beginIndex; i < beginIndex + count; ++i) {
710 result.push_back((*
this)[i]);
718 return front().angleTo2D(back());
727 for (const_iterator i = begin(); i != end() - 1; i++) {
731 if (dist < minDist) {
732 nearestPos = pos + seen;
738 if (cornerDist < minDist) {
743 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
745 minDist = cornerDist;
749 seen += (*i).distanceTo2D(*(i + 1));
768 for (const_iterator i = begin(); i != end() - 1; i++) {
772 if (dist < minDist) {
773 nearestPos = pos + seen;
775 sign =
isLeft(*i, *(i + 1), p) >= 0 ? -1 : 1;
780 if (cornerDist < minDist) {
785 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
787 minDist = cornerDist;
788 sign =
isLeft(*(i - 1), *i, p) >= 0 ? -1 : 1;
792 seen += (*i).distanceTo2D(*(i + 1));
794 if (nearestPos != -1) {
795 return Position(nearestPos, sign * minDist);
808 for (
int i = 0; i < (int)size(); i++) {
810 if (dist < minDist) {
822 int insertionIndex = 1;
823 for (
int i = 0; i < (int)size() - 1; i++) {
827 if (dist < minDist) {
828 insertionIndex = i + 1;
832 insert(begin() + insertionIndex, p);
833 return insertionIndex;
843 int removalIndex = 0;
844 for (
int i = 0; i < (int)size(); i++) {
846 if (dist < minDist) {
851 erase(begin() + removalIndex);
856 std::vector<SUMOReal>
858 std::vector<SUMOReal> ret;
859 for (const_iterator i = other.begin(); i != other.end() - 1; i++) {
861 copy(atSegment.begin(), atSegment.end(), back_inserter(ret));
867 std::vector<SUMOReal>
869 std::vector<SUMOReal> ret;
871 for (const_iterator i = begin(); i != end() - 1; i++) {
875 if (
intersects(p1, p2, lp1, lp2, 0., &x, &y, &m)) {
876 ret.push_back(
Position(x, y).distanceTo2D(p1) + pos);
925 for (const_reverse_iterator i = rbegin(); i != rend(); i++) {
935 return Position((beg.
y() - end.
y()) * scale, (end.
x() - beg.
x()) * scale);
948 for (
int i = 0; i < static_cast<int>(size()); i++) {
951 const Position& to = (*this)[i + 1];
952 shape.push_back(from -
sideOffset(from, to, amount));
953 }
else if (i == static_cast<int>(size()) - 1) {
954 const Position& from = (*this)[i - 1];
956 shape.push_back(to -
sideOffset(from, to, amount));
958 const Position& from = (*this)[i - 1];
960 const Position& to = (*this)[i + 1];
963 const SUMOReal extrapolateDev = fromMe[1].distanceTo2D(to);
966 shape.push_back(me -
sideOffset(from, to, amount));
971 shape.push_back(fromMe[1]);
982 shape.push_back(meNew);
985 shape.back().set(shape.back().x(), shape.back().y(), me.
z());
994 assert((
int)size() > pos + 1);
995 return (*
this)[pos].angleTo2D((*
this)[pos + 1]);
1001 if (size() == 0 || (*
this)[0] == back()) {
1004 push_back((*
this)[0]);
1008 std::vector<SUMOReal>
1010 std::vector<SUMOReal> ret;
1012 for (i = begin(); i != end(); i++) {
1015 ret.push_back(dist);
1018 for (i = s.begin(); i != s.end(); i++) {
1021 ret.push_back(dist);
1032 }
else if (size() == 1) {
1033 return front().distanceTo(p);
1062 return size() >= 2 && (*this)[0] == back();
1069 iterator last = begin();
1070 for (iterator i = begin() + 1; i != end() && (!assertLength || size() > 2);) {
1071 if (last->almostSame(*i, minDist)) {
1084 if (size() == v2.size()) {
1085 for (
int i = 0; i < (int)size(); i++) {
1086 if ((*
this)[i] != v2[i]) {
1102 for (const_iterator i = begin(); i != end() - 1; i++) {
1103 if ((*i).z() != (*(i + 1)).z()) {
1113 const SUMOReal eps = std::numeric_limits<SUMOReal>::epsilon();
1114 const double denominator = (p22.
y() - p21.
y()) * (p12.
x() - p11.
x()) - (p22.
x() - p21.
x()) * (p12.
y() - p11.
y());
1115 const double numera = (p22.
x() - p21.
x()) * (p11.
y() - p21.
y()) - (p22.
y() - p21.
y()) * (p11.
x() - p21.
x());
1116 const double numerb = (p12.
x() - p11.
x()) * (p11.
y() - p21.
y()) - (p12.
y() - p11.
y()) * (p11.
x() - p21.
x());
1118 if (fabs(numera) < eps && fabs(numerb) < eps && fabs(denominator) < eps) {
1124 if (p11.
x() != p12.
x()) {
1125 a1 = p11.
x() < p12.
x() ? p11.
x() : p12.
x();
1126 a2 = p11.
x() < p12.
x() ? p12.
x() : p11.
x();
1127 a3 = p21.
x() < p22.
x() ? p21.
x() : p22.
x();
1128 a4 = p21.
x() < p22.
x() ? p22.
x() : p21.
x();
1130 a1 = p11.
y() < p12.
y() ? p11.
y() : p12.
y();
1131 a2 = p11.
y() < p12.
y() ? p12.
y() : p11.
y();
1132 a3 = p21.
y() < p22.
y() ? p21.
y() : p22.
y();
1133 a4 = p21.
y() < p22.
y() ? p22.
y() : p21.
y();
1135 if (a1 <= a3 && a3 <= a2) {
1142 if (a3 <= a1 && a1 <= a4) {
1151 if (p11.
x() != p12.
x()) {
1152 *mu = (a - p11.
x()) / (p12.
x() - p11.
x());
1154 *y = p11.
y() + (*mu) * (p12.
y() - p11.
y());
1158 if (p12.
y() == p11.
y()) {
1161 *mu = (a - p11.
y()) / (p12.
y() - p11.
y());
1170 if (fabs(denominator) < eps) {
1174 double mua = numera / denominator;
1176 if (fabs(p12.
x() - p22.
x()) < eps && fabs(p12.
y() - p22.
y()) < eps) {
1179 const double offseta = withinDist / p11.
distanceTo2D(p12);
1180 const double offsetb = withinDist / p21.
distanceTo2D(p22);
1181 const double mub = numerb / denominator;
1182 if (mua < -offseta || mua > 1 + offseta || mub < -offsetb || mub > 1 + offsetb) {
1187 *x = p11.
x() + mua * (p12.
x() - p11.
x());
1188 *y = p11.
y() + mua * (p12.
y() - p11.
y());
1199 for (
int i = 0; i < (int)size(); i++) {
1203 const SUMOReal xnew = x * c - y * s;
1204 const SUMOReal ynew = x * s + y * c;
1205 (*this)[i].set(xnew, ynew, z);
1213 bool changed =
true;
1214 while (changed && result.size() > 3) {
1216 for (
int i = 0; i < (int)result.size(); i++) {
1218 const Position& p2 = result[(i + 2) % result.size()];
1219 const int middleIndex = (i + 1) % result.size();
1220 const Position& p0 = result[middleIndex];
1222 const SUMOReal triangleArea2 = fabs((p2.
y() - p1.
y()) * p0.
x() - (p2.
x() - p1.
x()) * p0.
y() + p2.
x() * p1.
y() - p2.
y() * p1.
x());
1226 result.erase(result.begin() + middleIndex);
1246 distToClosest = tmp[tmp.
indexOfClosest(base)].distanceTo2D(base);
1248 result.push_back(p);
1249 result.push_back(base);
1258 const SUMOReal z0 = (*this)[0].z();
1260 const SUMOReal dz = (*this)[1].z() - z0;
1262 if (size() > 2 && dz != 0) {
1272 const SUMOReal dz2 = result[iLast].z() - z0;
1274 for (
int i = 1; i < iLast; ++i) {
1275 seen += result[i].distanceTo2D(result[i - 1]);
1276 result[i].set(result[i].x(), result[i].y(), z0 + dz2 * seen / dist2);
1286 if (index < 0 || index >= (
int)size()) {
1290 for (
int i = 1; i <= index; ++i) {
1291 seen += (*this)[i].distanceTo2D((*
this)[i - 1]);
1300 for (
int i = 1; i < (int)size(); ++i) {
1301 const Position& p1 = (*this)[i - 1];
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)
friend std::ostream & operator<<(std::ostream &os, const PositionVector &geom)
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
SUMOReal getOverlapWith(const PositionVector &poly, SUMOReal zThreshold) const
Returns the maximum overlaps between this and the given polygon (when not separated by at least zThre...
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
checki if two position is almost the sme as other
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
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
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
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.
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.
PositionVector smoothedZFront(SUMOReal dist=std::numeric_limits< SUMOReal >::max()) const
returned vector that is smoothed at the front (within dist)
SUMOReal offsetAtIndex2D(int index) const
return the offset at the given index
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)
virtual bool around(const Position &p, SUMOReal offset=0) const =0
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 ...
SUMOReal getMaxGrade() const
return the maximum grade of all segments as a fraction of zRange/length2D
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
static const Position INVALID
used to indicate that a position is valid
Position transformToVectorCoordinates(const Position &p, bool extend=false) const
return position p within the length-wise coordinate system defined by this position vector...