54 std::copy(v.begin(), v.end(), std::back_inserter(*
this));
59 std::copy(beg, end, std::back_inserter(*
this));
84 for (const_iterator i = begin(); i != (end() - 1); i++) {
90 (i + 1)->y() - p.
y());
95 (end() - 1)->x() - p.
x(),
96 (end() - 1)->y() - p.
y());
99 begin()->y() - p.
y());
102 return (!(fabs(angle) <
M_PI));
116 for (const_iterator i = begin(); i != end() - 1; i++) {
117 if (poly.
crosses(*i, *(i + 1))) {
121 if (size() > 2 && poly.
crosses(back(), front())) {
132 if ((size() == 0) || (poly.size() == 0)) {
136 for (const_iterator i = begin(); i != end() - 1; i++) {
139 if (fabs(closest.
z() - (*i).z()) < zThreshold) {
145 for (const_iterator i = poly.begin(); i != poly.end() - 1; i++) {
148 if (fabs(closest.
z() - (*i).z()) < zThreshold) {
162 for (const_iterator i = begin(); i != end() - 1; i++) {
176 for (const_iterator i = begin(); i != end() - 1; i++) {
187 for (const_iterator i = begin(); i != end() - 1; i++) {
189 if (
intersects(*i, *(i + 1), p1, p2, withinDist, &x, &y, &m)) {
199 for (const_iterator i = begin(); i != end() - 1; i++) {
217 if (index >= 0 && index < (
int)size()) {
219 }
else if (index < 0 && -index <= (
int)size()) {
220 return at((
int)size() + index);
222 throw ProcessError(
"Index out of range in bracket operator of PositionVector");
236 if (index >= 0 && index < (
int)size()) {
238 }
else if (index < 0 && -index <= (
int)size()) {
239 return at((
int)size() + index);
241 throw ProcessError(
"Index out of range in bracket operator of PositionVector");
254 const_iterator i = begin();
255 double seenLength = 0;
257 const double nextLength = (*i).distanceTo(*(i + 1));
258 if (seenLength + nextLength > pos) {
261 seenLength += nextLength;
262 }
while (++i != end() - 1);
263 if (lateralOffset == 0 || size() < 2) {
266 return positionAtOffset(*(end() - 2), *(end() - 1), (*(end() - 2)).distanceTo(*(end() - 1)), lateralOffset);
279 const_iterator i = begin();
280 double seenLength = 0;
282 const double nextLength = (*i).distanceTo2D(*(i + 1));
283 if (seenLength + nextLength > pos) {
286 seenLength += nextLength;
287 }
while (++i != end() - 1);
294 if ((size() == 0) || (size() == 1)) {
300 const_iterator i = begin();
301 double seenLength = 0;
306 if (seenLength + nextLength > pos) {
309 seenLength += nextLength;
310 }
while (++i != end() - 1);
328 const_iterator i = begin();
329 double seenLength = 0;
334 if (seenLength + nextLength > pos) {
337 seenLength += nextLength;
338 }
while (++i != end() - 1);
348 if (pos < 0. || dist < pos) {
351 if (lateralOffset != 0) {
359 return p1 + (p2 - p1) * (pos / dist) + offset;
364 return p1 + (p2 - p1) * (pos / dist);
371 if (pos < 0 || dist < pos) {
374 if (lateralOffset != 0) {
379 return p1 + (p2 - p1) * (pos / dist) + offset;
384 return p1 + (p2 - p1) * (pos / dist);
408 return Position(x / (
double) size(), y / (
double) size(), z / (
double)size());
416 }
else if (size() == 1) {
418 }
else if (size() == 2) {
419 return ((*
this)[0] + (*
this)[1]) * 0.5;
423 tmp.push_back(tmp[0]);
429 const int endIndex = (int)tmp.size() - 1;
433 if (tmp.
area() != 0) {
435 for (
int i = 0; i < endIndex; i++) {
436 const double z = tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
438 x += (tmp[i].x() + tmp[i + 1].x()) * z;
439 y += (tmp[i].y() + tmp[i + 1].y()) * z;
442 result =
Position(x / div, y / div);
446 double lengthSum = 0;
447 for (
int i = 0; i < endIndex; i++) {
448 double length = tmp[i].distanceTo(tmp[i + 1]);
449 x += (tmp[i].x() + tmp[i + 1].x()) *
length / 2;
450 y += (tmp[i].y() + tmp[i + 1].y()) *
length / 2;
453 if (lengthSum == 0) {
457 result =
Position(x / lengthSum, y / lengthSum) + offset;
459 return result + offset;
466 for (
int i = 0; i < static_cast<int>(size()); i++) {
467 (*this)[i] = centroid + (((*this)[i] - centroid) * factor);
475 for (
int i = 0; i < static_cast<int>(size()); i++) {
476 (*this)[i] = centroid + (((*this)[i] - centroid) + offset);
497 for (const_iterator i = begin(); i != end() - 1; i++) {
498 len += (*i).distanceTo(*(i + 1));
510 for (const_iterator i = begin(); i != end() - 1; i++) {
511 len += (*i).distanceTo2D(*(i + 1));
525 tmp.push_back(tmp[0]);
527 const int endIndex = (int)tmp.size() - 1;
529 for (
int i = 0; i < endIndex; i++) {
530 area += tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
544 for (const_iterator i = begin(); i != end(); i++) {
545 if (poly.
around(*i, offset)) {
559 std::pair<PositionVector, PositionVector>
565 if (where < 0 || where > len) {
568 if (where <= POSITION_EPS || where >= len - POSITION_EPS) {
572 first.push_back((*
this)[0]);
574 const_iterator it = begin() + 1;
575 double next = use2D ? first.back().distanceTo2D(*it) : first.back().distanceTo(*it);
577 while (where >= seen + next + POSITION_EPS) {
579 first.push_back(*it);
581 next = use2D ? first.back().distanceTo2D(*it) : first.back().distanceTo(*it);
583 if (fabs(where - (seen + next)) > POSITION_EPS || it == end() - 1) {
592 first.push_back(*it);
595 for (; it != end(); it++) {
596 second.push_back(*it);
598 assert(first.size() >= 2);
599 assert(second.size() >= 2);
600 assert(first.back() == second.front());
602 return std::pair<PositionVector, PositionVector>(first, second);
608 for (PositionVector::const_iterator i = geom.begin(); i != geom.end(); i++) {
609 if (i != geom.begin()) {
626 for (
int i = 0; i < (int)size(); i++) {
627 (*this)[i].add(xoff, yoff, zoff);
634 sub(offset.
x(), offset.
y(), offset.
z());
640 for (
int i = 0; i < (int)size(); i++) {
641 (*this)[i].add(-xoff, -yoff, -zoff);
648 add(offset.
x(), offset.
y(), offset.
z());
655 for (
auto i1 = begin(); i1 != end(); ++i1) {
656 pv.push_back(*i1 + offset);
664 for (
int i = 0; i < (int)size(); i++) {
665 (*this)[i].mul(1, -1);
675 return atan2(p1.
x(), p1.
y()) < atan2(p2.
x(), p2.
y());
690 if (p1.
x() != p2.
x()) {
691 return p1.
x() < p2.
x();
693 return p1.
y() < p2.
y();
699 return (P1.
x() - P0.
x()) * (P2.
y() - P0.
y()) - (P2.
x() - P0.
x()) * (P1.
y() - P0.
y());
705 if ((size() > 0) && (v.size() > 0) && (back().distanceTo(v[0]) < sameThreshold)) {
706 copy(v.begin() + 1, v.end(), back_inserter(*
this));
708 copy(v.begin(), v.end(), back_inserter(*
this));
717 if (beginOffset > POSITION_EPS) {
721 if (endOffset <
length() - POSITION_EPS) {
724 ret.push_back(begPos);
727 const_iterator i = begin();
729 while ((i + 1) != end()
731 seen + (*i).distanceTo(*(i + 1)) < beginOffset) {
732 seen += (*i).distanceTo(*(i + 1));
736 while ((i + 1) != end()
738 seen + (*i).distanceTo(*(i + 1)) < endOffset) {
741 seen += (*i).distanceTo(*(i + 1));
746 if (ret.size() == 1) {
747 ret.push_back(endPos);
760 if (beginOffset > POSITION_EPS) {
764 if (endOffset <
length2D() - POSITION_EPS) {
767 ret.push_back(begPos);
770 const_iterator i = begin();
772 while ((i + 1) != end()
774 seen + (*i).distanceTo2D(*(i + 1)) < beginOffset) {
775 seen += (*i).distanceTo2D(*(i + 1));
779 while ((i + 1) != end()
781 seen + (*i).distanceTo2D(*(i + 1)) < endOffset) {
784 seen += (*i).distanceTo2D(*(i + 1));
789 if (ret.size() == 1) {
790 ret.push_back(endPos);
801 if (beginIndex < 0) {
802 beginIndex += (int)size();
805 assert(beginIndex < (
int)size());
806 assert(beginIndex + count <= (
int)size());
808 for (
int i = beginIndex; i < beginIndex + count; ++i) {
809 result.push_back((*
this)[i]);
820 return front().angleTo2D(back());
829 double minDist = std::numeric_limits<double>::max();
832 for (const_iterator i = begin(); i != end() - 1; i++) {
836 if (dist < minDist) {
837 nearestPos = pos + seen;
843 if (cornerDist < minDist) {
848 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
850 minDist = cornerDist;
854 seen += (*i).distanceTo2D(*(i + 1));
865 double minDist = std::numeric_limits<double>::max();
868 for (const_iterator i = begin(); i != end() - 1; i++) {
872 if (dist < minDist) {
873 const double pos25D = pos * (*i).distanceTo(*(i + 1)) / (*i).distanceTo2D(*(i + 1));
874 nearestPos = pos25D + seen;
880 if (cornerDist < minDist) {
885 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
887 minDist = cornerDist;
891 seen += (*i).distanceTo(*(i + 1));
909 double minDist = std::numeric_limits<double>::max();
910 double nearestPos = -1;
913 for (const_iterator i = begin(); i != end() - 1; i++) {
917 if (dist < minDist) {
918 nearestPos = pos + seen;
920 sign =
isLeft(*i, *(i + 1), p) >= 0 ? -1 : 1;
925 if (cornerDist < minDist) {
930 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
932 minDist = cornerDist;
933 sign =
isLeft(*(i - 1), *i, p) >= 0 ? -1 : 1;
937 seen += (*i).distanceTo2D(*(i + 1));
939 if (nearestPos != -1) {
940 return Position(nearestPos, sign * minDist);
952 double minDist = std::numeric_limits<double>::max();
955 for (
int i = 0; i < (int)size(); i++) {
957 if (dist < minDist) {
971 double minDist = std::numeric_limits<double>::max();
972 int insertionIndex = 1;
973 for (
int i = 0; i < (int)size() - 1; i++) {
977 if (dist < minDist) {
978 insertionIndex = i + 1;
985 const double previousZ = (begin() + (insertionIndex - 1))->z();
986 const double nextZ = (begin() + insertionIndex)->z();
988 insert(begin() + insertionIndex,
Position(p.
x(), p.
y(), ((previousZ + nextZ) / 2.0)));
990 insert(begin() + insertionIndex, p);
992 return insertionIndex;
1001 double minDist = std::numeric_limits<double>::max();
1002 int removalIndex = 0;
1003 for (
int i = 0; i < (int)size(); i++) {
1005 if (dist < minDist) {
1010 erase(begin() + removalIndex);
1011 return removalIndex;
1017 std::vector<double> ret;
1018 if (other.size() == 0) {
1021 for (const_iterator i = other.begin(); i != other.end() - 1; i++) {
1023 copy(atSegment.begin(), atSegment.end(), back_inserter(ret));
1031 std::vector<double> ret;
1036 for (const_iterator i = begin(); i != end() - 1; i++) {
1040 if (
intersects(p1, p2, lp1, lp2, 0., &x, &y, &m)) {
1096 for (const_reverse_iterator i = rbegin(); i != rend(); i++) {
1106 return Position((beg.
y() - end.
y()) * scale, (end.
x() - beg.
x()) * scale);
1120 for (
int i = 0; i < static_cast<int>(size()); i++) {
1123 const Position& to = (*this)[i + 1];
1125 shape.push_back(from -
sideOffset(from, to, amount));
1127 }
else if (i ==
static_cast<int>(size()) - 1) {
1128 const Position& from = (*this)[i - 1];
1131 shape.push_back(to -
sideOffset(from, to, amount));
1134 const Position& from = (*this)[i - 1];
1136 const Position& to = (*this)[i + 1];
1139 const double extrapolateDev = fromMe[1].distanceTo2D(to);
1140 if (fabs(extrapolateDev) < POSITION_EPS) {
1142 shape.push_back(me -
sideOffset(from, to, amount));
1143 }
else if (fabs(extrapolateDev - 2 * me.
distanceTo2D(to)) < POSITION_EPS) {
1147 shape.push_back(fromMe[1]);
1158 shape.push_back(meNew);
1161 shape.back().set(shape.back().x(), shape.back().y(), me.
z());
1176 if (size() != amount.size()) {
1178 +
") does not match number of points (" +
toString(size()) +
")");
1181 for (
int i = 0; i < static_cast<int>(size()); i++) {
1184 const Position& to = (*this)[i + 1];
1186 shape.push_back(from -
sideOffset(from, to, amount[i]));
1188 }
else if (i ==
static_cast<int>(size()) - 1) {
1189 const Position& from = (*this)[i - 1];
1192 shape.push_back(to -
sideOffset(from, to, amount[i]));
1195 const Position& from = (*this)[i - 1];
1197 const Position& to = (*this)[i + 1];
1200 const double extrapolateDev = fromMe[1].distanceTo2D(to);
1201 if (fabs(extrapolateDev) < POSITION_EPS) {
1203 shape.push_back(me -
sideOffset(from, to, amount[i]));
1204 }
else if (fabs(extrapolateDev - 2 * me.
distanceTo2D(to)) < POSITION_EPS) {
1208 shape.push_back(fromMe[1]);
1219 shape.push_back(meNew);
1222 shape.back().set(shape.back().x(), shape.back().y(), me.
z());
1230 if ((pos + 1) < (
int)size()) {
1231 return (*
this)[pos].angleTo2D((*
this)[pos + 1]);
1240 if ((size() != 0) && ((*
this)[0] != back())) {
1241 push_back((*
this)[0]);
1248 std::vector<double> ret;
1250 for (i = begin(); i != end(); i++) {
1251 const double dist = s.
distance2D(*i, perpendicular);
1253 ret.push_back(dist);
1256 for (i = s.begin(); i != s.end(); i++) {
1257 const double dist =
distance2D(*i, perpendicular);
1259 ret.push_back(dist);
1269 return std::numeric_limits<double>::max();
1270 }
else if (size() == 1) {
1271 return front().distanceTo(p);
1312 if ((size() == 0) || !p.
almostSame(front())) {
1320 if (at == begin()) {
1322 }
else if (at == end()) {
1334 return (size() >= 2) && ((*this)[0] == back());
1341 for (
auto i = begin(); i != end(); i++) {
1354 iterator last = begin();
1355 for (iterator i = begin() + 1; i != end() && (!assertLength || size() > 2);) {
1356 if (last->almostSame(*i, minDist)) {
1357 if (i + 1 == end()) {
1375 return static_cast<vp>(*this) ==
static_cast<vp>(v2);
1381 return static_cast<vp>(*this) !=
static_cast<vp>(v2);
1387 WRITE_ERROR(
"Trying to substract PositionVectors of different lengths.");
1391 auto i2 = v2.begin();
1392 while (i1 != end()) {
1401 WRITE_ERROR(
"Trying to substract PositionVectors of different lengths.");
1405 auto i2 = v2.begin();
1406 while (i1 != end()) {
1417 for (const_iterator i = begin(); i != end() - 1; i++) {
1418 if ((*i).z() != (*(i + 1)).z()) {
1428 const double eps = std::numeric_limits<double>::epsilon();
1429 const double denominator = (p22.
y() - p21.
y()) * (p12.
x() - p11.
x()) - (p22.
x() - p21.
x()) * (p12.
y() - p11.
y());
1430 const double numera = (p22.
x() - p21.
x()) * (p11.
y() - p21.
y()) - (p22.
y() - p21.
y()) * (p11.
x() - p21.
x());
1431 const double numerb = (p12.
x() - p11.
x()) * (p11.
y() - p21.
y()) - (p12.
y() - p11.
y()) * (p11.
x() - p21.
x());
1433 if (fabs(numera) < eps && fabs(numerb) < eps && fabs(denominator) < eps) {
1439 if (p11.
x() != p12.
x()) {
1440 a1 = p11.
x() < p12.
x() ? p11.
x() : p12.
x();
1441 a2 = p11.
x() < p12.
x() ? p12.
x() : p11.
x();
1442 a3 = p21.
x() < p22.
x() ? p21.
x() : p22.
x();
1443 a4 = p21.
x() < p22.
x() ? p22.
x() : p21.
x();
1445 a1 = p11.
y() < p12.
y() ? p11.
y() : p12.
y();
1446 a2 = p11.
y() < p12.
y() ? p12.
y() : p11.
y();
1447 a3 = p21.
y() < p22.
y() ? p21.
y() : p22.
y();
1448 a4 = p21.
y() < p22.
y() ? p22.
y() : p21.
y();
1450 if (a1 <= a3 && a3 <= a2) {
1457 if (a3 <= a1 && a1 <= a4) {
1466 if (p11.
x() != p12.
x()) {
1467 *mu = (a - p11.
x()) / (p12.
x() - p11.
x());
1469 *y = p11.
y() + (*mu) * (p12.
y() - p11.
y());
1473 if (p12.
y() == p11.
y()) {
1476 *mu = (a - p11.
y()) / (p12.
y() - p11.
y());
1485 if (fabs(denominator) < eps) {
1489 double mua = numera / denominator;
1491 if (fabs(p12.
x() - p22.
x()) < eps && fabs(p12.
y() - p22.
y()) < eps) {
1494 const double offseta = withinDist / p11.
distanceTo2D(p12);
1495 const double offsetb = withinDist / p21.
distanceTo2D(p22);
1496 const double mub = numerb / denominator;
1497 if (mua < -offseta || mua > 1 + offseta || mub < -offsetb || mub > 1 + offsetb) {
1502 *x = p11.
x() + mua * (p12.
x() - p11.
x());
1503 *y = p11.
y() + mua * (p12.
y() - p11.
y());
1512 const double s = sin(angle);
1513 const double c = cos(angle);
1514 for (
int i = 0; i < (int)size(); i++) {
1515 const double x = (*this)[i].x();
1516 const double y = (*this)[i].y();
1517 const double z = (*this)[i].z();
1518 const double xnew = x * c - y * s;
1519 const double ynew = x * s + y * c;
1520 (*this)[i].set(xnew, ynew, z);
1528 bool changed =
true;
1529 while (changed && result.size() > 3) {
1531 for (
int i = 0; i < (int)result.size(); i++) {
1533 const Position& p2 = result[(i + 2) % result.size()];
1534 const int middleIndex = (i + 1) % result.size();
1535 const Position& p0 = result[middleIndex];
1537 const double triangleArea2 = fabs((p2.
y() - p1.
y()) * p0.
x() - (p2.
x() - p1.
x()) * p0.
y() + p2.
x() * p1.
y() - p2.
y() * p1.
x());
1539 if (distIK > NUMERICAL_EPS && triangleArea2 / distIK < NUMERICAL_EPS) {
1541 result.erase(result.begin() + middleIndex);
1563 result.push_back(base);
1564 if (fabs(baseOffset - closestOffset) > NUMERICAL_EPS) {
1565 result.push_back(tmp[closestIndex]);
1566 if ((closestOffset < baseOffset) != before) {
1569 }
else if (before) {
1571 if (closestIndex > 0) {
1572 result.push_back(tmp[closestIndex - 1]);
1574 result.push_back(tmp[1]);
1579 if (closestIndex < (
int)size() - 1) {
1580 result.push_back(tmp[closestIndex + 1]);
1582 result.push_back(tmp[-1]);
1588 result.
add(base * -1);
1601 const double z0 = (*this)[0].z();
1603 const double dz = (*this)[1].z() - z0;
1605 if (size() > 2 && dz != 0) {
1611 if (pDist.
distanceTo2D((*
this)[iLast]) > POSITION_EPS * 20) {
1615 const double dz2 = result[iLast].z() - z0;
1617 for (
int i = 1; i < iLast; ++i) {
1618 seen += result[i].distanceTo2D(result[i - 1]);
1619 result[i].set(result[i].x(), result[i].y(), z0 + dz2 * seen / dist2);
1633 result[0].setz(zStart);
1634 result[-1].setz(zEnd);
1635 const double dz = zEnd - zStart;
1638 for (
int i = 1; i < (int)size() - 1; ++i) {
1639 seen += result[i].distanceTo2D(result[i - 1]);
1640 result[i].setz(zStart + dz * seen /
length);
1649 if (maxLength == 0) {
1653 if (
length < POSITION_EPS) {
1657 for (
double pos = 0; pos <=
length; pos += maxLength) {
1661 if (adjustEnd && !result.empty() && (result.back() != back())) {
1663 result.push_back(back());
1671 if (index < 0 || index >= (
int)size()) {
1675 for (
int i = 1; i <= index; ++i) {
1676 seen += (*this)[i].distanceTo2D((*
this)[i - 1]);
1685 for (
int i = 1; i < (int)size(); ++i) {
1686 const Position& p1 = (*this)[i - 1];
1688 const double distZ = fabs(p1.
z() - p2.
z());
1691 maxJump =
MAX2(maxJump, distZ);
1693 result =
MAX2(result, distZ / dist2D);
1703 assert(size() < 33);
1704 static const double fac[33] = {
1705 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,
1706 6227020800.0, 87178291200.0, 1307674368000.0, 20922789888000.0, 355687428096000.0, 6402373705728000.0,
1707 121645100408832000.0, 2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0,
1708 25852016738884976640000.0, 620448401733239439360000.0, 15511210043330985984000000.0,
1709 403291461126605635584000000.0, 10888869450418352160768000000.0, 304888344611713860501504000000.0,
1710 8841761993739701954543616000000.0, 265252859812191058636308480000000.0,
1711 8222838654177922817725562880000000.0, 263130836933693530167218012160000000.0
1714 const int npts = (int)size();
1716 const double step = (double) 1.0 / (numPoints - 1);
1719 for (
int i1 = 0; i1 < numPoints; i1++) {
1720 if ((1.0 - t) < 5e-6) {
1723 double x = 0., y = 0., z = 0.;
1724 for (
int i = 0; i < npts; i++) {
1725 const double ti = (i == 0) ? 1.0 : pow(t, i);
1726 const double tni = (npts == i + 1) ? 1.0 : pow(1 - t, npts - i - 1);
1727 const double basis = fac[npts - 1] / (fac[i] * fac[npts - 1 - i]) * ti * tni;
1728 x += basis * at(i).
x();
1729 y += basis * at(i).y();
1730 z += basis * at(i).z();
1735 ret.push_back(current);
#define WRITE_WARNING(msg)
std::ostream & operator<<(std::ostream &os, const PositionVector &geom)
const double INVALID_DOUBLE
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
virtual bool partialWithin(const AbstractPoly &poly, double offset=0) const =0
Returns whether the AbstractPoly is partially within the given polygon.
virtual bool crosses(const Position &p1, const Position &p2) const =0
Returns whether the AbstractPoly crosses the given line.
virtual bool around(const Position &p, double offset=0) const =0
Returns whether the AbstractPoly the given coordinate.
A class that stores a 2D geometrical boundary.
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
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,...
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
static double nearest_offset_on_line_to_point2D(const Position &lineStart, const Position &lineEnd, const Position &p, bool perpendicular=true)
static double legacyDegree(const double angle, const bool positive=false)
A point in 2D or 3D with translation and scaling methods.
static const Position INVALID
used to indicate that a position is valid
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
void sub(double dx, double dy)
Substracts the given position from this one.
double x() const
Returns the x-position.
void add(const Position &pos)
Adds the given position to this one.
double z() const
Returns the z-position.
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position
bool almostSame(const Position &p2, double maxDiv=POSITION_EPS) const
check if two position is almost the sme as other
double y() const
Returns the y-position.
int operator()(const Position &p1, const Position &p2) const
comparing operation for sort
as_poly_cw_sorter()
constructor
clase for increasing Sorter
increasing_x_y_sorter()
constructor
int operator()(const Position &p1, const Position &p2) const
comparing operation
PositionVector operator-(const PositionVector &v2) const
substracts two vectors (requires vectors of the same length)
void scaleAbsolute(double offset)
enlarges/shrinks the polygon by an absolute offset based at the centroid
double length2D() const
Returns the length.
void append(const PositionVector &v, double sameThreshold=2.0)
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns the information whether the given polygon overlaps with this.
PositionVector added(const Position &offset) const
double isLeft(const Position &P0, const Position &P1, const Position &P2) const
get left
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position
double length() const
Returns the length.
void sortAsPolyCWByAngle()
sort as polygon CW by angle
PositionVector simplified() const
return the same shape with intermediate colinear points removed
void rotate2D(double angle)
PositionVector()
Constructor. Creates an empty position vector.
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
Position intersectionPosition2D(const Position &p1, const Position &p2, const double withinDist=0.) const
Returns the position of the intersection.
const Position & operator[](int index) const
returns the constat position at the given index @ToDo !!! exceptions?
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
std::vector< Position > vp
vector of position
void push_front_noDoublePos(const Position &p)
insert in front a non double position
bool operator!=(const PositionVector &v2) const
comparing operation
PositionVector resample(double maxLength, const bool adjustEnd) const
resample shape (i.e. transform to segments, equal spacing)
void sortByIncreasingXY()
sort by increasing X-Y Positions
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
bool isNAN() const
check if PositionVector is NAN
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void add(double xoff, double yoff, double zoff)
void closePolygon()
ensures that the last position equals the first
static Position sideOffset(const Position &beg, const Position &end, const double amount)
get a side position of position vector using a offset
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 ...
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)
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
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
PositionVector getOrthogonal(const Position &p, double extend, bool before, double length=1.0, double deg=90) const
return orthogonal through p (extending this vector if necessary)
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.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
bool crosses(const Position &p1, const Position &p2) const
Returns whether the AbstractPoly crosses the given line.
PositionVector getSubpart2D(double beginOffset, double endOffset) const
get subpart of a position vector in two dimensions (Z is ignored)
PositionVector interpolateZ(double zStart, double zEnd) const
returned vector that varies z smoothly over its length
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
double offsetAtIndex2D(int index) const
return the offset at the given index
PositionVector smoothedZFront(double dist=std::numeric_limits< double >::max()) const
returned vector that is smoothed at the front (within dist)
double angleAt2D(int pos) const
get angle in certain position of position vector
void insert_noDoublePos(const std::vector< Position >::iterator &at, const Position &p)
insert in front a non double position
double slopeDegreeAtOffset(double pos) const
Returns the slope at the given length.
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false)
Removes positions if too near.
bool hasElevation() const
return whether two positions differ in z-coordinate
static const PositionVector EMPTY
empty Vector
void extrapolate(const double val, const bool onlyFirst=false, const bool onlyLast=false)
extrapolate position vector
PositionVector bezier(int numPoints)
return a bezier interpolation
void sub(double xoff, double yoff, double zoff)
Position getLineCenter() const
get line center
Position getCentroid() const
Returns the centroid (closes the polygon if unclosed)
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...
PositionVector operator+(const PositionVector &v2) const
adds two vectors (requires vectors of the same length)
void extrapolate2D(const double val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
int insertAtClosest(const Position &p, bool interpolateZ)
inserts p between the two closest positions
void push_front(const Position &p)
insert in front a Position
int indexOfClosest(const Position &p) const
index of the closest position to p
void scaleRelative(double factor)
enlarges/shrinks the polygon by a factor based at the centroid
void push_back_noDoublePos(const Position &p)
insert in back a non double position
bool partialWithin(const AbstractPoly &poly, double offset=0) const
Returns the information whether this polygon lies partially within the given polygon.
double getMaxGrade(double &maxJump) const
double area() const
Returns the area (0 for non-closed)
bool isClosed() const
check if PositionVector is closed
void pop_front()
pop first Position
double nearest_offset_to_point25D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D projected onto the 3D geometry
int removeClosest(const Position &p)
removes the point closest to p and return the removal index
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
PositionVector reverse() const
reverse position vector
PositionVector getSubpartByIndex(int beginIndex, int count) const
get subpart of a position vector using index and a cout
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
bool operator==(const PositionVector &v2) const
comparing operation
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
~PositionVector()
Destructor.
bool around(const Position &p, double offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point.
Position transformToVectorCoordinates(const Position &p, bool extend=false) const
return position p within the length-wise coordinate system defined by this position vector....