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);
384 for (const_iterator i = begin(); i != end(); i++) {
396 for (const_iterator i = begin(); i != end(); i++) {
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 add(offset.
x(), offset.
y(), offset.
z());
624 for (
int i = 0; i < (int)size(); i++) {
625 (*this)[i].mul(1, -1);
635 return atan2(p1.
x(), p1.
y()) < atan2(p2.
x(), p2.
y());
650 if (p1.
x() != p2.
x()) {
651 return p1.
x() < p2.
x();
653 return p1.
y() < p2.
y();
659 return (P1.
x() - P0.
x()) * (P2.
y() - P0.
y()) - (P2.
x() - P0.
x()) * (P1.
y() - P0.
y());
665 if ((size() > 0) && (v.size() > 0) && (back().distanceTo(v[0]) < sameThreshold)) {
666 copy(v.begin() + 1, v.end(), back_inserter(*
this));
668 copy(v.begin(), v.end(), back_inserter(*
this));
684 ret.push_back(begPos);
687 const_iterator i = begin();
689 while ((i + 1) != end()
691 seen + (*i).distanceTo(*(i + 1)) < beginOffset) {
692 seen += (*i).distanceTo(*(i + 1));
696 while ((i + 1) != end()
698 seen + (*i).distanceTo(*(i + 1)) < endOffset) {
701 seen += (*i).distanceTo(*(i + 1));
706 if (ret.size() == 1) {
707 ret.push_back(endPos);
727 ret.push_back(begPos);
730 const_iterator i = begin();
732 while ((i + 1) != end()
734 seen + (*i).distanceTo2D(*(i + 1)) < beginOffset) {
735 seen += (*i).distanceTo2D(*(i + 1));
739 while ((i + 1) != end()
741 seen + (*i).distanceTo2D(*(i + 1)) < endOffset) {
744 seen += (*i).distanceTo2D(*(i + 1));
749 if (ret.size() == 1) {
750 ret.push_back(endPos);
761 if (beginIndex < 0) {
762 beginIndex += (int)size();
765 assert(beginIndex < (
int)size());
766 assert(beginIndex + count <= (
int)size());
768 for (
int i = beginIndex; i < beginIndex + count; ++i) {
769 result.push_back((*
this)[i]);
780 return front().angleTo2D(back());
789 double minDist = std::numeric_limits<double>::max();
792 for (const_iterator i = begin(); i != end() - 1; i++) {
796 if (dist < minDist) {
797 nearestPos = pos + seen;
803 if (cornerDist < minDist) {
808 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
810 minDist = cornerDist;
814 seen += (*i).distanceTo2D(*(i + 1));
832 double minDist = std::numeric_limits<double>::max();
833 double nearestPos = -1;
836 for (const_iterator i = begin(); i != end() - 1; i++) {
840 if (dist < minDist) {
841 nearestPos = pos + seen;
843 sign =
isLeft(*i, *(i + 1), p) >= 0 ? -1 : 1;
848 if (cornerDist < minDist) {
853 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
855 minDist = cornerDist;
856 sign =
isLeft(*(i - 1), *i, p) >= 0 ? -1 : 1;
860 seen += (*i).distanceTo2D(*(i + 1));
862 if (nearestPos != -1) {
863 return Position(nearestPos, sign * minDist);
875 double minDist = std::numeric_limits<double>::max();
878 for (
int i = 0; i < (int)size(); i++) {
880 if (dist < minDist) {
894 double minDist = std::numeric_limits<double>::max();
895 int insertionIndex = 1;
896 for (
int i = 0; i < (int)size() - 1; i++) {
900 if (dist < minDist) {
901 insertionIndex = i + 1;
905 insert(begin() + insertionIndex, p);
906 return insertionIndex;
915 double minDist = std::numeric_limits<double>::max();
916 int removalIndex = 0;
917 for (
int i = 0; i < (int)size(); i++) {
919 if (dist < minDist) {
924 erase(begin() + removalIndex);
931 std::vector<double> ret;
932 if (other.size() == 0) {
935 for (const_iterator i = other.begin(); i != other.end() - 1; i++) {
937 copy(atSegment.begin(), atSegment.end(), back_inserter(ret));
945 std::vector<double> ret;
950 for (const_iterator i = begin(); i != end() - 1; i++) {
954 if (
intersects(p1, p2, lp1, lp2, 0., &x, &y, &m)) {
955 ret.push_back(
Position(x, y).distanceTo2D(p1) + pos);
1010 for (const_reverse_iterator i = rbegin(); i != rend(); i++) {
1020 return Position((beg.
y() - end.
y()) * scale, (end.
x() - beg.
x()) * scale);
1034 for (
int i = 0; i < static_cast<int>(size()); i++) {
1037 const Position& to = (*this)[i + 1];
1039 shape.push_back(from -
sideOffset(from, to, amount));
1041 }
else if (i == static_cast<int>(size()) - 1) {
1042 const Position& from = (*this)[i - 1];
1045 shape.push_back(to -
sideOffset(from, to, amount));
1048 const Position& from = (*this)[i - 1];
1050 const Position& to = (*this)[i + 1];
1053 const double extrapolateDev = fromMe[1].distanceTo2D(to);
1056 shape.push_back(me -
sideOffset(from, to, amount));
1061 shape.push_back(fromMe[1]);
1072 shape.push_back(meNew);
1075 shape.back().set(shape.back().x(), shape.back().y(), me.
z());
1084 if ((pos + 1) < (
int)size()) {
1085 return (*
this)[pos].angleTo2D((*
this)[pos + 1]);
1094 if ((size() != 0) && ((*
this)[0] != back())) {
1095 push_back((*
this)[0]);
1102 std::vector<double> ret;
1104 for (i = begin(); i != end(); i++) {
1105 const double dist = s.
distance2D(*i, perpendicular);
1107 ret.push_back(dist);
1110 for (i = s.begin(); i != s.end(); i++) {
1111 const double dist =
distance2D(*i, perpendicular);
1113 ret.push_back(dist);
1123 return std::numeric_limits<double>::max();
1124 }
else if (size() == 1) {
1125 return front().distanceTo(p);
1154 if (at == begin()) {
1156 }
else if (at == end()) {
1168 return (size() >= 2) && ((*this)[0] == back());
1175 iterator last = begin();
1176 for (iterator i = begin() + 1; i != end() && (!assertLength || size() > 2);) {
1177 if (last->almostSame(*i, minDist)) {
1190 return static_cast<vp>(*this) ==
static_cast<vp>(v2);
1196 return static_cast<vp>(*this) !=
static_cast<vp>(v2);
1202 WRITE_ERROR(
"Trying to substract PositionVectors of different lengths.");
1206 auto i2 = v2.begin();
1207 while (i1 != end()) {
1216 WRITE_ERROR(
"Trying to substract PositionVectors of different lengths.");
1220 auto i2 = v2.begin();
1221 while (i1 != end()) {
1232 for (const_iterator i = begin(); i != end() - 1; i++) {
1233 if ((*i).z() != (*(i + 1)).z()) {
1243 const double eps = std::numeric_limits<double>::epsilon();
1244 const double denominator = (p22.
y() - p21.
y()) * (p12.
x() - p11.
x()) - (p22.
x() - p21.
x()) * (p12.
y() - p11.
y());
1245 const double numera = (p22.
x() - p21.
x()) * (p11.
y() - p21.
y()) - (p22.
y() - p21.
y()) * (p11.
x() - p21.
x());
1246 const double numerb = (p12.
x() - p11.
x()) * (p11.
y() - p21.
y()) - (p12.
y() - p11.
y()) * (p11.
x() - p21.
x());
1248 if (fabs(numera) < eps && fabs(numerb) < eps && fabs(denominator) < eps) {
1254 if (p11.
x() != p12.
x()) {
1255 a1 = p11.
x() < p12.
x() ? p11.
x() : p12.
x();
1256 a2 = p11.
x() < p12.
x() ? p12.
x() : p11.
x();
1257 a3 = p21.
x() < p22.
x() ? p21.
x() : p22.
x();
1258 a4 = p21.
x() < p22.
x() ? p22.
x() : p21.
x();
1260 a1 = p11.
y() < p12.
y() ? p11.
y() : p12.
y();
1261 a2 = p11.
y() < p12.
y() ? p12.
y() : p11.
y();
1262 a3 = p21.
y() < p22.
y() ? p21.
y() : p22.
y();
1263 a4 = p21.
y() < p22.
y() ? p22.
y() : p21.
y();
1265 if (a1 <= a3 && a3 <= a2) {
1272 if (a3 <= a1 && a1 <= a4) {
1281 if (p11.
x() != p12.
x()) {
1282 *mu = (a - p11.
x()) / (p12.
x() - p11.
x());
1284 *y = p11.
y() + (*mu) * (p12.
y() - p11.
y());
1288 if (p12.
y() == p11.
y()) {
1291 *mu = (a - p11.
y()) / (p12.
y() - p11.
y());
1300 if (fabs(denominator) < eps) {
1304 double mua = numera / denominator;
1306 if (fabs(p12.
x() - p22.
x()) < eps && fabs(p12.
y() - p22.
y()) < eps) {
1309 const double offseta = withinDist / p11.
distanceTo2D(p12);
1310 const double offsetb = withinDist / p21.
distanceTo2D(p22);
1311 const double mub = numerb / denominator;
1312 if (mua < -offseta || mua > 1 + offseta || mub < -offsetb || mub > 1 + offsetb) {
1317 *x = p11.
x() + mua * (p12.
x() - p11.
x());
1318 *y = p11.
y() + mua * (p12.
y() - p11.
y());
1327 const double s = sin(angle);
1328 const double c = cos(angle);
1329 for (
int i = 0; i < (int)size(); i++) {
1330 const double x = (*this)[i].x();
1331 const double y = (*this)[i].y();
1332 const double z = (*this)[i].z();
1333 const double xnew = x * c - y * s;
1334 const double ynew = x * s + y * c;
1335 (*this)[i].set(xnew, ynew, z);
1343 bool changed =
true;
1344 while (changed && result.size() > 3) {
1346 for (
int i = 0; i < (int)result.size(); i++) {
1348 const Position& p2 = result[(i + 2) % result.size()];
1349 const int middleIndex = (i + 1) % result.size();
1350 const Position& p0 = result[middleIndex];
1352 const double triangleArea2 = fabs((p2.
y() - p1.
y()) * p0.
x() - (p2.
x() - p1.
x()) * p0.
y() + p2.
x() * p1.
y() - p2.
y() * p1.
x());
1356 result.erase(result.begin() + middleIndex);
1377 result.push_back(base);
1379 result.push_back(tmp[closestIndex]);
1380 }
else if (before) {
1382 if (closestIndex > 0) {
1383 result.push_back(tmp[closestIndex - 1]);
1385 result.push_back(tmp[1]);
1389 if (closestIndex < (
int)size() - 1) {
1390 result.push_back(tmp[closestIndex + 1]);
1392 result.push_back(tmp[-1]);
1397 result.
add(base * -1);
1410 const double z0 = (*this)[0].z();
1412 const double dz = (*this)[1].z() - z0;
1414 if (size() > 2 && dz != 0) {
1424 const double dz2 = result[iLast].z() - z0;
1426 for (
int i = 1; i < iLast; ++i) {
1427 seen += result[i].distanceTo2D(result[i - 1]);
1428 result[i].set(result[i].x(), result[i].y(), z0 + dz2 * seen / dist2);
1442 result[0].setz(zStart);
1443 result[-1].setz(zEnd);
1444 const double dz = zEnd - zStart;
1447 for (
int i = 1; i < (int)size() - 1; ++i) {
1448 seen += result[i].distanceTo2D(result[i - 1]);
1449 result[i].setz(zStart + dz * seen / length);
1457 if (maxLength == 0) {
1464 maxLength = length / ceil(length / maxLength);
1465 for (
double pos = 0; pos <=
length; pos += maxLength) {
1473 if (index < 0 || index >= (
int)size()) {
1477 for (
int i = 1; i <= index; ++i) {
1478 seen += (*this)[i].distanceTo2D((*
this)[i - 1]);
1487 for (
int i = 1; i < (int)size(); ++i) {
1488 const Position& p1 = (*this)[i - 1];
1490 const double distZ = fabs(p1.
z() - p2.
z());
1493 maxJump =
MAX2(maxJump, distZ);
1495 result =
MAX2(result, distZ / dist2D);
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
checki 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()
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.
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)
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.
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
void move2side(double amount)
move position vector to side using certain ammount
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
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
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.