/* * 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; }