| 148 | } |
| 149 | |
| 150 | std::vector<ImVec2> VHConvexHull(const std::vector<ImVec2> &points) { |
| 151 | std::vector<ImVec2> hull; |
| 152 | |
| 153 | // There must be at least 3 points |
| 154 | if (points.size() < 3) return hull; |
| 155 | |
| 156 | // Find the leftmost point |
| 157 | int l = 0; |
| 158 | for (size_t i = 1; i < points.size(); i++) { |
| 159 | if (points[i].x < points[l].x) { |
| 160 | l = i; |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | // Start from leftmost point, keep moving counterclockwise |
| 165 | // until reach the start point again. This loop runs O(h) |
| 166 | // times where h is number of points in result or output. |
| 167 | int p = l, q; |
| 168 | do { |
| 169 | // Add current point to result |
| 170 | // hull[hpc] = CoordToScreen(points[p].x, points[p].y); |
| 171 | hull.push_back({points[p].x, points[p].y}); |
| 172 | |
| 173 | // Search for a point 'q' such that orientation(p, x, |
| 174 | // q) is counterclockwise for all points 'x'. The idea |
| 175 | // is to keep track of last visited most counterclock- |
| 176 | // wise point in q. If any point 'i' is more counterclock- |
| 177 | // wise than q, then update q. |
| 178 | q = (p + 1) % points.size(); |
| 179 | for (size_t i = 0; i < points.size(); i++) { |
| 180 | // If i is more counterclockwise than current q, then update q |
| 181 | if (VHConvexHullOrientation(points[p], points[i], points[q]) == 2) { |
| 182 | q = i; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | // Now q is the most counterclockwise with respect to p |
| 187 | // Set p as q for next iteration, so that q is added to |
| 188 | // result 'hull' |
| 189 | p = q; |
| 190 | |
| 191 | } while ((p != l) && (hull.size() < points.size())); // While we don't come to first point |
| 192 | |
| 193 | return hull; |
| 194 | } |
| 195 | |
| 196 | int VHTightenHull(ImVec2 hull[], int n, double threshold) { |
| 197 | // theory: circle the hull, compare 3 points at a time, if the mid point is |
no test coverage detected