KiCad PCB EDA Suite
lib_arc.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) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2004-2020 KiCad Developers, see AUTHORS.txt for contributors.
6  * Copyright (C) 2019 CERN
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <fctsys.h>
27 #include <gr_basic.h>
28 #include <macros.h>
29 #include <sch_draw_panel.h>
30 #include <plotter.h>
31 #include <trigo.h>
32 #include <base_units.h>
33 #include <msgpanel.h>
34 #include <bitmaps.h>
35 #include <math/util.h> // for KiROUND
36 #include <eda_draw_frame.h>
37 #include <general.h>
38 #include <lib_arc.h>
39 #include <transform.h>
41 #include <status_popup.h>
42 
43 // Helper function
44 static inline wxPoint twoPointVector( const wxPoint &startPoint, const wxPoint &endPoint )
45 {
46  return endPoint - startPoint;
47 }
48 
49 
50 LIB_ARC::LIB_ARC( LIB_PART* aParent ) : LIB_ITEM( LIB_ARC_T, aParent )
51 {
52  m_Radius = 0;
53  m_t1 = 0;
54  m_t2 = 0;
55  m_Width = 0;
56  m_Fill = NO_FILL;
57  m_isFillable = true;
58  m_editState = 0;
59 }
60 
61 
62 bool LIB_ARC::HitTest( const wxPoint& aRefPoint, int aAccuracy ) const
63 {
64  int mindist = std::max( aAccuracy + GetPenWidth() / 2,
65  Mils2iu( MINIMUM_SELECTION_DISTANCE ) );
66  wxPoint relativePosition = aRefPoint;
67 
68  relativePosition.y = -relativePosition.y; // reverse Y axis
69 
70  int distance = KiROUND( GetLineLength( m_Pos, relativePosition ) );
71 
72  if( abs( distance - m_Radius ) > mindist )
73  return false;
74 
75  // We are on the circle, ensure we are only on the arc, i.e. between
76  // m_ArcStart and m_ArcEnd
77 
78  wxPoint startEndVector = twoPointVector( m_ArcStart, m_ArcEnd );
79  wxPoint startRelativePositionVector = twoPointVector( m_ArcStart, relativePosition );
80 
81  wxPoint centerStartVector = twoPointVector( m_Pos, m_ArcStart );
82  wxPoint centerEndVector = twoPointVector( m_Pos, m_ArcEnd );
83  wxPoint centerRelativePositionVector = twoPointVector( m_Pos, relativePosition );
84 
85  // Compute the cross product to check if the point is in the sector
86  double crossProductStart = CrossProduct( centerStartVector, centerRelativePositionVector );
87  double crossProductEnd = CrossProduct( centerEndVector, centerRelativePositionVector );
88 
89  // The cross products need to be exchanged, depending on which side the center point
90  // relative to the start point to end point vector lies
91  if( CrossProduct( startEndVector, startRelativePositionVector ) < 0 )
92  {
93  std::swap( crossProductStart, crossProductEnd );
94  }
95 
96  // When the cross products have a different sign, the point lies in sector
97  // also check, if the reference is near start or end point
98  return HitTestPoints( m_ArcStart, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
99  HitTestPoints( m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
100  ( crossProductStart <= 0 && crossProductEnd >= 0 );
101 }
102 
103 
104 bool LIB_ARC::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
105 {
106  if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
107  return false;
108 
110  int radius = GetRadius();
111  int lineWidth = GetWidth();
112  EDA_RECT sel = aRect ;
113 
114  if ( aAccuracy )
115  sel.Inflate( aAccuracy );
116 
117  if( aContained )
118  return sel.Contains( GetBoundingBox() );
119 
120  EDA_RECT arcRect = GetBoundingBox().Common( sel );
121 
122  /* All following tests must pass:
123  * 1. Rectangle must intersect arc BoundingBox
124  * 2. Rectangle must cross the outside of the arc
125  */
126  return arcRect.Intersects( sel ) && arcRect.IntersectsCircleEdge( center, radius, lineWidth );
127 }
128 
129 
131 {
132  return new LIB_ARC( *this );
133 }
134 
135 
136 int LIB_ARC::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const
137 {
138  wxASSERT( aOther.Type() == LIB_ARC_T );
139 
140  int retv = LIB_ITEM::compare( aOther );
141 
142  if( retv )
143  return retv;
144 
145  const LIB_ARC* tmp = ( LIB_ARC* ) &aOther;
146 
147  if( m_Pos.x != tmp->m_Pos.x )
148  return m_Pos.x - tmp->m_Pos.x;
149 
150  if( m_Pos.y != tmp->m_Pos.y )
151  return m_Pos.y - tmp->m_Pos.y;
152 
153  if( m_t1 != tmp->m_t1 )
154  return m_t1 - tmp->m_t1;
155 
156  if( m_t2 != tmp->m_t2 )
157  return m_t2 - tmp->m_t2;
158 
159  return 0;
160 }
161 
162 
163 void LIB_ARC::Offset( const wxPoint& aOffset )
164 {
165  m_Pos += aOffset;
166  m_ArcStart += aOffset;
167  m_ArcEnd += aOffset;
168 }
169 
170 
171 void LIB_ARC::MoveTo( const wxPoint& aPosition )
172 {
173  wxPoint offset = aPosition - m_Pos;
174  m_Pos = aPosition;
175  m_ArcStart += offset;
176  m_ArcEnd += offset;
177 }
178 
179 
180 void LIB_ARC::MirrorHorizontal( const wxPoint& aCenter )
181 {
182  m_Pos.x -= aCenter.x;
183  m_Pos.x *= -1;
184  m_Pos.x += aCenter.x;
185  m_ArcStart.x -= aCenter.x;
186  m_ArcStart.x *= -1;
187  m_ArcStart.x += aCenter.x;
188  m_ArcEnd.x -= aCenter.x;
189  m_ArcEnd.x *= -1;
190  m_ArcEnd.x += aCenter.x;
191  std::swap( m_ArcStart, m_ArcEnd );
192  std::swap( m_t1, m_t2 );
193  m_t1 = 1800 - m_t1;
194  m_t2 = 1800 - m_t2;
195  if( m_t1 > 3600 || m_t2 > 3600 )
196  {
197  m_t1 -= 3600;
198  m_t2 -= 3600;
199  }
200  else if( m_t1 < -3600 || m_t2 < -3600 )
201  {
202  m_t1 += 3600;
203  m_t2 += 3600;
204  }
205 }
206 
207 void LIB_ARC::MirrorVertical( const wxPoint& aCenter )
208 {
209  m_Pos.y -= aCenter.y;
210  m_Pos.y *= -1;
211  m_Pos.y += aCenter.y;
212  m_ArcStart.y -= aCenter.y;
213  m_ArcStart.y *= -1;
214  m_ArcStart.y += aCenter.y;
215  m_ArcEnd.y -= aCenter.y;
216  m_ArcEnd.y *= -1;
217  m_ArcEnd.y += aCenter.y;
218  std::swap( m_ArcStart, m_ArcEnd );
219  std::swap( m_t1, m_t2 );
220  m_t1 = - m_t1;
221  m_t2 = - m_t2;
222  if( m_t1 > 3600 || m_t2 > 3600 )
223  {
224  m_t1 -= 3600;
225  m_t2 -= 3600;
226  }
227  else if( m_t1 < -3600 || m_t2 < -3600 )
228  {
229  m_t1 += 3600;
230  m_t2 += 3600;
231  }
232 }
233 
234 void LIB_ARC::Rotate( const wxPoint& aCenter, bool aRotateCCW )
235 {
236  int rot_angle = aRotateCCW ? -900 : 900;
237  RotatePoint( &m_Pos, aCenter, rot_angle );
238  RotatePoint( &m_ArcStart, aCenter, rot_angle );
239  RotatePoint( &m_ArcEnd, aCenter, rot_angle );
240  m_t1 -= rot_angle;
241  m_t2 -= rot_angle;
242  if( m_t1 > 3600 || m_t2 > 3600 )
243  {
244  m_t1 -= 3600;
245  m_t2 -= 3600;
246  }
247  else if( m_t1 < -3600 || m_t2 < -3600 )
248  {
249  m_t1 += 3600;
250  m_t2 += 3600;
251  }
252 }
253 
254 
255 
256 void LIB_ARC::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
257  const TRANSFORM& aTransform )
258 {
259  wxASSERT( aPlotter != NULL );
260 
261  int t1 = m_t1;
262  int t2 = m_t2;
263  wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
264 
265  aTransform.MapAngles( &t1, &t2 );
266 
267  if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
268  {
269  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
270  aPlotter->Arc( pos, -t2, -t1, m_Radius, FILLED_WITH_BG_BODYCOLOR, 0 );
271  }
272 
273  bool already_filled = m_Fill == FILLED_WITH_BG_BODYCOLOR;
274  int pen_size = GetPenWidth();
275 
276  if( !already_filled || pen_size > 0 )
277  {
278  pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetDefaultPenWidth() );
279 
280  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) );
281  aPlotter->Arc( pos, -t2, -t1, m_Radius, already_filled ? NO_FILL : m_Fill, pen_size );
282  }
283 }
284 
285 
287 {
288  // Historically 0 meant "default width" and negative numbers meant "don't stroke".
289  if( m_Width < 0 && GetFillMode() != NO_FILL )
290  return 0;
291  else
292  return std::max( m_Width, 1 );
293 }
294 
295 
296 void LIB_ARC::print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData,
297  const TRANSFORM& aTransform )
298 {
299  bool forceNoFill = static_cast<bool>( aData );
300  int penWidth = GetPenWidth();
301 
302  if( forceNoFill && m_Fill != NO_FILL && penWidth == 0 )
303  return;
304 
305  wxDC* DC = aSettings->GetPrintDC();
306  wxPoint pos1, pos2, posc;
307  COLOR4D color = aSettings->GetLayerColor( LAYER_DEVICE );
308 
309  pos1 = aTransform.TransformCoordinate( m_ArcEnd ) + aOffset;
310  pos2 = aTransform.TransformCoordinate( m_ArcStart ) + aOffset;
311  posc = aTransform.TransformCoordinate( m_Pos ) + aOffset;
312  int pt1 = m_t1;
313  int pt2 = m_t2;
314  bool swap = aTransform.MapAngles( &pt1, &pt2 );
315 
316  if( swap )
317  {
318  std::swap( pos1.x, pos2.x );
319  std::swap( pos1.y, pos2.y );
320  }
321 
322  if( forceNoFill || m_Fill == NO_FILL )
323  {
324  penWidth = std::max( penWidth, aSettings->GetDefaultPenWidth() );
325 
326  GRArc1( nullptr, DC, pos1.x, pos1.y, pos2.x, pos2.y, posc.x, posc.y, penWidth, color );
327  }
328  else
329  {
332 
333  GRFilledArc( nullptr, DC, posc.x, posc.y, pt1, pt2, m_Radius, penWidth, color, color );
334  }
335 }
336 
337 
339 {
340  int minX, minY, maxX, maxY, angleStart, angleEnd;
341  EDA_RECT rect;
342  wxPoint nullPoint, startPos, endPos, centerPos;
343  wxPoint normStart = m_ArcStart - m_Pos;
344  wxPoint normEnd = m_ArcEnd - m_Pos;
345 
346  if( ( normStart == nullPoint ) || ( normEnd == nullPoint ) || ( m_Radius == 0 ) )
347  {
348  wxLogDebug( wxT("Invalid arc drawing definition, center(%d, %d), start(%d, %d), "
349  "end(%d, %d), radius %d" ),
351  m_ArcEnd.y, m_Radius );
352  return rect;
353  }
354 
358  angleStart = m_t1;
359  angleEnd = m_t2;
360 
361  if( DefaultTransform.MapAngles( &angleStart, &angleEnd ) )
362  {
363  std::swap( endPos.x, startPos.x );
364  std::swap( endPos.y, startPos.y );
365  }
366 
367  /* Start with the start and end point of the arc. */
368  minX = std::min( startPos.x, endPos.x );
369  minY = std::min( startPos.y, endPos.y );
370  maxX = std::max( startPos.x, endPos.x );
371  maxY = std::max( startPos.y, endPos.y );
372 
373  /* Zero degrees is a special case. */
374  if( angleStart == 0 )
375  maxX = centerPos.x + m_Radius;
376 
377  /* Arc end angle wrapped passed 360. */
378  if( angleStart > angleEnd )
379  angleEnd += 3600;
380 
381  if( angleStart <= 900 && angleEnd >= 900 ) /* 90 deg */
382  maxY = centerPos.y + m_Radius;
383 
384  if( angleStart <= 1800 && angleEnd >= 1800 ) /* 180 deg */
385  minX = centerPos.x - m_Radius;
386 
387  if( angleStart <= 2700 && angleEnd >= 2700 ) /* 270 deg */
388  minY = centerPos.y - m_Radius;
389 
390  if( angleStart <= 3600 && angleEnd >= 3600 ) /* 0 deg */
391  maxX = centerPos.x + m_Radius;
392 
393  rect.SetOrigin( minX, minY );
394  rect.SetEnd( maxX, maxY );
395  rect.Inflate( ( GetPenWidth() / 2 ) + 1 );
396 
397  return rect;
398 }
399 
400 
401 void LIB_ARC::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
402 {
403  wxString msg;
404  EDA_RECT bBox = GetBoundingBox();
405 
406  LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
407 
408  msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Width, true );
409 
410  aList.emplace_back( _( "Line Width" ), msg, BLUE );
411 
412  msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
413  bBox.GetOrigin().y, bBox.GetEnd().x, bBox.GetEnd().y );
414 
415  aList.emplace_back( _( "Bounding Box" ), msg, BROWN );
416 }
417 
418 
419 wxString LIB_ARC::GetSelectMenuText( EDA_UNITS aUnits ) const
420 {
421  return wxString::Format( _( "Arc center (%s, %s), radius %s" ),
422  MessageTextFromValue( aUnits, m_Pos.x ),
423  MessageTextFromValue( aUnits, m_Pos.y ),
424  MessageTextFromValue( aUnits, m_Radius ) );
425 }
426 
427 
429 {
430  return add_arc_xpm;
431 }
432 
433 
434 void LIB_ARC::BeginEdit( const wxPoint aPosition )
435 {
436  m_ArcStart = m_ArcEnd = aPosition;
437  m_editState = 1;
438 }
439 
440 
441 void LIB_ARC::CalcEdit( const wxPoint& aPosition )
442 {
443 #define sq( x ) pow( x, 2 )
444 
445  // Edit state 0: drawing: place ArcStart
446  // Edit state 1: drawing: place ArcEnd (center calculated for 90-degree subtended angle)
447  // Edit state 2: point editing: move ArcStart (center calculated for invariant subtended angle)
448  // Edit state 3: point editing: move ArcEnd (center calculated for invariant subtended angle)
449  // Edit state 4: point editing: move center
450 
451  switch( m_editState )
452  {
453  case 0:
454  m_ArcStart = aPosition;
455  m_ArcEnd = aPosition;
456  m_Pos = aPosition;
457  m_Radius = 0;
458  m_t1 = 0;
459  m_t2 = 0;
460  return;
461 
462  case 1:
463  m_ArcEnd = aPosition;
464  m_Radius = KiROUND( sqrt( pow( GetLineLength( m_ArcStart, m_ArcEnd ), 2 ) / 2.0 ) );
465  break;
466 
467  case 2:
468  case 3:
469  {
471  double chordBefore = sq( v.x ) + sq( v.y );
472 
473  if( m_editState == 2 )
474  m_ArcStart = aPosition;
475  else
476  m_ArcEnd = aPosition;
477 
478  v = m_ArcStart - m_ArcEnd;
479  double chordAfter = sq( v.x ) + sq( v.y );
480  double ratio = chordAfter / chordBefore;
481 
482  if( ratio > 0 )
483  {
484  m_Radius = int( sqrt( m_Radius * m_Radius * ratio ) ) + 1;
485  m_Radius = std::max( m_Radius, int( sqrt( chordAfter ) / 2 ) + 1 );
486  }
487 
488  break;
489  }
490 
491  case 4:
492  {
493  double chordA = GetLineLength( m_ArcStart, aPosition );
494  double chordB = GetLineLength( m_ArcEnd, aPosition );
495  m_Radius = int( ( chordA + chordB ) / 2.0 ) + 1;
496  break;
497  }
498  }
499 
500  // Calculate center based on start, end, and radius
501  //
502  // Let 'l' be the length of the chord and 'm' the middle point of the chord
503  double l = GetLineLength( m_ArcStart, m_ArcEnd );
504  wxPoint m = ( m_ArcStart + m_ArcEnd ) / 2;
505 
506  // Calculate 'd', the vector from the chord midpoint to the center
507  wxPoint d;
508  d.x = KiROUND( sqrt( sq( m_Radius ) - sq( l/2 ) ) * ( m_ArcStart.y - m_ArcEnd.y ) / l );
509  d.y = KiROUND( sqrt( sq( m_Radius ) - sq( l/2 ) ) * ( m_ArcEnd.x - m_ArcStart.x ) / l );
510 
511  wxPoint c1 = m + d;
512  wxPoint c2 = m - d;
513 
514  // Solution gives us 2 centers; we need to pick one:
515  switch( m_editState )
516  {
517  case 1:
518  {
519  // Keep center clockwise from chord while drawing
520  wxPoint chordVector = twoPointVector( m_ArcStart, m_ArcEnd );
521  double chordAngle = ArcTangente( chordVector.y, chordVector.x );
522  NORMALIZE_ANGLE_POS( chordAngle );
523 
524  wxPoint c1Test = c1;
525  RotatePoint( &c1Test, m_ArcStart, -chordAngle );
526 
527  m_Pos = c1Test.x > 0 ? c2 : c1;
528  }
529  break;
530 
531  case 2:
532  case 3:
533  // Pick the one closer to the old center
534  m_Pos = ( GetLineLength( c1, m_Pos ) < GetLineLength( c2, m_Pos ) ) ? c1 : c2;
535  break;
536 
537  case 4:
538  // Pick the one closer to the mouse position
539  m_Pos = ( GetLineLength( c1, aPosition ) < GetLineLength( c2, aPosition ) ) ? c1 : c2;
540  break;
541  }
542 
544 }
545 
546 
548 {
549  wxPoint centerStartVector = twoPointVector( m_Pos, m_ArcStart );
550  wxPoint centerEndVector = twoPointVector( m_Pos, m_ArcEnd );
551 
552  m_Radius = KiROUND( EuclideanNorm( centerStartVector ) );
553 
554  // Angles in eeschema are still integers
555  m_t1 = KiROUND( ArcTangente( centerStartVector.y, centerStartVector.x ) );
556  m_t2 = KiROUND( ArcTangente( centerEndVector.y, centerEndVector.x ) );
557 
559  NORMALIZE_ANGLE_POS( m_t2 ); // angles = 0 .. 3600
560 
561  // Restrict angle to less than 180 to avoid PBS display mirror Trace because it is
562  // assumed that the arc is less than 180 deg to find orientation after rotate or mirror.
563  if( (m_t2 - m_t1) > 1800 )
564  m_t2 -= 3600;
565  else if( (m_t2 - m_t1) <= -1800 )
566  m_t2 += 3600;
567 
568  while( (m_t2 - m_t1) >= 1800 )
569  {
570  m_t2--;
571  m_t1++;
572  }
573 
574  while( (m_t1 - m_t2) >= 1800 )
575  {
576  m_t2++;
577  m_t1--;
578  }
579 
581 
582  if( !IsMoving() )
584 }
585 
586 
588 {
589  VECTOR2D midPoint;
590  double startAngle = static_cast<double>( m_t1 ) / 10.0;
591  double endAngle = static_cast<double>( m_t2 ) / 10.0;
592 
593  if( endAngle < startAngle )
594  endAngle -= 360.0;
595 
596  double midPointAngle = ( ( endAngle - startAngle ) / 2.0 ) + startAngle;
597  double x = cos( DEG2RAD( midPointAngle ) ) * m_Radius;
598  double y = sin( DEG2RAD( midPointAngle ) ) * m_Radius;
599 
600  midPoint.x = KiROUND( x ) + m_Pos.x;
601  midPoint.y = KiROUND( y ) + m_Pos.y;
602 
603  return midPoint;
604 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:128
int m_Radius
Definition: lib_arc.h:44
EDA_UNITS
Definition: common.h:198
void Rotate(const wxPoint &aCenter, bool aRotateCCW=true) override
Rotate the object about aCenter point.
Definition: lib_arc.cpp:234
static wxPoint twoPointVector(const wxPoint &startPoint, const wxPoint &endPoint)
Definition: lib_arc.cpp:44
int m_t1
Definition: lib_arc.h:45
void Plot(PLOTTER *aPlotter, const wxPoint &aOffset, bool aFill, const TRANSFORM &aTransform) override
Plot the draw item using the plot object.
Definition: lib_arc.cpp:256
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:206
PNG memory record (file in memory).
Definition: bitmap_def.h:29
RENDER_SETTINGS Contains all the knowledge about how graphical objects are drawn on any output surfac...
Implementation of conversion functions that require both schematic and board internal units.
virtual void SetColor(COLOR4D color)=0
int m_t2
Definition: lib_arc.h:46
#define SKIP_STRUCT
flag indicating that the structure should be ignored
Definition: base_struct.h:128
bool IsMoving() const
Definition: base_struct.h:200
int color
Definition: DXF_plotter.cpp:61
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: lib_arc.cpp:338
FILL_T GetFillMode() const
Definition: lib_item.h:301
Definition: color4d.h:61
const COLOR4D & GetLayerColor(int aLayer) const
Function GetLayerColor Returns the color used to draw a layer.
TRANSFORM DefaultTransform
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:131
bool IntersectsCircleEdge(const wxPoint &aCenter, const int aRadius, const int aWidth) const
IntersectsCircleEdge Tests for intersection between this rect and the edge (radius) of a circle.
void CalcRadiusAngles()
Calculate the radius and angle of an arc using the start, end, and center points.
Definition: lib_arc.cpp:547
EDA_RECT Common(const EDA_RECT &aRect) const
Function Common returns the area that is common with another rectangle.
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Definition: lib_arc.cpp:428
VECTOR2I CalcMidPoint() const
Calculate the arc mid point using the arc start and end angles and radius length.
Definition: lib_arc.cpp:587
wxPoint m_ArcEnd
Definition: lib_arc.h:48
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:257
The base class for create windows for drawing purpose.
bool Contains(const wxPoint &aPoint) const
Function Contains.
wxPoint TransformCoordinate(const wxPoint &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:42
The base class for drawable items used by schematic library components.
Definition: lib_item.h:61
void MirrorVertical(const wxPoint &aCenter) override
Mirror the draw object along the MirrorVertical (Y) axis about aCenter point.
Definition: lib_arc.cpp:207
This file contains miscellaneous commonly used macros and functions.
const wxPoint GetEnd() const
Definition: eda_rect.h:116
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
#define NULL
COMPARE_FLAGS
The list of flags used by the compare function.
Definition: lib_item.h:116
wxPoint m_Pos
Definition: lib_arc.h:49
const wxPoint GetOrigin() const
Definition: eda_rect.h:114
const wxPoint GetPosition() const override
Definition: lib_arc.h:90
void SetEnd(int x, int y)
Definition: eda_rect.h:192
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: lib_arc.cpp:130
#define MINIMUM_SELECTION_DISTANCE
Definition: lib_item.h:47
bool m_isFillable
Definition: lib_item.h:94
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
Definition: lib_arc.cpp:62
void print(RENDER_SETTINGS *aSettings, const wxPoint &aOffset, void *aData, const TRANSFORM &aTransform) override
Print the item to aDC.
Definition: lib_arc.cpp:296
Define a library symbol object.
void MoveTo(const wxPoint &aPosition) override
Move a draw object to aPosition.
Definition: lib_arc.cpp:171
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:126
int m_editState
Definition: lib_arc.h:51
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: lib_arc.cpp:401
double CrossProduct(const wxPoint &vectorA, const wxPoint &vectorB)
Determine the cross product.
Definition: trigo.h:182
const BITMAP_OPAQUE add_arc_xpm[1]
Definition: add_arc.cpp:37
void CalcEdit(const wxPoint &aPosition) override
Calculates the attributes of an item at aPosition when it is being edited.
Definition: lib_arc.cpp:441
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
Definition: lib_item.cpp:52
void GRFilledArc(EDA_RECT *ClipBox, wxDC *DC, int x, int y, double StAngle, double EndAngle, int r, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:689
void MirrorHorizontal(const wxPoint &aCenter) override
Mirror the draw object along the horizontal (X) axis about aCenter point.
Definition: lib_arc.cpp:180
int GetRadius() const
Definition: lib_arc.h:103
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:124
Base plotter engine class.
Definition: plotter.h:114
Definition: color4d.h:56
int GetWidth() const override
Definition: lib_arc.h:99
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:147
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
double DEG2RAD(double deg)
Definition: trigo.h:214
int GetPenWidth() const override
Definition: lib_arc.cpp:286
#define _(s)
Definition: 3d_actions.cpp:33
FILL_T m_Fill
The body fill type.
Definition: lib_item.h:93
LIB_ARC(LIB_PART *aParent)
Definition: lib_arc.cpp:50
bool HitTestPoints(const wxPoint &pointA, const wxPoint &pointB, double threshold)
Test, if two points are near each other.
Definition: trigo.h:166
STATUS_FLAGS m_Flags
Definition: base_struct.h:176
void Offset(const wxPoint &aOffset) override
Set the drawing object by aOffset from the current position.
Definition: lib_arc.cpp:163
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
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:68
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
virtual void Arc(const wxPoint &centre, double StAngle, double EndAngle, int rayon, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)
Generic fallback: arc rendered as a polyline.
Definition: plotter.cpp:158
int GetDefaultPenWidth() const
int compare(const LIB_ITEM &aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags=LIB_ITEM::COMPARE_FLAGS::NORMAL) const override
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_arc.cpp:136
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: lib_arc.cpp:419
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:162
bool MapAngles(int *aAngle1, int *aAngle2) const
Calculate new angles according to the transform.
Definition: transform.cpp:81
#define sq(x)
wxPoint m_ArcStart
Definition: lib_arc.h:47
Message panel definition file.
void BeginEdit(const wxPoint aStartPoint) override
Begin drawing a component library draw item at aPosition.
Definition: lib_arc.cpp:434
virtual int compare(const LIB_ITEM &aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags=LIB_ITEM::COMPARE_FLAGS::NORMAL) const
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_item.cpp:76
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
int m_Width
Definition: lib_arc.h:50
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
void GRArc1(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int xc, int yc, COLOR4D Color)
Definition: gr_basic.cpp:640
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:99