Skip to content

Commit e64c607

Browse files
committed
parity with delaunator#35
1 parent 373c725 commit e64c607

File tree

3 files changed

+45
-46
lines changed

3 files changed

+45
-46
lines changed

CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/mason.cmake)
99
option(WERROR "Add -Werror flag to build (turns warnings into errors)" ON)
1010
option(BENCHMARK_BIG_O "Calculate Big O in benchmark" OFF)
1111
option(BENCHMARK_100M "Run against 100M points" OFF)
12+
option(BENCHMARK_10M "Run against 100M points" OFF)
1213

1314
# configure optimization
1415
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
@@ -54,11 +55,15 @@ file(GLOB BENCH_SOURCES bench/*.cpp)
5455
add_executable(bench-tests ${BENCH_SOURCES})
5556
if(BENCHMARK_BIG_O)
5657
message("-- BENCHMARK_BIG_O=1")
57-
target_compile_definitions(bench-tests PRIVAT BENCHMARK_BIG_O=1)
58+
target_compile_definitions(bench-tests PUBLIC BENCHMARK_BIG_O=1)
5859
endif()
5960
if(BENCHMARK_100M)
6061
message("-- BENCHMARK_100M=1")
61-
target_compile_definitions(bench-tests PRIVAT BENCHMARK_100M=1)
62+
target_compile_definitions(bench-tests PUBLIC BENCHMARK_100M=1)
63+
endif()
64+
if(BENCHMARK_10M)
65+
message("-- BENCHMARK_10M=1")
66+
target_compile_definitions(bench-tests PUBLIC BENCHMARK_10M=1)
6267
endif()
6368

6469
#examples

bench/run.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,13 @@ BENCHMARK(BM_45K_geojson_nodes)->Unit(benchmark::kMillisecond);
3939
BENCHMARK(BM_uniform)->Arg(2000)->Arg(100000)->Arg(200000)->Arg(500000)->Arg(1000000)->Unit(benchmark::kMillisecond);
4040

4141
#if BENCHMARK_BIG_O
42-
BENCHMARK(BM_uniform)->RangeMultiplier(2)->Range(1<<12, 1<<22)->Unit(benchmark::kMillisecond)->Complexity();
42+
BENCHMARK(BM_uniform)->RangeMultiplier(2)->Range(1 << 12, 1 << 22)->Unit(benchmark::kMillisecond)->Complexity();
43+
#endif
44+
#if BENCHMARK_10M
45+
BENCHMARK(BM_uniform)->Arg(1000000 * 10)->Unit(benchmark::kMillisecond);
4346
#endif
4447
#if BENCHMARK_100M
45-
BENCHMARK(BM_uniform)->Arg(1000000 * 100)->Unit(benchmark::kMillisecond);
48+
BENCHMARK(BM_uniform)->Arg(1000000 * 100)->Unit(benchmark::kMillisecond);
4649
#endif
4750

4851
BENCHMARK_MAIN()

include/delaunator.hpp

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ constexpr double EPSILON = std::numeric_limits<double>::epsilon();
150150
constexpr std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
151151

152152
//@see https://stackoverflow.com/questions/30208196/maximum-recursive-function-calls-in-c-c-before-stack-is-full-and-gives-a-segme
153-
constexpr std::size_t LEGALIZE_STACK_SIZE = 1024;
153+
constexpr std::size_t EDGE_STACK_SIZE = 1024;
154154

155155
inline bool check_pts_equal(double x1, double y1, double x2, double y2) {
156156
return std::fabs(x1 - x2) <= EPSILON &&
@@ -193,7 +193,7 @@ class Delaunator {
193193
double m_center_x;
194194
double m_center_y;
195195
std::size_t m_hash_size;
196-
std::size_t m_legalize_stack[LEGALIZE_STACK_SIZE];
196+
std::size_t m_edge_stack[EDGE_STACK_SIZE];
197197

198198
std::size_t legalize(std::size_t a);
199199
std::size_t hash_key(double x, double y) const;
@@ -219,7 +219,7 @@ Delaunator::Delaunator(std::vector<double> const& in_coords)
219219
m_center_x(),
220220
m_center_y(),
221221
m_hash_size(),
222-
m_legalize_stack() {
222+
m_edge_stack() {
223223
std::size_t n = coords.size() >> 1;
224224

225225
double max_x = std::numeric_limits<double>::min();
@@ -440,21 +440,13 @@ double Delaunator::get_hull_area() {
440440
return sum(hull_area);
441441
}
442442

443-
std::size_t Delaunator::legalize(std::size_t ia) {
444-
std::size_t b;
445-
std::size_t a0;
446-
std::size_t b0;
447-
std::size_t al;
448-
std::size_t ar;
449-
std::size_t bl;
443+
std::size_t Delaunator::legalize(std::size_t a) {
444+
std::size_t i = 0;
445+
std::size_t ar = 0;
450446

451-
unsigned int i = 0;
452-
m_legalize_stack[i] = ia;
453-
size_t size = 1;
454-
while (i < size) {
455-
456-
auto const a = m_legalize_stack[i];
457-
i++;
447+
// recursion eliminated with a fixed-size stack
448+
while (true) {
449+
const size_t b = halfedges[a];
458450

459451
/* if the pair of triangles doesn't satisfy the Delaunay condition
460452
* (p1 is inside the circumcircle of [p0, pl, pr]), flip them,
@@ -471,26 +463,29 @@ std::size_t Delaunator::legalize(std::size_t ia) {
471463
* \||/ \ /
472464
* pr pr
473465
*/
466+
const size_t a0 = 3 * (a / 3);
467+
ar = a0 + (a + 2) % 3;
474468

475-
b = halfedges[a];
476-
477-
//@see https://embeddedgurus.com/stack-overflow/2011/02/efficient-c-tip-13-use-the-modulus-operator-with-caution/
478-
a0 = 3 * (a / 3); //a - a % 3;
479-
b0 = 3 * (b / 3); //b - b % 3;
469+
if (b == INVALID_INDEX) {
470+
if (i > 0) {
471+
i--;
472+
a = m_edge_stack[i];
473+
continue;
474+
} else {
475+
//i = INVALID_INDEX;
476+
break;
477+
}
478+
}
480479

481-
al = a0 + (a + 1) % 3;
482-
ar = a0 + (a + 2) % 3;
483-
bl = b0 + (b + 2) % 3;
480+
const size_t b0 = 3 * (b / 3);
481+
const size_t al = a0 + (a + 1) % 3;
482+
const size_t bl = b0 + (b + 2) % 3;
484483

485484
const std::size_t p0 = triangles[ar];
486485
const std::size_t pr = triangles[a];
487486
const std::size_t pl = triangles[al];
488487
const std::size_t p1 = triangles[bl];
489488

490-
if (b == INVALID_INDEX) {
491-
continue;
492-
}
493-
494489
const bool illegal = in_circle(
495490
coords[2 * p0],
496491
coords[2 * p0 + 1],
@@ -521,23 +516,19 @@ std::size_t Delaunator::legalize(std::size_t ia) {
521516
link(a, hbl);
522517
link(b, halfedges[ar]);
523518
link(ar, bl);
524-
525519
std::size_t br = b0 + (b + 1) % 3;
526520

527-
if (size + 2 >= (LEGALIZE_STACK_SIZE)) {
528-
throw std::runtime_error("Legalize stack overflow");
521+
if (i + 1 < EDGE_STACK_SIZE) {
522+
m_edge_stack[i++] = br;
529523
}
530-
531-
if (i < size) {
532-
//move elements down the stack
533-
for (auto mi = size - 1; mi >= i; mi--) {
534-
m_legalize_stack[mi + 2] = m_legalize_stack[mi];
535-
}
524+
} else {
525+
if (i > 0) {
526+
i--;
527+
a = m_edge_stack[i];
528+
continue;
529+
} else {
530+
break;
536531
}
537-
538-
m_legalize_stack[i] = a;
539-
m_legalize_stack[i + 1] = br;
540-
size += 2;
541532
}
542533
}
543534
return ar;

0 commit comments

Comments
 (0)