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) {
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);