From 89defb3bc2c085b777752c4eb225f52ca5fa1251 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Thu, 19 Apr 2018 13:27:43 +1000 Subject: [PATCH] geom/sample: add trivial poisson sample generator --- CMakeLists.txt | 1 + geom/sample.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ geom/sample.hpp | 9 +++++-- 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 geom/sample.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 43aff927..6264d529 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -240,6 +240,7 @@ list ( geom/ray.hpp geom/rect.cpp geom/rect.hpp + geom/sample.cpp geom/sample.hpp geom/sphere.cpp geom/sphere.hpp diff --git a/geom/sample.cpp b/geom/sample.cpp new file mode 100644 index 00000000..7663a71b --- /dev/null +++ b/geom/sample.cpp @@ -0,0 +1,71 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2018 Danny Robson + */ + +#include "sample.hpp" + +#include "../point.hpp" + +#include + + +/////////////////////////////////////////////////////////////////////////////// +std::vector +util::geom::poisson_sample (util::extent2i area, float distance, int samples) +{ + std::vector selected; + + std::vector candidates (samples); + std::uniform_real_distribution dist_w (0, area.w); + std::uniform_real_distribution dist_h (0, area.h); + std::random_device rd; + std::default_random_engine gen; + + selected.push_back ({ + dist_w (gen), + dist_h (gen), + }); + + auto min_distance = [&selected] (auto q) { + float min_d = INFINITY; + + for (auto s: selected) + if (auto s_d = util::distance2 (s, q); s_d < min_d) + min_d = s_d; + + return min_d; + }; + + while (1) { + util::point2f p; + float d = -INFINITY; + + for (int i = 0; i < samples; ++i) { + util::point2f candidate { dist_w (gen), dist_h (gen) }; + + if (auto p_d = min_distance (candidate); p_d > d) { + p = candidate; + d = p_d; + } + } + + if (std::sqrt (d) < distance) + break; + + selected.push_back (p); + } + + return selected; +} diff --git a/geom/sample.hpp b/geom/sample.hpp index bf4cc88a..c87e7a11 100644 --- a/geom/sample.hpp +++ b/geom/sample.hpp @@ -11,14 +11,15 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * Copyright 2015-2017 Danny Robson + * Copyright 2015-2018 Danny Robson */ #ifndef __UTIL_GEOM_SAMPLE_HPP #define __UTIL_GEOM_SAMPLE_HPP #include "../coord/fwd.hpp" -#include "./ops.hpp" +#include "../extent.hpp" +#include "ops.hpp" #include @@ -72,6 +73,10 @@ namespace util::geom { { return sampler::fn (k, g); } + + + std::vector + poisson_sample (util::extent2i, float distance, int samples); } #endif