I implemented the @templatetypedefdef solution in C++ for a closed polygonal chain described by two vectors x,y . I go along the polygon, and if the point is collinear to the previous and next point, I delete it:
template<class T> void del_collinear_vanilla(std::vector<T> &x, std::vector<T> &y) { assert(x.size() == y.size()); size_t i = x.size(); size_t im1, ip1 = 0; do { i--; im1 = i ? i - 1 : x.size() - 1; if (are_collinear(x[ip1], y[ip1], x[i], y[i], x[im1], y[im1])) { x.erase(x.begin() + i); y.erase(y.begin() + i); } ip1 = i; } while (i != 0); }
where the implementation depends on the macro / template are_collinear(x0,y0,x1,y1,x2,y2) .
However, in some cases, I still had some colinear points at the exit. This is an example input with which the algorithm crashes:

In this example, P5 is the same as P0, and P4 has the same ordinate P0 and P1; I slightly changed their coordinates to show all segments. The algorithm should only return a rectangle with vertices P1, P2, P3, P4.
Above, P6 is collinear to P5 and P0. Then, as soon as P6 is removed, P5 and P0 coincide, and both are collinear with P4 and P1.
It turns out that a simple cycle over each point, removing the point, if it is collinear to the previous and next point, does not give the correct result.
(In the example, suppose you start with P0 and you find that it is not collinear with a point before P6 and a point after P1. Then you go to P1, P2, ... until you reach P6. P6 is collinear, you delete it , and the cycle is completed. But now P0 is collinear to P4 and P1, and it had to be deleted!)
The same flaw exists for an open path. The algorithm works fine until the input path is compiled by itself .
The solution is to take a step backward every time you delete a point to make sure that the previous point has become collinear:
template<class T> void del_collinear(std::vector<T> &x, std::vector<T> &y) { assert(x.size() == y.size()); size_t target = x.size() - 1; size_t i = x.size() - 1; do { size_t im1 = i ? i - 1 : x.size() - 1; size_t ip1 = (i == x.size() - 1) ? 0 : i + 1; if (are_collinear(x[ip1], y[ip1], x[i], y[i], x[im1], y[im1])) { x.erase(x.begin() + i); y.erase(y.begin() + i);