From acd94fec68d3d207cc05613d0fd3747cd59c9049 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Sun, 22 May 2016 18:35:37 +0200 Subject: Extract determination of nearest reference vector Replaced const reference with call by value style functions to simplify the code (no performance degredation was detected). --- voronoi.cc | 74 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 38 insertions(+), 36 deletions(-) (limited to 'voronoi.cc') diff --git a/voronoi.cc b/voronoi.cc index 00a49d6..d683fe7 100644 --- a/voronoi.cc +++ b/voronoi.cc @@ -6,9 +6,9 @@ #include double minkowski_metric( - const double p, - const imgen::vector& a, - const imgen::vector& b + const double p, + const imgen::vector a, + const imgen::vector b ) { return std::pow( std::pow(std::abs(std::get<0>(a) - std::get<0>(b)), p) @@ -17,16 +17,11 @@ double minkowski_metric( ); } -double manhattan_metric(const imgen::vector& a, const imgen::vector& b) { - return minkowski_metric(1, a, b); -} - -double euclidean_metric(const imgen::vector& a, const imgen::vector& b) { - return minkowski_metric(2, a, b); -} - -void generate_minkowski_voronoi(const double p) { - constexpr std::array ref{ +std::pair get_distance_to_nearest( + const std::function& metric, + const imgen::vector a +) { + constexpr std::array reference_vectors{ 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} }, @@ -38,37 +33,44 @@ void generate_minkowski_voronoi(const double p) { imgen::colored_vector{-240, -20, imgen::color{ 54, 69, 79} } }; + std::array distances; + + std::transform( + reference_vectors.begin(), + reference_vectors.end(), + distances.begin(), + [&a, &metric](const imgen::colored_vector b) { + return metric(a, imgen::vector{std::get<0>(b), std::get<1>(b)}); + } + ); + + const auto& minimal_distance{ + std::min_element(distances.begin(), distances.end())}; + const imgen::colored_vector& nearest{ + reference_vectors[std::distance(distances.begin(), minimal_distance)]}; + + return std::make_pair(*minimal_distance, nearest); +} + +void generate_minkowski_voronoi(const double p) { + const auto metric{[p](const imgen::vector a, const imgen::vector b) -> double { + return minkowski_metric(p, a, b); + }}; + 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 distances; - - std::transform( - ref.begin(), - ref.end(), - distances.begin(), - [x, y, p](const imgen::colored_vector& pos) { - return minkowski_metric( - p, - imgen::vector{std::get<0>(pos), std::get<1>(pos)}, - imgen::vector{x, y} - ); - }); - - const auto& minimal_distance = std::min_element( - distances.begin(), - distances.end() + [&metric](std::ptrdiff_t x, std::ptrdiff_t y) -> imgen::color { + const auto& nearest = get_distance_to_nearest( + metric, + imgen::vector{x, y} ); - const imgen::colored_vector& nearest = ref[ - std::distance(distances.begin(), minimal_distance) - ]; - if ( *minimal_distance <= 5.0 ) { + if ( nearest.first <= 5.0 ) { return imgen::black(); } else { - return std::get<2>(nearest); + return std::get<2>(nearest.second); } } ); -- cgit v1.2.3