|
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