KiCad PCB EDA Suite
Loading...
Searching...
No Matches
chamfer.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 (C) 2023 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 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <geometry/chamfer.h>
25
26std::optional<CHAMFER_RESULT> ComputeChamferPoints( const SEG& aSegA, const SEG& aSegB,
27 const CHAMFER_PARAMS& aChamferParams )
28{
29 const int line_a_setback = aChamferParams.m_chamfer_setback_a;
30 const int line_b_setback = aChamferParams.m_chamfer_setback_b;
31
32 if( line_a_setback == 0 && line_b_setback == 0 )
33 {
34 // No chamfer to do
35 // In theory a chamfer of 0 on one side is kind-of valid (adds a collinear point)
36 // so allow it (using an and above, not an or)
37 return std::nullopt;
38 }
39
40 if( aSegA.Length() < line_a_setback || aSegB.Length() < line_b_setback )
41 {
42 // Chamfer is too big for the line segments
43 return std::nullopt;
44 }
45
46 // We only support the case where the lines intersect at the end points
47 // otherwise we would need to decide which inside corner to chamfer
48
49 // Figure out which end points are the ones at the intersection
50 const VECTOR2I* a_pt = nullptr;
51 const VECTOR2I* b_pt = nullptr;
52
53 if( aSegA.A == aSegB.A )
54 {
55 a_pt = &aSegA.A;
56 b_pt = &aSegB.A;
57 }
58 else if( aSegA.A == aSegB.B )
59 {
60 a_pt = &aSegA.A;
61 b_pt = &aSegB.B;
62 }
63 else if( aSegA.B == aSegB.A )
64 {
65 a_pt = &aSegA.B;
66 b_pt = &aSegB.A;
67 }
68 else if( aSegA.B == aSegB.B )
69 {
70 a_pt = &aSegA.B;
71 b_pt = &aSegB.B;
72 }
73
74 if( !a_pt || !b_pt )
75 {
76 // No intersection found, so no chamfer to do
77 return std::nullopt;
78 }
79
80 // These are the other existing line points (the ones that are not the intersection)
81 const VECTOR2I& a_end_pt = ( &aSegA.A == a_pt ) ? aSegA.B : aSegA.A;
82 const VECTOR2I& b_end_pt = ( &aSegB.A == b_pt ) ? aSegB.B : aSegB.A;
83
84 // Now, construct segment of the set-back lengths, that begins
85 // at the intersection point and is parallel to each line segments
86 SEG setback_a( *a_pt, *b_pt + VECTOR2I( a_end_pt - *a_pt ).Resize( line_a_setback ) );
87 SEG setback_b( *b_pt, *b_pt + VECTOR2I( b_end_pt - *b_pt ).Resize( line_b_setback ) );
88
89 // The chamfer segment then goes between the end points of the set-back segments
90 SEG chamfer( setback_a.B, setback_b.B );
91
92 // The adjusted segments go from the old end points to the chamfer ends
93
94 std::optional<SEG> new_a;
95
96 if( a_end_pt != chamfer.A )
97 new_a = SEG{ a_end_pt, chamfer.A };
98
99 std::optional<SEG> new_b;
100
101 if( b_end_pt != chamfer.B )
102 new_b = SEG{ b_end_pt, chamfer.B };
103
104 return CHAMFER_RESULT{ chamfer, new_a, new_b };
105}
std::optional< CHAMFER_RESULT > ComputeChamferPoints(const SEG &aSegA, const SEG &aSegB, const CHAMFER_PARAMS &aChamferParams)
Compute the chamfer points for a given line pair and chamfer parameters.
Definition: chamfer.cpp:26
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
int Length() const
Return the length (this).
Definition: seg.h:326
Parameters that define a simple chamfer operation.
Definition: chamfer.h:37
int m_chamfer_setback_b
Chamfer set-back distance along the second line.
Definition: chamfer.h:41
int m_chamfer_setback_a
Chamfer set-back distance along the first line.
Definition: chamfer.h:39
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588