56 std::copy(v.begin(), v.end(), std::back_inserter(*
this));
61 std::copy(beg, end, std::back_inserter(*
this));
85 for (const_iterator i = begin(); i != end() - 1; i++) {
90 (*(i + 1)).x() - p.
x(),
91 (*(i + 1)).y() - p.
y());
95 (*(end() - 1)).x() - p.
x(),
96 (*(end() - 1)).y() - p.
y());
98 (*(begin())).x() - p.
x(),
99 (*(begin())).y() - p.
y());
101 return (!(fabs(angle) <
M_PI));
115 for (const_iterator i = begin(); i != end() - 1; i++) {
116 if (poly.
crosses(*i, *(i + 1))) {
120 if (size() > 2 && poly.
crosses(back(), front())) {
131 if ((size() == 0) || (poly.size() == 0)) {
135 for (const_iterator i = begin(); i != end() - 1; i++) {
138 if (fabs(closest.
z() - (*i).z()) < zThreshold) {
144 for (const_iterator i = poly.begin(); i != poly.end() - 1; i++) {
147 if (fabs(closest.
z() - (*i).z()) < zThreshold) {
161 for (const_iterator i = begin(); i != end() - 1; i++) {
175 for (const_iterator i = begin(); i != end() - 1; i++) {
186 for (const_iterator i = begin(); i != end() - 1; i++) {
188 if (
intersects(*i, *(i + 1), p1, p2, withinDist, &x, &y, &m)) {
198 for (const_iterator i = begin(); i != end() - 1; i++) {
216 if (index >= 0 && index < (
int)size()) {
218 }
else if (index < 0 && -index <= (
int)size()) {
219 return at((
int)size() + index);
221 throw ProcessError(
"Index out of range in bracket operator of PositionVector");
235 if (index >= 0 && index < (
int)size()) {
237 }
else if (index < 0 && -index <= (
int)size()) {
238 return at((
int)size() + index);
240 throw ProcessError(
"Index out of range in bracket operator of PositionVector");
250 const_iterator i = begin();
251 double seenLength = 0;
253 const double nextLength = (*i).distanceTo(*(i + 1));
254 if (seenLength + nextLength > pos) {
257 seenLength += nextLength;
258 }
while (++i != end() - 1);
259 if (lateralOffset == 0 || size() < 2) {
262 return positionAtOffset(*(end() - 2), *(end() - 1), (*(end() - 2)).distanceTo(*(end() - 1)), lateralOffset);
272 const_iterator i = begin();
273 double seenLength = 0;
275 const double nextLength = (*i).distanceTo2D(*(i + 1));
276 if (seenLength + nextLength > pos) {
279 seenLength += nextLength;
280 }
while (++i != end() - 1);
293 const_iterator i = begin();
294 double seenLength = 0;
299 if (seenLength + nextLength > pos) {
302 seenLength += nextLength;
303 }
while (++i != end() - 1);
321 const_iterator i = begin();
322 double seenLength = 0;
327 if (seenLength + nextLength > pos) {
330 seenLength += nextLength;
331 }
while (++i != end() - 1);
341 if (pos < 0. || dist < pos) {
344 if (lateralOffset != 0) {
352 return p1 + (p2 - p1) * (pos / dist) + offset;
357 return p1 + (p2 - p1) * (pos / dist);
364 if (pos < 0 || dist < pos) {
367 if (lateralOffset != 0) {
372 return p1 + (p2 - p1) * (pos / dist) + offset;
377 return p1 + (p2 - p1) * (pos / dist);
401 return Position(x / (
double) size(), y / (
double) size(), z / (
double)size());
412 tmp.push_back(tmp[0]);
414 const int endIndex = (int)tmp.size() - 1;
418 if (tmp.
area() != 0) {
420 for (
int i = 0; i < endIndex; i++) {
421 const double z = tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
423 x += (tmp[i].x() + tmp[i + 1].x()) * z;
424 y += (tmp[i].y() + tmp[i + 1].y()) * z;
431 double lengthSum = 0;
432 for (
int i = 0; i < endIndex; i++) {
433 double length = tmp[i].distanceTo(tmp[i + 1]);
434 x += (tmp[i].x() + tmp[i + 1].x()) * length / 2;
435 y += (tmp[i].y() + tmp[i + 1].y()) * length / 2;
438 if (lengthSum == 0) {
442 return Position(x / lengthSum, y / lengthSum);
450 for (
int i = 0; i < static_cast<int>(size()); i++) {
451 (*this)[i] = centroid + (((*this)[i] - centroid) * factor);
459 for (
int i = 0; i < static_cast<int>(size()); i++) {
460 (*this)[i] = centroid + (((*this)[i] - centroid) + offset);
481 for (const_iterator i = begin(); i != end() - 1; i++) {
482 len += (*i).distanceTo(*(i + 1));
494 for (const_iterator i = begin(); i != end() - 1; i++) {
495 len += (*i).distanceTo2D(*(i + 1));
509 tmp.push_back(tmp[0]);
511 const int endIndex = (int)tmp.size() - 1;
513 for (
int i = 0; i < endIndex; i++) {
514 area += tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
528 for (const_iterator i = begin(); i != end() - 1; i++) {
529 if (poly.
around(*i, offset)) {
543 std::pair<PositionVector, PositionVector>
549 if (where < 0 || where > len) {
552 if (where <= POSITION_EPS || where >= len -
POSITION_EPS) {
556 first.push_back((*
this)[0]);
558 const_iterator it = begin() + 1;
559 double next = use2D ? first.back().distanceTo2D(*it) : first.back().distanceTo(*it);
563 first.push_back(*it);
565 next = use2D ? first.back().distanceTo2D(*it) : first.back().distanceTo(*it);
567 if (fabs(where - (seen + next)) >
POSITION_EPS || it == end() - 1) {
576 first.push_back(*it);
579 for (; it != end(); it++) {
580 second.push_back(*it);
582 assert(first.size() >= 2);
583 assert(second.size() >= 2);
584 assert(first.back() == second.front());
586 return std::pair<PositionVector, PositionVector>(first, second);
592 for (PositionVector::const_iterator i = geom.begin(); i != geom.end(); i++) {
593 if (i != geom.begin()) {
610 for (
int i = 0; i < (int)size(); i++) {
611 (*this)[i].add(xoff, yoff, zoff);
618 sub(offset.
x(), offset.
y(), offset.
z());
624 for (
int i = 0; i < (int)size(); i++) {
625 (*this)[i].add(-xoff, -yoff, -zoff);
632 add(offset.
x(), offset.
y(), offset.
z());
639 for (
auto i1 = begin(); i1 != end(); ++i1) {
640 pv.push_back(*i1 + offset);
648 for (
int i = 0; i < (int)size(); i++) {
649 (*this)[i].mul(1, -1);
659 return atan2(p1.
x(), p1.
y()) < atan2(p2.
x(), p2.
y());
674 if (p1.
x() != p2.
x()) {
675 return p1.
x() < p2.
x();
677 return p1.
y() < p2.
y();
683 return (P1.
x() - P0.
x()) * (P2.
y() - P0.
y()) - (P2.
x() - P0.
x()) * (P1.
y() - P0.
y());
689 if ((size() > 0) && (v.size() > 0) && (back().distanceTo(v[0]) < sameThreshold)) {
690 copy(v.begin() + 1, v.end(), back_inserter(*
this));
692 copy(v.begin(), v.end(), back_inserter(*
this));
708 ret.push_back(begPos);
711 const_iterator i = begin();
713 while ((i + 1) != end()
715 seen + (*i).distanceTo(*(i + 1)) < beginOffset) {
716 seen += (*i).distanceTo(*(i + 1));
720 while ((i + 1) != end()
722 seen + (*i).distanceTo(*(i + 1)) < endOffset) {
725 seen += (*i).distanceTo(*(i + 1));
730 if (ret.size() == 1) {
731 ret.push_back(endPos);
751 ret.push_back(begPos);
754 const_iterator i = begin();
756 while ((i + 1) != end()
758 seen + (*i).distanceTo2D(*(i + 1)) < beginOffset) {
759 seen += (*i).distanceTo2D(*(i + 1));
763 while ((i + 1) != end()
765 seen + (*i).distanceTo2D(*(i + 1)) < endOffset) {
768 seen += (*i).distanceTo2D(*(i + 1));
773 if (ret.size() == 1) {
774 ret.push_back(endPos);
785 if (beginIndex < 0) {
786 beginIndex += (int)size();
789 assert(beginIndex < (
int)size());
790 assert(beginIndex + count <= (
int)size());
792 for (
int i = beginIndex; i < beginIndex + count; ++i) {
793 result.push_back((*
this)[i]);
804 return front().angleTo2D(back());
813 double minDist = std::numeric_limits<double>::max();
816 for (const_iterator i = begin(); i != end() - 1; i++) {
820 if (dist < minDist) {
821 nearestPos = pos + seen;
827 if (cornerDist < minDist) {
832 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
834 minDist = cornerDist;
838 seen += (*i).distanceTo2D(*(i + 1));
849 double minDist = std::numeric_limits<double>::max();
852 for (const_iterator i = begin(); i != end() - 1; i++) {
856 if (dist < minDist) {
857 const double pos25D = pos * (*i).distanceTo(*(i + 1)) / (*i).distanceTo2D(*(i + 1));
858 nearestPos = pos25D + seen;
864 if (cornerDist < minDist) {
869 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
871 minDist = cornerDist;
875 seen += (*i).distanceTo(*(i + 1));
893 double minDist = std::numeric_limits<double>::max();
894 double nearestPos = -1;
897 for (const_iterator i = begin(); i != end() - 1; i++) {
901 if (dist < minDist) {
902 nearestPos = pos + seen;
904 sign =
isLeft(*i, *(i + 1), p) >= 0 ? -1 : 1;
909 if (cornerDist < minDist) {
914 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
916 minDist = cornerDist;
917 sign =
isLeft(*(i - 1), *i, p) >= 0 ? -1 : 1;
921 seen += (*i).distanceTo2D(*(i + 1));
923 if (nearestPos != -1) {
924 return Position(nearestPos, sign * minDist);
936 double minDist = std::numeric_limits<double>::max();
939 for (
int i = 0; i < (int)size(); i++) {
941 if (dist < minDist) {
955 double minDist = std::numeric_limits<double>::max();
956 int insertionIndex = 1;
957 for (
int i = 0; i < (int)size() - 1; i++) {
961 if (dist < minDist) {
962 insertionIndex = i + 1;
966 insert(begin() + insertionIndex, p);
967 return insertionIndex;
976 double minDist = std::numeric_limits<double>::max();
977 int removalIndex = 0;
978 for (
int i = 0; i < (int)size(); i++) {
980 if (dist < minDist) {
985 erase(begin() + removalIndex);
992 std::vector<double> ret;
993 if (other.size() == 0) {
996 for (const_iterator i = other.begin(); i != other.end() - 1; i++) {
998 copy(atSegment.begin(), atSegment.end(), back_inserter(ret));
1006 std::vector<double> ret;
1011 for (const_iterator i = begin(); i != end() - 1; i++) {
1015 if (
intersects(p1, p2, lp1, lp2, 0., &x, &y, &m)) {
1016 ret.push_back(
Position(x, y).distanceTo2D(p1) + pos);
1071 for (const_reverse_iterator i = rbegin(); i != rend(); i++) {
1081 return Position((beg.
y() - end.
y()) * scale, (end.
x() - beg.
x()) * scale);
1095 for (
int i = 0; i < static_cast<int>(size()); i++) {
1098 const Position& to = (*this)[i + 1];
1100 shape.push_back(from -
sideOffset(from, to, amount));
1102 }
else if (i == static_cast<int>(size()) - 1) {
1103 const Position& from = (*this)[i - 1];
1106 shape.push_back(to -
sideOffset(from, to, amount));
1109 const Position& from = (*this)[i - 1];
1111 const Position& to = (*this)[i + 1];
1114 const double extrapolateDev = fromMe[1].distanceTo2D(to);
1117 shape.push_back(me -
sideOffset(from, to, amount));
1122 shape.push_back(fromMe[1]);
1133 shape.push_back(meNew);
1136 shape.back().set(shape.back().x(), shape.back().y(), me.
z());
1151 if (size() != amount.size()) {
1153 +
") does not match number of points (" +
toString(size()) +
")");
1156 for (
int i = 0; i < static_cast<int>(size()); i++) {
1159 const Position& to = (*this)[i + 1];
1161 shape.push_back(from -
sideOffset(from, to, amount[i]));
1163 }
else if (i == static_cast<int>(size()) - 1) {
1164 const Position& from = (*this)[i - 1];
1167 shape.push_back(to -
sideOffset(from, to, amount[i]));
1170 const Position& from = (*this)[i - 1];
1172 const Position& to = (*this)[i + 1];
1175 const double extrapolateDev = fromMe[1].distanceTo2D(to);
1178 shape.push_back(me -
sideOffset(from, to, amount[i]));
1183 shape.push_back(fromMe[1]);
1194 shape.push_back(meNew);
1197 shape.back().set(shape.back().x(), shape.back().y(), me.
z());
1205 if ((pos + 1) < (
int)size()) {
1206 return (*
this)[pos].angleTo2D((*
this)[pos + 1]);
1215 if ((size() != 0) && ((*
this)[0] != back())) {
1216 push_back((*
this)[0]);
1223 std::vector<double> ret;
1225 for (i = begin(); i != end(); i++) {
1226 const double dist = s.
distance2D(*i, perpendicular);
1228 ret.push_back(dist);
1231 for (i = s.begin(); i != s.end(); i++) {
1232 const double dist =
distance2D(*i, perpendicular);
1234 ret.push_back(dist);
1244 return std::numeric_limits<double>::max();
1245 }
else if (size() == 1) {
1246 return front().distanceTo(p);
1275 if (at == begin()) {
1277 }
else if (at == end()) {
1289 return (size() >= 2) && ((*this)[0] == back());
1296 for (
auto i = begin(); i != end(); i++) {
1309 iterator last = begin();
1310 for (iterator i = begin() + 1; i != end() && (!assertLength || size() > 2);) {
1311 if (last->almostSame(*i, minDist)) {
1324 return static_cast<vp>(*this) ==
static_cast<vp>(v2);
1330 return static_cast<vp>(*this) !=
static_cast<vp>(v2);
1336 WRITE_ERROR(
"Trying to substract PositionVectors of different lengths.");
1340 auto i2 = v2.begin();
1341 while (i1 != end()) {
1350 WRITE_ERROR(
"Trying to substract PositionVectors of different lengths.");
1354 auto i2 = v2.begin();
1355 while (i1 != end()) {
1366 for (const_iterator i = begin(); i != end() - 1; i++) {
1367 if ((*i).z() != (*(i + 1)).z()) {
1377 const double eps = std::numeric_limits<double>::epsilon();
1378 const double denominator = (p22.
y() - p21.
y()) * (p12.
x() - p11.
x()) - (p22.
x() - p21.
x()) * (p12.
y() - p11.
y());
1379 const double numera = (p22.
x() - p21.
x()) * (p11.
y() - p21.
y()) - (p22.
y() - p21.
y()) * (p11.
x() - p21.
x());
1380 const double numerb = (p12.
x() - p11.
x()) * (p11.
y() - p21.
y()) - (p12.
y() - p11.
y()) * (p11.
x() - p21.
x());
1382 if (fabs(numera) < eps && fabs(numerb) < eps && fabs(denominator) < eps) {
1388 if (p11.
x() != p12.
x()) {
1389 a1 = p11.
x() < p12.
x() ? p11.
x() : p12.
x();
1390 a2 = p11.
x() < p12.
x() ? p12.
x() : p11.
x();
1391 a3 = p21.
x() < p22.
x() ? p21.
x() : p22.
x();
1392 a4 = p21.
x() < p22.
x() ? p22.
x() : p21.
x();
1394 a1 = p11.
y() < p12.
y() ? p11.
y() : p12.
y();
1395 a2 = p11.
y() < p12.
y() ? p12.
y() : p11.
y();
1396 a3 = p21.
y() < p22.
y() ? p21.
y() : p22.
y();
1397 a4 = p21.
y() < p22.
y() ? p22.
y() : p21.
y();
1399 if (a1 <= a3 && a3 <= a2) {
1406 if (a3 <= a1 && a1 <= a4) {
1415 if (p11.
x() != p12.
x()) {
1416 *mu = (a - p11.
x()) / (p12.
x() - p11.
x());
1418 *y = p11.
y() + (*mu) * (p12.
y() - p11.
y());
1422 if (p12.
y() == p11.
y()) {
1425 *mu = (a - p11.
y()) / (p12.
y() - p11.
y());
1434 if (fabs(denominator) < eps) {
1438 double mua = numera / denominator;
1440 if (fabs(p12.
x() - p22.
x()) < eps && fabs(p12.
y() - p22.
y()) < eps) {
1443 const double offseta = withinDist / p11.
distanceTo2D(p12);
1444 const double offsetb = withinDist / p21.
distanceTo2D(p22);
1445 const double mub = numerb / denominator;
1446 if (mua < -offseta || mua > 1 + offseta || mub < -offsetb || mub > 1 + offsetb) {
1451 *x = p11.
x() + mua * (p12.
x() - p11.
x());
1452 *y = p11.
y() + mua * (p12.
y() - p11.
y());
1461 const double s = sin(angle);
1462 const double c = cos(angle);
1463 for (
int i = 0; i < (int)size(); i++) {
1464 const double x = (*this)[i].x();
1465 const double y = (*this)[i].y();
1466 const double z = (*this)[i].z();
1467 const double xnew = x * c - y * s;
1468 const double ynew = x * s + y * c;
1469 (*this)[i].set(xnew, ynew, z);
1477 bool changed =
true;
1478 while (changed && result.size() > 3) {
1480 for (
int i = 0; i < (int)result.size(); i++) {
1482 const Position& p2 = result[(i + 2) % result.size()];
1483 const int middleIndex = (i + 1) % result.size();
1484 const Position& p0 = result[middleIndex];
1486 const double triangleArea2 = fabs((p2.
y() - p1.
y()) * p0.
x() - (p2.
x() - p1.
x()) * p0.
y() + p2.
x() * p1.
y() - p2.
y() * p1.
x());
1490 result.erase(result.begin() + middleIndex);
1511 result.push_back(base);
1513 result.push_back(tmp[closestIndex]);
1514 }
else if (before) {
1516 if (closestIndex > 0) {
1517 result.push_back(tmp[closestIndex - 1]);
1519 result.push_back(tmp[1]);
1523 if (closestIndex < (
int)size() - 1) {
1524 result.push_back(tmp[closestIndex + 1]);
1526 result.push_back(tmp[-1]);
1531 result.
add(base * -1);
1544 const double z0 = (*this)[0].z();
1546 const double dz = (*this)[1].z() - z0;
1548 if (size() > 2 && dz != 0) {
1558 const double dz2 = result[iLast].z() - z0;
1560 for (
int i = 1; i < iLast; ++i) {
1561 seen += result[i].distanceTo2D(result[i - 1]);
1562 result[i].set(result[i].x(), result[i].y(), z0 + dz2 * seen / dist2);
1576 result[0].setz(zStart);
1577 result[-1].setz(zEnd);
1578 const double dz = zEnd - zStart;
1581 for (
int i = 1; i < (int)size() - 1; ++i) {
1582 seen += result[i].distanceTo2D(result[i - 1]);
1583 result[i].setz(zStart + dz * seen / length);
1592 if (maxLength == 0) {
1599 maxLength = length / ceil(length / maxLength);
1600 for (
double pos = 0; pos <=
length; pos += maxLength) {
1609 if (index < 0 || index >= (
int)size()) {
1613 for (
int i = 1; i <= index; ++i) {
1614 seen += (*this)[i].distanceTo2D((*
this)[i - 1]);
1623 for (
int i = 1; i < (int)size(); ++i) {
1624 const Position& p1 = (*this)[i - 1];
1626 const double distZ = fabs(p1.
z() - p2.
z());
1629 maxJump =
MAX2(maxJump, distZ);
1631 result =
MAX2(result, distZ / dist2D);
1641 assert(size() < 33);
1642 static const double fac[33] = {
1643 1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0, 362880.0, 3628800.0, 39916800.0, 479001600.0,
1644 6227020800.0, 87178291200.0, 1307674368000.0, 20922789888000.0, 355687428096000.0, 6402373705728000.0,
1645 121645100408832000.0, 2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0,
1646 25852016738884976640000.0, 620448401733239439360000.0, 15511210043330985984000000.0,
1647 403291461126605635584000000.0, 10888869450418352160768000000.0, 304888344611713860501504000000.0,
1648 8841761993739701954543616000000.0, 265252859812191058636308480000000.0,
1649 8222838654177922817725562880000000.0, 263130836933693530167218012160000000.0
1652 const int npts = (int)size();
1654 const double step = (double) 1.0 / (numPoints - 1);
1657 for (
int i1 = 0; i1 < numPoints; i1++) {
1658 if ((1.0 - t) < 5e-6) {
1661 double x = 0., y = 0., z = 0.;
1662 for (
int i = 0; i < npts; i++) {
1663 const double ti = (i == 0) ? 1.0 : pow(t, i);
1664 const double tni = (npts == i + 1) ? 1.0 : pow(1 - t, npts - i - 1);
1665 const double basis = fac[npts - 1] / (fac[i] * fac[npts - 1 - i]) * ti * tni;
1666 x += basis * at(i).
x();
1667 y += basis * at(i).y();
1668 z += basis * at(i).z();
1673 ret.push_back(current);
PositionVector operator+(const PositionVector &v2) const
adds two vectors (requires vectors of the same length)
bool around(const Position &p, double offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point...
static const PositionVector EMPTY
empty Vector
clase for increasing Sorter
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
virtual bool partialWithin(const AbstractPoly &poly, double offset=0) const =0
Returns whether the AbstractPoly is partially within the given polygon.
int operator()(const Position &p1, const Position &p2) const
comparing operation
bool almostSame(const Position &p2, double maxDiv=POSITION_EPS) const
check if two position is almost the sme as other
double length2D() const
Returns the length.
void append(const PositionVector &v, double sameThreshold=2.0)
PositionVector getOrthogonal(const Position &p, double extend, bool before, double length=1.0) const
return orthogonal through p (extending this vector if necessary)
double z() const
Returns the z-position.
void sortAsPolyCWByAngle()
short as polygon CV by angle
double 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) ...
void add(const Position &pos)
Adds the given position to this one.
double getMaxGrade(double &maxJump) const
int indexOfClosest(const Position &p) const
index of the closest position to p
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
friend std::ostream & operator<<(std::ostream &os, const PositionVector &geom)
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
PositionVector resample(double maxLength) const
resample shape with the given number of points (equal spacing)
Position intersectionPosition2D(const Position &p1, const Position &p2, const double withinDist=0.) const
Returns the position of the intersection.
std::pair< PositionVector, PositionVector > splitAt(double where, bool use2D=false) const
Returns the two lists made when this list vector is splitted at the given point.
double y() const
Returns the y-position.
double x() const
Returns the x-position.
virtual bool crosses(const Position &p1, const Position &p2) const =0
Returns whether the AbstractPoly crosses the given line.
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
Position getCentroid() const
Returns the centroid (closes the polygon if unclosed)
bool partialWithin(const AbstractPoly &poly, double offset=0) const
Returns the information whether this polygon lies partially within the given polygon.
PositionVector reverse() const
reverse position vector
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
PositionVector interpolateZ(double zStart, double zEnd) const
returned vector that varies z smoothly over its length
void insert_noDoublePos(const std::vector< Position >::iterator &at, const Position &p)
insert in front a non double position
std::vector< double > distances(const PositionVector &s, bool perpendicular=false) const
distances of all my points to s and all of s points to myself
bool hasElevation() const
return whether two positions differ in z-coordinate
bool operator!=(const PositionVector &v2) const
comparing operation
A class that stores a 2D geometrical boundary.
#define WRITE_WARNING(msg)
Position getLineCenter() const
get line center
static double legacyDegree(const double angle, const bool positive=false)
double area() const
Returns the area (0 for non-closed)
PositionVector bezier(int numPoints)
return a bezier interpolation
~PositionVector()
Destructor.
void extrapolate2D(const double val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
void push_front_noDoublePos(const Position &p)
insert in front a non double position
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false)
Removes positions if too near.
PositionVector added(const Position &offset) const
static double nearest_offset_on_line_to_point2D(const Position &lineStart, const Position &lineEnd, const Position &p, bool perpendicular=true)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
double nearest_offset_to_point25D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D projected onto the 3D geometry
void scaleAbsolute(double offset)
enlarges/shrinks the polygon by an absolute offset based at the centroid
bool operator==(const PositionVector &v2) const
comparing operation
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position ...
A point in 2D or 3D with translation and scaling methods.
std::vector< Position > vp
vector of position
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
int operator()(const Position &p1, const Position &p2) const
comparing operation for sort
virtual bool around(const Position &p, double offset=0) const =0
Returns whether the AbstractPoly the given coordinate.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
static double 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...
std::vector< double > intersectsAtLengths2D(const PositionVector &other) const
For all intersections between this vector and other, return the 2D-length of the subvector from this ...
const Position & operator[](int index) const
returns the constat position at the given index !!! exceptions?
int insertAtClosest(const Position &p)
inserts p between the two closest positions and returns the insertion index
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns the information whether the given polygon overlaps with this.
as_poly_cw_sorter()
constructor
PositionVector smoothedZFront(double dist=std::numeric_limits< double >::max()) const
returned vector that is smoothed at the front (within dist)
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
PositionVector getSubpartByIndex(int beginIndex, int count) const
get subpart of a position vector using index and a cout
void sortByIncreasingXY()
shory by increasing X-Y Psitions
PositionVector operator-(const PositionVector &v2) const
substracts two vectors (requires vectors of the same length)
PositionVector simplified() const
return the same shape with intermediate colinear points removed
double slopeDegreeAtOffset(double pos) const
Returns the slope at the given length.
PositionVector()
Constructor. Creates an empty position vector.
double isLeft(const Position &P0, const Position &P1, const Position &P2) const
get left
PositionVector getSubpart2D(double beginOffset, double endOffset) const
get subpart of a position vector in two dimensions (Z is ignored)
void rotate2D(double angle)
void extrapolate(const double val, const bool onlyFirst=false, const bool onlyLast=false)
extrapolate position vector
double length() const
Returns the length.
bool isClosed() const
check if PositionVector is closed
static Position sideOffset(const Position &beg, const Position &end, const double amount)
get a side position of position vector using a offset
void scaleRelative(double factor)
enlarges/shrinks the polygon by a factor based at the centroid
bool isNAN() const
check if PositionVector is NAN
double angleAt2D(int pos) const
get angle in certain position of position vector
double offsetAtIndex2D(int index) const
return the offset at the given index
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void push_back_noDoublePos(const Position &p)
insert in back a non double position
const double INVALID_DOUBLE
bool crosses(const Position &p1, const Position &p2) const
Returns whether the AbstractPoly crosses the given line.
double getOverlapWith(const PositionVector &poly, double zThreshold) const
Returns the maximum overlaps between this and the given polygon (when not separated by at least zThre...
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
void add(double xoff, double yoff, double zoff)
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
void closePolygon()
ensures that the last position equals the first
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
increasing_x_y_sorter()
constructor
void sub(double xoff, double yoff, double zoff)
int removeClosest(const Position &p)
removes the point closest to p and return the removal index
Position transformToVectorCoordinates(const Position &p, bool extend=false) const
return position p within the length-wise coordinate system defined by this position vector...
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
static const Position INVALID
used to indicate that a position is valid
void sub(double dx, double dy)
Substracts the given position from this one.