aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2016-05-22 01:46:18 +0200
committerAdrian Kummerlaender2016-05-22 01:46:18 +0200
commit05534078833a80ab435e343438485a4dad410c9d (patch)
treea62efb0ac530297e3c96d5aba893dc9392fcb041
parentfefb5de652f3f07eda7bfb79ebb0134b64e5bd19 (diff)
downloadvoronoi-05534078833a80ab435e343438485a4dad410c9d.tar
voronoi-05534078833a80ab435e343438485a4dad410c9d.tar.gz
voronoi-05534078833a80ab435e343438485a4dad410c9d.tar.bz2
voronoi-05534078833a80ab435e343438485a4dad410c9d.tar.lz
voronoi-05534078833a80ab435e343438485a4dad410c9d.tar.xz
voronoi-05534078833a80ab435e343438485a4dad410c9d.tar.zst
voronoi-05534078833a80ab435e343438485a4dad410c9d.zip
Prevent off-by-one errors during sequential generation
i.e. replaced floating point iteration counter with an integer and use it to calculate the actual p values.
-rw-r--r--example.cc108
1 files changed, 53 insertions, 55 deletions
diff --git a/example.cc b/example.cc
index 8e4eee8..bc82ba4 100644
--- a/example.cc
+++ b/example.cc
@@ -22,54 +22,60 @@ int euclidean_metric(int refX, int refY, int x, int y) {
return minkowski_metric(2, refX, refY, x, y);
}
+void generate_minkowski_voronoi(const double p) {
+ constexpr std::array<imgen::colored_vector, 9> ref{
+ imgen::colored_vector{ 0, 0, imgen::red() },
+ imgen::colored_vector{ 240, 200, imgen::color{220, 220, 220} },
+ imgen::colored_vector{-100, 230, imgen::color{ 94, 113, 106} },
+ imgen::colored_vector{ 120, -100, imgen::color{140, 146, 172} },
+ imgen::colored_vector{ -42, -200, imgen::color{128, 128, 128} },
+ imgen::colored_vector{ 120, 40, imgen::color{ 16, 20, 22} },
+ imgen::colored_vector{-150, 50, imgen::color{192, 192, 192} },
+ imgen::colored_vector{ 60, -128, imgen::color{178, 190, 181} },
+ imgen::colored_vector{-240, -20, imgen::color{ 54, 69, 79} }
+ };
+
+ imgen::write_ppm(
+ "voronoi_" + std::to_string(p) + ".ppm",
+ 512,
+ 512,
+ [&ref, p](std::ptrdiff_t x, std::ptrdiff_t y) -> imgen::color {
+ std::array<int, 9> distances;
+
+ std::transform(
+ ref.begin(),
+ ref.end(),
+ distances.begin(),
+ [x, y, p](const imgen::colored_vector& pos) {
+ return minkowski_metric(p, std::get<0>(pos), std::get<1>(pos), x, y);
+ });
+
+ const auto& minimal_distance = std::min_element(
+ distances.begin(),
+ distances.end()
+ );
+ const imgen::colored_vector& nearest = ref[
+ std::distance(distances.begin(), minimal_distance)
+ ];
+
+ if ( *minimal_distance <= 5 ) {
+ return imgen::black();
+ } else {
+ return std::get<2>(nearest);
+ }
+ }
+ );
+}
+
void generate_minkowski_voronoi(
const double lower,
const double upper,
const double epsilon
) {
- constexpr std::array<imgen::colored_vector, 9> ref{
- imgen::colored_vector{ 0, 0, imgen::red() },
- imgen::colored_vector{ 240, 200, imgen::green() },
- imgen::colored_vector{-100, 230, imgen::blue() },
- imgen::colored_vector{ 120, -100, imgen::yellow() },
- imgen::colored_vector{ -42, -200, imgen::cyan() },
- imgen::colored_vector{ 120, 40, imgen::magenta()},
- imgen::colored_vector{-150, 50, imgen::silver() },
- imgen::colored_vector{ 60, -128, imgen::maroon() },
- imgen::colored_vector{-240, -20, imgen::olive() }
- };
+ const auto n{ std::nearbyint( ( upper - lower ) / epsilon) };
- for ( double p = lower; p < upper + epsilon; p = p + epsilon ) {
- imgen::write_ppm(
- "voronoi_" + std::to_string(p) + ".ppm",
- 512,
- 512,
- [&ref, p](std::ptrdiff_t x, std::ptrdiff_t y) -> imgen::color {
- std::array<int, 9> distances;
-
- std::transform(
- ref.begin(),
- ref.end(),
- distances.begin(),
- [x, y, p](const imgen::colored_vector& pos) {
- return minkowski_metric(p, std::get<0>(pos), std::get<1>(pos), x, y);
- });
-
- const auto& minimal_distance = std::min_element(
- distances.begin(),
- distances.end()
- );
- const imgen::colored_vector& nearest = ref[
- std::distance(distances.begin(), minimal_distance)
- ];
-
- if ( *minimal_distance <= 5 ) {
- return imgen::black();
- } else {
- return std::get<2>(nearest);
- }
- }
- );
+ for ( std::size_t i = 0; i < n; ++i ) {
+ generate_minkowski_voronoi(lower + i * epsilon);
}
}
@@ -81,19 +87,9 @@ void generate_parallel_minkowski_voronoi(
) {
std::vector<std::thread> threads;
- const double step = ( ( upper - lower ) / thread_count ) - epsilon;
+ const double step = ( upper - lower ) / thread_count;
double offset = lower;
- threads.emplace_back([offset, step, epsilon]{
- generate_minkowski_voronoi(
- offset,
- offset + step + epsilon,
- epsilon
- );
- });
-
- offset += step + epsilon + epsilon;
-
while ( threads.size() < thread_count ) {
threads.emplace_back([offset, step, epsilon]{
generate_minkowski_voronoi(
@@ -103,14 +99,16 @@ void generate_parallel_minkowski_voronoi(
);
});
- offset += step + epsilon;
+ offset += step;
}
+ generate_minkowski_voronoi(upper);
+
for ( auto& thread : threads ) {
thread.join();
}
}
int main(int, char*[]) {
- generate_parallel_minkowski_voronoi(4, 1.0, 16.0, 0.05);
+ generate_parallel_minkowski_voronoi(4, 1.0, 2.0, 0.025);
}