KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_poisson_disk.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 */
20
21#include <boost/test/unit_test.hpp>
22
23#include <cmath>
24
26
27BOOST_AUTO_TEST_SUITE( PoissonDisk )
28
29// Distance squared on the unit torus (coordinates wrap at 1.0)
30static double torDistSq( const VECTOR2D& a, const VECTOR2D& b )
31{
32 double dx = std::fabs( a.x - b.x );
33 double dy = std::fabs( a.y - b.y );
34
35 if( dx > 0.5 )
36 dx = 1.0 - dx;
37
38 if( dy > 0.5 )
39 dy = 1.0 - dy;
40
41 return dx * dx + dy * dy;
42}
43
44
45BOOST_AUTO_TEST_CASE( DegenerateInputs )
46{
47 BOOST_CHECK( POISSON_DISK::ToroidalUnitTile( 0.0, 1 ).empty() );
48 BOOST_CHECK( POISSON_DISK::ToroidalUnitTile( -0.1, 1 ).empty() );
49 BOOST_CHECK( POISSON_DISK::ToroidalUnitTile( 0.6, 1 ).empty() );
50}
51
52
53BOOST_AUTO_TEST_CASE( SamplesInUnitSquare )
54{
55 for( const VECTOR2D& pt : POISSON_DISK::ToroidalUnitTile( 0.125, 42 ) )
56 {
57 BOOST_CHECK( pt.x >= 0.0 && pt.x < 1.0 );
58 BOOST_CHECK( pt.y >= 0.0 && pt.y < 1.0 );
59 }
60}
61
62
63BOOST_AUTO_TEST_CASE( ToroidalMinDistanceRespected )
64{
65 const double minDist = 0.125;
66
67 std::vector<VECTOR2D> samples = POISSON_DISK::ToroidalUnitTile( minDist, 42 );
68
69 for( size_t i = 0; i < samples.size(); ++i )
70 {
71 for( size_t j = i + 1; j < samples.size(); ++j )
72 {
73 BOOST_CHECK_MESSAGE( torDistSq( samples[i], samples[j] ) >= minDist * minDist,
74 "samples " << i << " and " << j << " closer than minDist" );
75 }
76 }
77}
78
79
80BOOST_AUTO_TEST_CASE( DeterministicForSeed )
81{
82 std::vector<VECTOR2D> a = POISSON_DISK::ToroidalUnitTile( 0.125, 42 );
83 std::vector<VECTOR2D> b = POISSON_DISK::ToroidalUnitTile( 0.125, 42 );
84
85 BOOST_REQUIRE_EQUAL( a.size(), b.size() );
86
87 for( size_t i = 0; i < a.size(); ++i )
88 {
89 BOOST_CHECK_EQUAL( a[i].x, b[i].x );
90 BOOST_CHECK_EQUAL( a[i].y, b[i].y );
91 }
92
93 // A different seed must give a different pattern
94 std::vector<VECTOR2D> c = POISSON_DISK::ToroidalUnitTile( 0.125, 43 );
95
96 bool differs = ( a.size() != c.size() );
97
98 for( size_t i = 0; !differs && i < a.size(); ++i )
99 differs = ( a[i] != c[i] );
100
101 BOOST_CHECK( differs );
102}
103
104
105BOOST_AUTO_TEST_CASE( ReasonableDensity )
106{
107 const double minDist = 0.125;
108
109 std::vector<VECTOR2D> samples = POISSON_DISK::ToroidalUnitTile( minDist, 42 );
110
111 // Hexagonal packing bounds the count above at 2/(sqrt(3)*r^2) ~= 74 for r = 1/8.
112 // Bridson sampling typically lands around 55-65; anything below 20 means the
113 // generator stopped early.
114 BOOST_CHECK_GE( samples.size(), 20 );
115 BOOST_CHECK_LE( samples.size(), 74 );
116}
117
static bool empty(const wxTextEntryBase *aCtrl)
std::vector< VECTOR2D > ToroidalUnitTile(double aMinDist, uint32_t aSeed)
Bridson's "Fast Poisson Disk Sampling in Arbitrary Dimensions" with toroidal boundary conditions on t...
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(DegenerateInputs)
static double torDistSq(const VECTOR2D &a, const VECTOR2D &b)
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< double > VECTOR2D
Definition vector2d.h:682