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()->GetMinPenWidth() );
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  return rect;
348 
352  angleStart = m_t1;
353  angleEnd = m_t2;
354 
355  if( DefaultTransform.MapAngles( &angleStart, &angleEnd ) )
356  {
357  std::swap( endPos.x, startPos.x );
358  std::swap( endPos.y, startPos.y );
359  }
360 
361  /* Start with the start and end point of the arc. */
362  minX = std::min( startPos.x, endPos.x );
363  minY = std::min( startPos.y, endPos.y );
364  maxX = std::max( startPos.x, endPos.x );
365  maxY = std::max( startPos.y, endPos.y );
366 
367  /* Zero degrees is a special case. */
368  if( angleStart == 0 )
369  maxX = centerPos.x + m_Radius;
370 
371  /* Arc end angle wrapped passed 360. */
372  if( angleStart > angleEnd )
373  angleEnd += 3600;
374 
375  if( angleStart <= 900 && angleEnd >= 900 ) /* 90 deg */
376  maxY = centerPos.y + m_Radius;
377 
378  if( angleStart <= 1800 && angleEnd >= 1800 ) /* 180 deg */
379  minX = centerPos.x - m_Radius;
380 
381  if( angleStart <= 2700 && angleEnd >= 2700 ) /* 270 deg */
382  minY = centerPos.y - m_Radius;
383 
384  if( angleStart <= 3600 && angleEnd >= 3600 ) /* 0 deg */
385  maxX = centerPos.x + m_Radius;
386 
387  rect.SetOrigin( minX, minY );
388  rect.SetEnd( maxX, maxY );
389  rect.Inflate( ( GetPenWidth() / 2 ) + 1 );
390 
391  return rect;
392 }
393 
394 
395 void LIB_ARC::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
396 {
397  wxString msg;
398  EDA_RECT bBox = GetBoundingBox();
399 
400  LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
401 
402  msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Width, true );
403 
404  aList.emplace_back( _( "Line Width" ), msg, BLUE );
405 
406  msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
407  bBox.GetOrigin().y, bBox.GetEnd().x, bBox.GetEnd().y );
408 
409  aList.emplace_back( _( "Bounding Box" ), msg, BROWN );
410 }
411 
412 
413 wxString LIB_ARC::GetSelectMenuText( EDA_UNITS aUnits ) const
414 {
415  return wxString::Format( _( "Arc center (%s, %s), radius %s" ),
416  MessageTextFromValue( aUnits, m_Pos.x ),
417  MessageTextFromValue( aUnits, m_Pos.y ),
418  MessageTextFromValue( aUnits, m_Radius ) );
419 }
420 
421 
423 {
424  return add_arc_xpm;
425 }
426 
427 
428 void LIB_ARC::BeginEdit( const wxPoint aPosition )
429 {
430  m_ArcStart = m_ArcEnd = aPosition;
431  m_editState = 1;
432 }
433 
434 
435 void LIB_ARC::CalcEdit( const wxPoint& aPosition )
436 {
437 #define sq( x ) pow( x, 2 )
438 
439  // Edit state 0: drawing: place ArcStart
440  // Edit state 1: drawing: place ArcEnd (center calculated for 90-degree subtended angle)
441  // Edit state 2: point editing: move ArcStart (center calculated for invariant subtended angle)
442  // Edit state 3: point editing: move ArcEnd (center calculated for invariant subtended angle)
443  // Edit state 4: point editing: move center
444 
445  switch( m_editState )
446  {
447  case 0:
448  m_ArcStart = aPosition;
449  m_ArcEnd = aPosition;
450  m_Pos = aPosition;
451  m_Radius = 0;
452  m_t1 = 0;
453  m_t2 = 0;
454  return;
455 
456  case 1:
457  m_ArcEnd = aPosition;
458  m_Radius = KiROUND( sqrt( pow( GetLineLength( m_ArcStart, m_ArcEnd ), 2 ) / 2.0 ) );
459  break;
460 
461  case 2:
462  case 3:
463  {
465  double chordBefore = sq( v.x ) + sq( v.y );
466 
467  if( m_editState == 2 )
468  m_ArcStart = aPosition;
469  else
470  m_ArcEnd = aPosition;
471 
472  v = m_ArcStart - m_ArcEnd;
473  double chordAfter = sq( v.x ) + sq( v.y );
474  double ratio = chordAfter / chordBefore;
475 
476  if( ratio > 0 )
477  {
478  m_Radius = int( sqrt( m_Radius * m_Radius * ratio ) ) + 1;
479  m_Radius = std::max( m_Radius, int( sqrt( chordAfter ) / 2 ) + 1 );
480  }
481 
482  break;
483  }
484 
485  case 4:
486  {
487  double chordA = GetLineLength( m_ArcStart, aPosition );
488  double chordB = GetLineLength( m_ArcEnd, aPosition );
489  m_Radius = int( ( chordA + chordB ) / 2.0 ) + 1;
490  break;
491  }
492  }
493 
494  // Calculate center based on start, end, and radius
495  //
496  // Let 'l' be the length of the chord and 'm' the middle point of the chord
497  double l = GetLineLength( m_ArcStart, m_ArcEnd );
498  wxPoint m = ( m_ArcStart + m_ArcEnd ) / 2;
499 
500  // Calculate 'd', the vector from the chord midpoint to the center
501  wxPoint d;
502  d.x = KiROUND( sqrt( sq( m_Radius ) - sq( l/2 ) ) * ( m_ArcStart.y - m_ArcEnd.y ) / l );
503  d.y = KiROUND( sqrt( sq( m_Radius ) - sq( l/2 ) ) * ( m_ArcEnd.x - m_ArcStart.x ) / l );
504 
505  wxPoint c1 = m + d;
506  wxPoint c2 = m - d;
507 
508  // Solution gives us 2 centers; we need to pick one:
509  switch( m_editState )
510  {
511  case 1:
512  {
513  // Keep center clockwise from chord while drawing
514  wxPoint chordVector = twoPointVector( m_ArcStart, m_ArcEnd );
515  double chordAngle = ArcTangente( chordVector.y, chordVector.x );
516  NORMALIZE_ANGLE_POS( chordAngle );
517 
518  wxPoint c1Test = c1;
519  RotatePoint( &c1Test, m_ArcStart, -chordAngle );
520 
521  m_Pos = c1Test.x > 0 ? c2 : c1;
522  }
523  break;
524 
525  case 2:
526  case 3:
527  // Pick the one closer to the old center
528  m_Pos = ( GetLineLength( c1, m_Pos ) < GetLineLength( c2, m_Pos ) ) ? c1 : c2;
529  break;
530 
531  case 4:
532  // Pick the one closer to the mouse position
533  m_Pos = ( GetLineLength( c1, aPosition ) < GetLineLength( c2, aPosition ) ) ? c1 : c2;
534  break;
535  }
536 
538 }
539 
540 
542 {
543  wxPoint centerStartVector = twoPointVector( m_Pos, m_ArcStart );
544  wxPoint centerEndVector = twoPointVector( m_Pos, m_ArcEnd );
545 
546  m_Radius = KiROUND( EuclideanNorm( centerStartVector ) );
547 
548  // Angles in eeschema are still integers
549  m_t1 = KiROUND( ArcTangente( centerStartVector.y, centerStartVector.x ) );
550  m_t2 = KiROUND( ArcTangente( centerEndVector.y, centerEndVector.x ) );
551 
553  NORMALIZE_ANGLE_POS( m_t2 ); // angles = 0 .. 3600
554 
555  // Restrict angle to less than 180 to avoid PBS display mirror Trace because it is
556  // assumed that the arc is less than 180 deg to find orientation after rotate or mirror.
557  if( (m_t2 - m_t1) > 1800 )
558  m_t2 -= 3600;
559  else if( (m_t2 - m_t1) <= -1800 )
560  m_t2 += 3600;
561 
562  while( (m_t2 - m_t1) >= 1800 )
563  {
564  m_t2--;
565  m_t1++;
566  }
567 
568  while( (m_t1 - m_t2) >= 1800 )
569  {
570  m_t2++;
571  m_t1--;
572  }
573 
575 
576  if( !IsMoving() )
578 }
579 
580 
582 {
583  VECTOR2D midPoint;
584  double startAngle = static_cast<double>( m_t1 ) / 10.0;
585  double endAngle = static_cast<double>( m_t2 ) / 10.0;
586 
587  if( endAngle < startAngle )
588  endAngle -= 360.0;
589 
590  double midPointAngle = ( ( endAngle - startAngle ) / 2.0 ) + startAngle;
591  double x = cos( DEG2RAD( midPointAngle ) ) * m_Radius;
592  double y = sin( DEG2RAD( midPointAngle ) ) * m_Radius;
593 
594  midPoint.x = KiROUND( x ) + m_Pos.x;
595  midPoint.y = KiROUND( y ) + m_Pos.y;
596 
597  return midPoint;
598 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:133
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:211
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:541
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:422
VECTOR2I CalcMidPoint() const
Calculate the arc mid point using the arc start and end angles and radius length.
Definition: lib_arc.cpp:581
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:276
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
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:395
double CrossProduct(const wxPoint &vectorA, const wxPoint &vectorB)
Determine the cross product.
Definition: trigo.h:187
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:435
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:691
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:201
double DEG2RAD(double deg)
Definition: trigo.h:219
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:171
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:413
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:428
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
wxPoint GetPosition() const override
Definition: lib_arc.h:90
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:642
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:99