62 std::copy(v.begin(), v.end(), std::back_inserter(*
this));
67 std::copy(beg, end, std::back_inserter(*
this));
91 for (const_iterator i = begin(); i != end() - 1; i++) {
96 (*(i + 1)).x() - p.
x(),
97 (*(i + 1)).y() - p.
y());
101 (*(end() - 1)).x() - p.
x(),
102 (*(end() - 1)).y() - p.
y());
104 (*(begin())).x() - p.
x(),
105 (*(begin())).y() - p.
y());
107 return (!(fabs(angle) <
M_PI));
121 for (const_iterator i = begin(); i != end() - 1; i++) {
122 if (poly.
crosses(*i, *(i + 1))) {
126 if (size() > 2 && poly.
crosses(back(), front())) {
138 for (const_iterator i = begin(); i != end() - 1; i++) {
141 if (fabs(closest.
z() - (*i).z()) < zThreshold) {
147 for (const_iterator i = poly.begin(); i != poly.end() - 1; i++) {
150 if (fabs(closest.
z() - (*i).z()) < zThreshold) {
164 for (const_iterator i = begin(); i != end() - 1; i++) {
178 for (const_iterator i = begin(); i != end() - 1; i++) {
189 for (const_iterator i = begin(); i != end() - 1; i++) {
191 if (
intersects(*i, *(i + 1), p1, p2, withinDist, &x, &y, &m)) {
201 for (const_iterator i = begin(); i != end() - 1; i++) {
215 return at((
int)size() + index);
225 return at((
int)size() + index);
233 const_iterator i = begin();
234 double seenLength = 0;
236 const double nextLength = (*i).distanceTo(*(i + 1));
237 if (seenLength + nextLength > pos) {
240 seenLength += nextLength;
241 }
while (++i != end() - 1);
242 if (lateralOffset == 0 || size() < 2) {
245 return positionAtOffset(*(end() - 2), *(end() - 1), (*(end() - 2)).distanceTo(*(end() - 1)), lateralOffset);
252 const_iterator i = begin();
253 double seenLength = 0;
255 const double nextLength = (*i).distanceTo2D(*(i + 1));
256 if (seenLength + nextLength > pos) {
259 seenLength += nextLength;
260 }
while (++i != end() - 1);
270 const_iterator i = begin();
271 double seenLength = 0;
276 if (seenLength + nextLength > pos) {
279 seenLength += nextLength;
280 }
while (++i != end() - 1);
295 const_iterator i = begin();
296 double seenLength = 0;
301 if (seenLength + nextLength > pos) {
304 seenLength += nextLength;
305 }
while (++i != end() - 1);
315 if (pos < 0. || dist < pos) {
318 if (lateralOffset != 0) {
326 return p1 + (p2 - p1) * (pos / dist) + offset;
331 return p1 + (p2 - p1) * (pos / dist);
338 if (pos < 0 || dist < pos) {
341 if (lateralOffset != 0) {
346 return p1 + (p2 - p1) * (pos / dist) + offset;
351 return p1 + (p2 - p1) * (pos / dist);
358 for (const_iterator i = begin(); i != end(); i++) {
370 for (const_iterator i = begin(); i != end(); i++) {
375 return Position(x / (
double) size(), y / (
double) size(), z / (
double)size());
383 tmp.push_back(tmp[0]);
385 const int endIndex = (int)tmp.size() - 1;
389 if (tmp.
area() != 0) {
391 for (
int i = 0; i < endIndex; i++) {
392 const double z = tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
394 x += (tmp[i].x() + tmp[i + 1].x()) * z;
395 y += (tmp[i].y() + tmp[i + 1].y()) * z;
402 double lengthSum = 0;
403 for (
int i = 0; i < endIndex; i++) {
404 double length = tmp[i].distanceTo(tmp[i + 1]);
405 x += (tmp[i].x() + tmp[i + 1].x()) * length / 2;
406 y += (tmp[i].y() + tmp[i + 1].y()) * length / 2;
409 if (lengthSum == 0) {
413 return Position(x / lengthSum, y / lengthSum);
421 for (
int i = 0; i < static_cast<int>(size()); i++) {
422 (*this)[i] = centroid + (((*this)[i] - centroid) * factor);
430 for (
int i = 0; i < static_cast<int>(size()); i++) {
431 (*this)[i] = centroid + (((*this)[i] - centroid) + offset);
448 for (const_iterator i = begin(); i != end() - 1; i++) {
449 len += (*i).distanceTo(*(i + 1));
458 for (const_iterator i = begin(); i != end() - 1; i++) {
459 len += (*i).distanceTo2D(*(i + 1));
473 tmp.push_back(tmp[0]);
475 const int endIndex = (int)tmp.size() - 1;
477 for (
int i = 0; i < endIndex; i++) {
478 area += tmp[i].x() * tmp[i + 1].y() - tmp[i + 1].x() * tmp[i].y();
492 for (const_iterator i = begin(); i != end() - 1; i++) {
493 if (poly.
around(*i, offset)) {
507 std::pair<PositionVector, PositionVector>
516 first.push_back((*
this)[0]);
518 const_iterator it = begin() + 1;
519 double next = first.back().distanceTo(*it);
523 first.push_back(*it);
525 next = first.back().distanceTo(*it);
527 if (fabs(where - (seen + next)) >
POSITION_EPS || it == end() - 1) {
534 first.push_back(*it);
537 for (; it != end(); it++) {
538 second.push_back(*it);
540 assert(first.size() >= 2);
541 assert(second.size() >= 2);
542 assert(first.back() == second.front());
544 return std::pair<PositionVector, PositionVector>(first, second);
550 for (PositionVector::const_iterator i = geom.begin(); i != geom.end(); i++) {
551 if (i != geom.begin()) {
568 for (
int i = 0; i < static_cast<int>(size()); i++) {
569 (*this)[i].add(xoff, yoff, zoff);
576 add(offset.
x(), offset.
y(), offset.
z());
582 for (
int i = 0; i < static_cast<int>(size()); i++) {
583 (*this)[i].mul(1, -1);
593 return atan2(p1.
x(), p1.
y()) < atan2(p2.
x(), p2.
y());
609 if (p1.
x() != p2.
x()) {
610 return p1.
x() < p2.
x();
612 return p1.
y() < p2.
y();
618 return (P1.
x() - P0.
x()) * (P2.
y() - P0.
y()) - (P2.
x() - P0.
x()) * (P1.
y() - P0.
y());
624 if (size() > 0 && v.size() > 0 && back().distanceTo(v[0]) < sameThreshold) {
625 copy(v.begin() + 1, v.end(), back_inserter(*
this));
627 copy(v.begin(), v.end(), back_inserter(*
this));
643 ret.push_back(begPos);
646 const_iterator i = begin();
648 while ((i + 1) != end()
650 seen + (*i).distanceTo(*(i + 1)) < beginOffset) {
651 seen += (*i).distanceTo(*(i + 1));
655 while ((i + 1) != end()
657 seen + (*i).distanceTo(*(i + 1)) < endOffset) {
660 seen += (*i).distanceTo(*(i + 1));
665 if (ret.size() == 1) {
666 ret.push_back(endPos);
683 ret.push_back(begPos);
686 const_iterator i = begin();
688 while ((i + 1) != end()
690 seen + (*i).distanceTo2D(*(i + 1)) < beginOffset) {
691 seen += (*i).distanceTo2D(*(i + 1));
695 while ((i + 1) != end()
697 seen + (*i).distanceTo2D(*(i + 1)) < endOffset) {
700 seen += (*i).distanceTo2D(*(i + 1));
705 if (ret.size() == 1) {
706 ret.push_back(endPos);
714 if (beginIndex < 0) {
715 beginIndex += (int)size();
718 assert(beginIndex < (
int)size());
719 assert(beginIndex + count <= (
int)size());
721 for (
int i = beginIndex; i < beginIndex + count; ++i) {
722 result.push_back((*
this)[i]);
730 return front().angleTo2D(back());
736 double minDist = std::numeric_limits<double>::max();
739 for (const_iterator i = begin(); i != end() - 1; i++) {
743 if (dist < minDist) {
744 nearestPos = pos + seen;
750 if (cornerDist < minDist) {
755 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
757 minDist = cornerDist;
761 seen += (*i).distanceTo2D(*(i + 1));
776 double minDist = std::numeric_limits<double>::max();
777 double nearestPos = -1;
780 for (const_iterator i = begin(); i != end() - 1; i++) {
784 if (dist < minDist) {
785 nearestPos = pos + seen;
787 sign =
isLeft(*i, *(i + 1), p) >= 0 ? -1 : 1;
792 if (cornerDist < minDist) {
797 if (pos1 == (*(i - 1)).distanceTo2D(*i) && pos2 == 0.) {
799 minDist = cornerDist;
800 sign =
isLeft(*(i - 1), *i, p) >= 0 ? -1 : 1;
804 seen += (*i).distanceTo2D(*(i + 1));
806 if (nearestPos != -1) {
807 return Position(nearestPos, sign * minDist);
817 double minDist = std::numeric_limits<double>::max();
820 for (
int i = 0; i < (int)size(); i++) {
822 if (dist < minDist) {
833 double minDist = std::numeric_limits<double>::max();
834 int insertionIndex = 1;
835 for (
int i = 0; i < (int)size() - 1; i++) {
839 if (dist < minDist) {
840 insertionIndex = i + 1;
844 insert(begin() + insertionIndex, p);
845 return insertionIndex;
854 double minDist = std::numeric_limits<double>::max();
855 int removalIndex = 0;
856 for (
int i = 0; i < (int)size(); i++) {
858 if (dist < minDist) {
863 erase(begin() + removalIndex);
870 std::vector<double> ret;
871 for (const_iterator i = other.begin(); i != other.end() - 1; i++) {
873 copy(atSegment.begin(), atSegment.end(), back_inserter(ret));
881 std::vector<double> ret;
883 for (const_iterator i = begin(); i != end() - 1; i++) {
887 if (
intersects(p1, p2, lp1, lp2, 0., &x, &y, &m)) {
888 ret.push_back(
Position(x, y).distanceTo2D(p1) + pos);
939 for (const_reverse_iterator i = rbegin(); i != rend(); i++) {
949 return Position((beg.
y() - end.
y()) * scale, (end.
x() - beg.
x()) * scale);
963 for (
int i = 0; i < static_cast<int>(size()); i++) {
966 const Position& to = (*this)[i + 1];
968 shape.push_back(from -
sideOffset(from, to, amount));
970 }
else if (i == static_cast<int>(size()) - 1) {
971 const Position& from = (*this)[i - 1];
974 shape.push_back(to -
sideOffset(from, to, amount));
977 const Position& from = (*this)[i - 1];
979 const Position& to = (*this)[i + 1];
982 const double extrapolateDev = fromMe[1].distanceTo2D(to);
985 shape.push_back(me -
sideOffset(from, to, amount));
990 shape.push_back(fromMe[1]);
1001 shape.push_back(meNew);
1004 shape.back().set(shape.back().x(), shape.back().y(), me.
z());
1013 assert((
int)size() > pos + 1);
1014 return (*
this)[pos].angleTo2D((*
this)[pos + 1]);
1020 if (size() == 0 || (*
this)[0] == back()) {
1023 push_back((*
this)[0]);
1029 std::vector<double> ret;
1031 for (i = begin(); i != end(); i++) {
1032 const double dist = s.
distance2D(*i, perpendicular);
1034 ret.push_back(dist);
1037 for (i = s.begin(); i != s.end(); i++) {
1038 const double dist =
distance2D(*i, perpendicular);
1040 ret.push_back(dist);
1050 return std::numeric_limits<double>::max();
1051 }
else if (size() == 1) {
1052 return front().distanceTo(p);
1081 if (at == begin()) {
1083 }
else if (at == end()) {
1095 return size() >= 2 && (*this)[0] == back();
1102 iterator last = begin();
1103 for (iterator i = begin() + 1; i != end() && (!assertLength || size() > 2);) {
1104 if (last->almostSame(*i, minDist)) {
1117 return static_cast<vp>(*this) ==
static_cast<vp>(v2);
1123 return static_cast<vp>(*this) !=
static_cast<vp>(v2);
1129 WRITE_ERROR(
"Trying to substract PositionVectors of different lengths.");
1133 auto i2 = v2.begin();
1134 while (i1 != end()) {
1143 WRITE_ERROR(
"Trying to substract PositionVectors of different lengths.");
1147 auto i2 = v2.begin();
1148 while (i1 != end()) {
1159 for (const_iterator i = begin(); i != end() - 1; i++) {
1160 if ((*i).z() != (*(i + 1)).z()) {
1170 const double eps = std::numeric_limits<double>::epsilon();
1171 const double denominator = (p22.
y() - p21.
y()) * (p12.
x() - p11.
x()) - (p22.
x() - p21.
x()) * (p12.
y() - p11.
y());
1172 const double numera = (p22.
x() - p21.
x()) * (p11.
y() - p21.
y()) - (p22.
y() - p21.
y()) * (p11.
x() - p21.
x());
1173 const double numerb = (p12.
x() - p11.
x()) * (p11.
y() - p21.
y()) - (p12.
y() - p11.
y()) * (p11.
x() - p21.
x());
1175 if (fabs(numera) < eps && fabs(numerb) < eps && fabs(denominator) < eps) {
1181 if (p11.
x() != p12.
x()) {
1182 a1 = p11.
x() < p12.
x() ? p11.
x() : p12.
x();
1183 a2 = p11.
x() < p12.
x() ? p12.
x() : p11.
x();
1184 a3 = p21.
x() < p22.
x() ? p21.
x() : p22.
x();
1185 a4 = p21.
x() < p22.
x() ? p22.
x() : p21.
x();
1187 a1 = p11.
y() < p12.
y() ? p11.
y() : p12.
y();
1188 a2 = p11.
y() < p12.
y() ? p12.
y() : p11.
y();
1189 a3 = p21.
y() < p22.
y() ? p21.
y() : p22.
y();
1190 a4 = p21.
y() < p22.
y() ? p22.
y() : p21.
y();
1192 if (a1 <= a3 && a3 <= a2) {
1199 if (a3 <= a1 && a1 <= a4) {
1208 if (p11.
x() != p12.
x()) {
1209 *mu = (a - p11.
x()) / (p12.
x() - p11.
x());
1211 *y = p11.
y() + (*mu) * (p12.
y() - p11.
y());
1215 if (p12.
y() == p11.
y()) {
1218 *mu = (a - p11.
y()) / (p12.
y() - p11.
y());
1227 if (fabs(denominator) < eps) {
1231 double mua = numera / denominator;
1233 if (fabs(p12.
x() - p22.
x()) < eps && fabs(p12.
y() - p22.
y()) < eps) {
1236 const double offseta = withinDist / p11.
distanceTo2D(p12);
1237 const double offsetb = withinDist / p21.
distanceTo2D(p22);
1238 const double mub = numerb / denominator;
1239 if (mua < -offseta || mua > 1 + offseta || mub < -offsetb || mub > 1 + offsetb) {
1244 *x = p11.
x() + mua * (p12.
x() - p11.
x());
1245 *y = p11.
y() + mua * (p12.
y() - p11.
y());
1254 const double s = sin(angle);
1255 const double c = cos(angle);
1256 for (
int i = 0; i < (int)size(); i++) {
1257 const double x = (*this)[i].x();
1258 const double y = (*this)[i].y();
1259 const double z = (*this)[i].z();
1260 const double xnew = x * c - y * s;
1261 const double ynew = x * s + y * c;
1262 (*this)[i].set(xnew, ynew, z);
1270 bool changed =
true;
1271 while (changed && result.size() > 3) {
1273 for (
int i = 0; i < (int)result.size(); i++) {
1275 const Position& p2 = result[(i + 2) % result.size()];
1276 const int middleIndex = (i + 1) % result.size();
1277 const Position& p0 = result[middleIndex];
1279 const double triangleArea2 = fabs((p2.
y() - p1.
y()) * p0.
x() - (p2.
x() - p1.
x()) * p0.
y() + p2.
x() * p1.
y() - p2.
y() * p1.
x());
1283 result.erase(result.begin() + middleIndex);
1304 result.push_back(base);
1306 result.push_back(tmp[closestIndex]);
1307 }
else if (before) {
1309 if (closestIndex > 0) {
1310 result.push_back(tmp[closestIndex - 1]);
1312 result.push_back(tmp[1]);
1316 if (closestIndex < (
int)size() - 1) {
1317 result.push_back(tmp[closestIndex + 1]);
1319 result.push_back(tmp[-1]);
1324 result.
add(base * -1);
1334 const double z0 = (*this)[0].z();
1336 const double dz = (*this)[1].z() - z0;
1338 if (size() > 2 && dz != 0) {
1348 const double dz2 = result[iLast].z() - z0;
1350 for (
int i = 1; i < iLast; ++i) {
1351 seen += result[i].distanceTo2D(result[i - 1]);
1352 result[i].set(result[i].x(), result[i].y(), z0 + dz2 * seen / dist2);
1366 result[0].setz(zStart);
1367 result[-1].setz(zEnd);
1368 const double dz = zEnd - zStart;
1371 for (
int i = 1; i < (int)size() - 1; ++i) {
1372 seen += result[i].distanceTo2D(result[i - 1]);
1373 result[i].setz(zStart + dz * seen / length);
1385 maxLength = length / ceil(length / maxLength);
1386 for (
double pos = 0; pos <=
length; pos += maxLength) {
1394 if (index < 0 || index >= (
int)size()) {
1398 for (
int i = 1; i <= index; ++i) {
1399 seen += (*this)[i].distanceTo2D((*
this)[i - 1]);
1408 for (
int i = 1; i < (int)size(); ++i) {
1409 const Position& p1 = (*this)[i - 1];
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
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.
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.
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
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
std::pair< PositionVector, PositionVector > splitAt(double where) const
Returns the two lists made when this list vector is splitted at the given point.
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
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
double getMaxGrade() const
return the maximum grade of all segments as a fraction of zRange/length2D
bool crosses(const Position &p1, const Position &p2) const
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.