Skip to content

Commit 5fc1ecb

Browse files
committed
Don't store the distances in the comparator.
1 parent 0ef71e0 commit 5fc1ecb

File tree

1 file changed

+14
-40
lines changed

1 file changed

+14
-40
lines changed

include/delaunator.cpp

Lines changed: 14 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <limits>
1010
#include <stdexcept>
1111
#include <tuple>
12+
#include <vector>
1213

1314
namespace delaunator {
1415

@@ -160,45 +161,6 @@ inline Point circumcenter(
160161
return Point(x, y);
161162
}
162163

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-
202164
inline bool in_circle(
203165
const double ax,
204166
const double ay,
@@ -327,8 +289,20 @@ Delaunator::Delaunator(std::vector<double> const& in_coords)
327289

328290
m_center = circumcenter(i0x, i0y, i1x, i1y, i2x, i2y);
329291

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+
330302
// 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]; });
332306

333307
// initialize a hash table for storing edges of the advancing convex hull
334308
m_hash_size = static_cast<std::size_t>(std::ceil(std::sqrt(n)));

0 commit comments

Comments
 (0)