KiCad PCB EDA Suite
direction_45.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) 2019 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program. If not, see <http://www.gnu.or/licenses/>.
18  */
19 
20 #include <geometry/direction45.h>
21 
23  bool aStartDiagonal, int aMaxRadius ) const
24 {
25  bool start_diagonal;
26 
27  if( m_dir == UNDEFINED )
28  start_diagonal = aStartDiagonal;
29  else
30  start_diagonal = IsDiagonal();
31 
32  int w = abs( aP1.x - aP0.x );
33  int h = abs( aP1.y - aP0.y );
34  int sw = sign( aP1.x - aP0.x );
35  int sh = sign( aP1.y - aP0.y );
36 
37  int radius = std::min( aMaxRadius, std::min( w, h ) );
38  bool use_rounded = aMaxRadius > 0;
39  int dist90 = use_rounded ? KiROUND( ( M_SQRT2 - 1.0 ) * radius ) : 0;
40  int dist45 = use_rounded ? KiROUND( radius * ( 1.0 - M_SQRT1_2 ) ) : 0;
41 
42  VECTOR2I mp0, mp1, arc_offset_90, arc_offset_45;
43 
44  // we are more horizontal than vertical?
45 // if( m_90deg )
46 // {
47 // if( m_dir == N || m_dir == S )
48 //
49 // }
50 
51  if( w > h )
52  {
53  mp0 = VECTOR2I( ( w - h - dist90 ) * sw, 0 ); // direction: E
54  mp1 = VECTOR2I( ( h - dist45 ) * sw, ( h - dist45 ) * sh ); // direction: NE
55  arc_offset_90 = VECTOR2I( 0, radius * sh );
56  arc_offset_45 = VECTOR2I( sw * radius * M_SQRT1_2, -sh * radius * M_SQRT1_2 );
57  }
58  else
59  {
60  mp0 = VECTOR2I( 0, sh * ( h - w - dist90 ) ); // direction: N
61  mp1 = VECTOR2I( sw * ( w - dist45 ), sh * ( w - dist45 ) ); // direction: NE
62  arc_offset_90 = VECTOR2I( radius * sw, 0 );
63  arc_offset_45 = VECTOR2I( -sw * radius * M_SQRT1_2, sh * radius * M_SQRT1_2 );
64  }
65 
67  VECTOR2I arc_center;
68 
69  pl.Append( aP0 );
70  VECTOR2I next_point;
71 
72  if( start_diagonal )
73  {
74  next_point = aP0 + mp1;
75  arc_center = aP0 + mp1 + arc_offset_45;
76  }
77  else
78  {
79  next_point = aP0 + mp0;
80  arc_center = aP0 + mp0 + arc_offset_90;
81  }
82 
83  if( use_rounded )
84  {
85  int sa = start_diagonal ? -sw * sh : sw * sh;
86 
87  if( h > w )
88  sa = -sa;
89 
90  SHAPE_ARC new_arc( arc_center, next_point, sa * 45.0 );
91  pl.Append( new_arc );
92  }
93  else
94  {
95  pl.Append( next_point );
96  }
97 
98  pl.Append( aP1 );
99 
100  pl.Simplify();
101  return pl;
102 }
int sign(T val)
Definition: util.h:90
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
SHAPE_LINE_CHAIN & Simplify()
Function Simplify()
bool IsDiagonal() const
Function IsDiagonal() Returns true if the direction is diagonal (e.g.
Definition: direction45.h:186
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false, int aMaxRadius=0) const
Function BuildInitialTrace()
SHAPE_LINE_CHAIN.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:61
Directions m_dir
our actual direction
Definition: direction45.h:329