|
9 | 9 | #include <limits> |
10 | 10 | #include <stdexcept> |
11 | 11 | #include <tuple> |
| 12 | +#include <vector> |
12 | 13 |
|
13 | 14 | namespace delaunator { |
14 | 15 |
|
@@ -160,45 +161,6 @@ inline Point circumcenter( |
160 | 161 | return Point(x, y); |
161 | 162 | } |
162 | 163 |
|
163 | | - |
164 | | -struct compare { |
165 | | - |
166 | | - std::vector<double> const& m_coords; |
167 | | - std::vector<double> m_dists; |
168 | | - |
169 | | - compare(std::vector<double> const& coords, const Point& center) : |
170 | | - m_coords(coords) |
171 | | - { |
172 | | - size_t n = m_coords.size() / 2; |
173 | | - m_dists.reserve(n); |
174 | | - double const *xcoord = m_coords.data(); |
175 | | - double const *ycoord = m_coords.data() + 1; |
176 | | - while (n--) |
177 | | - { |
178 | | - m_dists.push_back(dist(*xcoord, *ycoord, center.x(), center.y())); |
179 | | - xcoord += 2; |
180 | | - ycoord += 2; |
181 | | - } |
182 | | - } |
183 | | - |
184 | | - bool operator()(std::size_t i, std::size_t j) |
185 | | - { |
186 | | - const double diff1 = m_dists[i] - m_dists[j]; |
187 | | - const double diff2 = m_coords[2 * i] - m_coords[2 * j]; |
188 | | - const double diff3 = m_coords[2 * i + 1] - m_coords[2 * j + 1]; |
189 | | - |
190 | | - //ABELL - Not sure why we're not just checking != 0 here. |
191 | | - if (diff1 > 0.0 || diff1 < 0.0) { |
192 | | - return diff1 < 0; |
193 | | - } else if (diff2 > 0.0 || diff2 < 0.0) { |
194 | | - return diff2 < 0; |
195 | | - } else { |
196 | | - return diff3 < 0; |
197 | | - } |
198 | | - } |
199 | | -}; |
200 | | - |
201 | | - |
202 | 164 | inline bool in_circle( |
203 | 165 | const double ax, |
204 | 166 | const double ay, |
@@ -327,8 +289,20 @@ Delaunator::Delaunator(std::vector<double> const& in_coords) |
327 | 289 |
|
328 | 290 | m_center = circumcenter(i0x, i0y, i1x, i1y, i2x, i2y); |
329 | 291 |
|
| 292 | + // Calculate the distances from the center once to avoid having to |
| 293 | + // calculate for each compare. This used to be done in the comparator, |
| 294 | + // but GCC 7.5+ would copy the comparator to iterators used in the |
| 295 | + // sort, and this was excruciatingly slow when there were many points |
| 296 | + // because you had to copy the vector of distances. |
| 297 | + std::vector<double> dists; |
| 298 | + dists.reserve(m_points.size()); |
| 299 | + for (const Point& p : m_points) |
| 300 | + dists.push_back(dist(p.x(), p.y(), m_center.x(), m_center.y())); |
| 301 | + |
330 | 302 | // sort the points by distance from the seed triangle circumcenter |
331 | | - std::sort(ids.begin(), ids.end(), compare{ coords, m_center }); |
| 303 | + std::sort(ids.begin(), ids.end(), |
| 304 | + [&dists](std::size_t i, std::size_t j) |
| 305 | + { return dists[i] < dists[j]; }); |
332 | 306 |
|
333 | 307 | // initialize a hash table for storing edges of the advancing convex hull |
334 | 308 | m_hash_size = static_cast<std::size_t>(std::ceil(std::sqrt(n))); |
|
0 commit comments