KiCad PCB EDA Suite
Loading...
Searching...
No Matches
nearest.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, see <https://www.gnu.org/licenses/>.
18 */
19
20#include "geometry/nearest.h"
21
22#include <wx/debug.h>
23
24#include <core/type_helpers.h>
25
27
28
29namespace
30{
31
32VECTOR2I NearestPoint( const BOX2I& aBox, const VECTOR2I& aPt )
33{
34 VECTOR2I nearest;
35 int bestDistance = std::numeric_limits<int>::max();
36
37 for( const SEG& seg : KIGEOM::BoxToSegs( aBox ) )
38 {
39 const VECTOR2I nearestSegPt = seg.NearestPoint( aPt );
40 const int thisDistance = nearestSegPt.Distance( aPt );
41
42 if( thisDistance <= bestDistance )
43 {
44 nearest = nearestSegPt;
45 bestDistance = thisDistance;
46 }
47 }
48 return nearest;
49};
50
51} // namespace
52
53
55{
56 VECTOR2I nearest;
57
58 std::visit(
59 [&]( const auto& geom )
60 {
61 using GeomType = std::decay_t<decltype( geom )>;
62
63 if constexpr( std::is_same_v<GeomType, LINE>
64 || std::is_same_v<GeomType, HALF_LINE>
65 || std::is_same_v<GeomType, SEG>
66 || std::is_same_v<GeomType, CIRCLE>
67 || std::is_same_v<GeomType, SHAPE_ARC> )
68 {
69 // Same signatures for all these types
70 // But they're not in the same polymorphic hierarchy
71 nearest = geom.NearestPoint( aPt );
72 }
73 else if constexpr( std::is_same_v<GeomType, BOX2I> )
74 {
75 // Defer to the utils function
76 nearest = NearestPoint( geom, aPt );
77 }
78 else if constexpr( std::is_same_v<GeomType, VECTOR2I> )
79 {
80 nearest = geom;
81 }
82 else
83 {
84 static_assert( always_false<GeomType>::value, "non-exhaustive visitor" );
85 }
86 },
87 aGeom );
88
89 return nearest;
90}
91
92OPT_VECTOR2I GetNearestPoint( const std::vector<NEARABLE_GEOM>& aGeoms, const VECTOR2I& aPt )
93{
94 OPT_VECTOR2I nearestPointOnAny;
95 int bestDistance = std::numeric_limits<int>::max();
96
97 for( const NEARABLE_GEOM& geom : aGeoms )
98 {
99 const VECTOR2I thisNearest = GetNearestPoint( geom, aPt );
100 const int thisDistance = thisNearest.Distance( aPt );
101
102 if( !nearestPointOnAny || thisDistance < bestDistance )
103 {
104 nearestPointOnAny = thisNearest;
105 bestDistance = thisDistance;
106 }
107 }
108
109 return nearestPointOnAny;
110}
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
Definition seg.h:38
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
Definition vector2d.h:549
std::array< SEG, 4 > BoxToSegs(const BOX2I &aBox)
Decompose a BOX2 into four segments.
VECTOR2I GetNearestPoint(const NEARABLE_GEOM &aGeom, const VECTOR2I &aPt)
Get the nearest point on a geometry to a given point.
Definition nearest.cpp:54
std::variant< LINE, HALF_LINE, SEG, CIRCLE, SHAPE_ARC, BOX2I, VECTOR2I > NEARABLE_GEOM
A variant type that can hold any of the supported geometry types for nearest point calculations.
Definition nearest.h:39
std::optional< VECTOR2I > OPT_VECTOR2I
Definition seg.h:35
Utility functions for working with shapes.
A type that is always false.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683