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 <sch_draw_panel.h>
27 #include <plotter.h>
28 #include <trigo.h>
29 #include <base_units.h>
30 #include <widgets/msgpanel.h>
31 #include <bitmaps.h>
32 #include <math/util.h> // for KiROUND
33 #include <eda_draw_frame.h>
34 #include <general.h>
35 #include <lib_arc.h>
36 #include <transform.h>
38 #include <status_popup.h>
39 
40 // Helper function
41 static inline wxPoint twoPointVector( const wxPoint &startPoint, const wxPoint &endPoint )
42 {
43  return endPoint - startPoint;
44 }
45 
46 
47 LIB_ARC::LIB_ARC( LIB_PART* aParent ) : LIB_ITEM( LIB_ARC_T, aParent )
48 {
49  m_Radius = 0;
50  m_t1 = 0;
51  m_t2 = 0;
52  m_Width = 0;
54  m_isFillable = true;
55  m_editState = 0;
56 }
57 
58 
59 bool LIB_ARC::HitTest( const wxPoint& aRefPoint, int aAccuracy ) const
60 {
61  int mindist = std::max( aAccuracy + GetPenWidth() / 2,
62  Mils2iu( MINIMUM_SELECTION_DISTANCE ) );
63  wxPoint relativePosition = aRefPoint;
64 
65  relativePosition.y = -relativePosition.y; // reverse Y axis
66 
67  int distance = KiROUND( GetLineLength( m_Pos, relativePosition ) );
68 
69  if( abs( distance - m_Radius ) > mindist )
70  return false;
71 
72  // We are on the circle, ensure we are only on the arc, i.e. between
73  // m_ArcStart and m_ArcEnd
74 
75  wxPoint startEndVector = twoPointVector( m_ArcStart, m_ArcEnd );
76  wxPoint startRelativePositionVector = twoPointVector( m_ArcStart, relativePosition );
77 
78  wxPoint centerStartVector = twoPointVector( m_Pos, m_ArcStart );
79  wxPoint centerEndVector = twoPointVector( m_Pos, m_ArcEnd );
80  wxPoint centerRelativePositionVector = twoPointVector( m_Pos, relativePosition );
81 
82  // Compute the cross product to check if the point is in the sector
83  double crossProductStart = CrossProduct( centerStartVector, centerRelativePositionVector );
84  double crossProductEnd = CrossProduct( centerEndVector, centerRelativePositionVector );
85 
86  // The cross products need to be exchanged, depending on which side the center point
87  // relative to the start point to end point vector lies
88  if( CrossProduct( startEndVector, startRelativePositionVector ) < 0 )
89  {
90  std::swap( crossProductStart, crossProductEnd );
91  }
92 
93  // When the cross products have a different sign, the point lies in sector
94  // also check, if the reference is near start or end point
95  return HitTestPoints( m_ArcStart, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
96  HitTestPoints( m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
97  ( crossProductStart <= 0 && crossProductEnd >= 0 );
98 }
99 
100 
101 bool LIB_ARC::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
102 {
103  if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) )
104  return false;
105 
106  wxPoint center = DefaultTransform.TransformCoordinate( GetPosition() );
107  int radius = GetRadius();
108  int lineWidth = GetWidth();
109  EDA_RECT sel = aRect ;
110 
111  if ( aAccuracy )
112  sel.Inflate( aAccuracy );
113 
114  if( aContained )
115  return sel.Contains( GetBoundingBox() );
116 
117  EDA_RECT arcRect = GetBoundingBox().Common( sel );
118 
119  /* All following tests must pass:
120  * 1. Rectangle must intersect arc BoundingBox
121  * 2. Rectangle must cross the outside of the arc
122  */
123  return arcRect.Intersects( sel ) && arcRect.IntersectsCircleEdge( center, radius, lineWidth );
124 }
125 
126 
128 {
129  return new LIB_ARC( *this );
130 }
131 
132 
133 int LIB_ARC::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const
134 {
135  wxASSERT( aOther.Type() == LIB_ARC_T );
136 
137  int retv = LIB_ITEM::compare( aOther );
138 
139  if( retv )
140  return retv;
141 
142  const LIB_ARC* tmp = ( LIB_ARC* ) &aOther;
143 
144  if( m_Pos.x != tmp->m_Pos.x )
145  return m_Pos.x - tmp->m_Pos.x;
146 
147  if( m_Pos.y != tmp->m_Pos.y )
148  return m_Pos.y - tmp->m_Pos.y;
149 
150  if( m_t1 != tmp->m_t1 )
151  return m_t1 - tmp->m_t1;
152 
153  if( m_t2 != tmp->m_t2 )
154  return m_t2 - tmp->m_t2;
155 
156  return 0;
157 }
158 
159 
160 void LIB_ARC::Offset( const wxPoint& aOffset )
161 {
162  m_Pos += aOffset;
163  m_ArcStart += aOffset;
164  m_ArcEnd += aOffset;
165 }
166 
167 
168 void LIB_ARC::MoveTo( const wxPoint& aPosition )
169 {
170  wxPoint offset = aPosition - m_Pos;
171  m_Pos = aPosition;
172  m_ArcStart += offset;
173  m_ArcEnd += offset;
174 }
175 
176 
177 void LIB_ARC::MirrorHorizontal( const wxPoint& aCenter )
178 {
179  m_Pos.x -= aCenter.x;
180  m_Pos.x *= -1;
181  m_Pos.x += aCenter.x;
182  m_ArcStart.x -= aCenter.x;
183  m_ArcStart.x *= -1;
184  m_ArcStart.x += aCenter.x;
185  m_ArcEnd.x -= aCenter.x;
186  m_ArcEnd.x *= -1;
187  m_ArcEnd.x += aCenter.x;
188  std::swap( m_ArcStart, m_ArcEnd );
189  std::swap( m_t1, m_t2 );
190  m_t1 = 1800 - m_t1;
191  m_t2 = 1800 - m_t2;
192  if( m_t1 > 3600 || m_t2 > 3600 )
193  {
194  m_t1 -= 3600;
195  m_t2 -= 3600;
196  }
197  else if( m_t1 < -3600 || m_t2 < -3600 )
198  {
199  m_t1 += 3600;
200  m_t2 += 3600;
201  }
202 }
203 
204 void LIB_ARC::MirrorVertical( const wxPoint& aCenter )
205 {
206  m_Pos.y -= aCenter.y;
207  m_Pos.y *= -1;
208  m_Pos.y += aCenter.y;
209  m_ArcStart.y -= aCenter.y;
210  m_ArcStart.y *= -1;
211  m_ArcStart.y += aCenter.y;
212  m_ArcEnd.y -= aCenter.y;
213  m_ArcEnd.y *= -1;
214  m_ArcEnd.y += aCenter.y;
215  std::swap( m_ArcStart, m_ArcEnd );
216  std::swap( m_t1, m_t2 );
217  m_t1 = - m_t1;
218  m_t2 = - m_t2;
219  if( m_t1 > 3600 || m_t2 > 3600 )
220  {
221  m_t1 -= 3600;
222  m_t2 -= 3600;
223  }
224  else if( m_t1 < -3600 || m_t2 < -3600 )
225  {
226  m_t1 += 3600;
227  m_t2 += 3600;
228  }
229 }
230 
231 void LIB_ARC::Rotate( const wxPoint& aCenter, bool aRotateCCW )
232 {
233  int rot_angle = aRotateCCW ? -900 : 900;
234  RotatePoint( &m_Pos, aCenter, rot_angle );
235  RotatePoint( &m_ArcStart, aCenter, rot_angle );
236  RotatePoint( &m_ArcEnd, aCenter, rot_angle );
237  m_t1 -= rot_angle;
238  m_t2 -= rot_angle;
239  if( m_t1 > 3600 || m_t2 > 3600 )
240  {
241  m_t1 -= 3600;
242  m_t2 -= 3600;
243  }
244  else if( m_t1 < -3600 || m_t2 < -3600 )
245  {
246  m_t1 += 3600;
247  m_t2 += 3600;
248  }
249 }
250 
251 
252 
253 void LIB_ARC::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
254  const TRANSFORM& aTransform )
255 {
256  wxASSERT( aPlotter != NULL );
257 
258  int t1 = m_t1;
259  int t2 = m_t2;
260  wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
261 
262  aTransform.MapAngles( &t1, &t2 );
263 
265  {
266  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
267  aPlotter->Arc( pos, -t2, -t1, m_Radius, FILL_TYPE::FILLED_WITH_BG_BODYCOLOR, 0 );
268  }
269 
270  bool already_filled = m_Fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR;
271  int pen_size = GetPenWidth();
272 
273  if( !already_filled || pen_size > 0 )
274  {
275  pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetMinPenWidth() );
276 
277  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) );
278  aPlotter->Arc(
279  pos, -t2, -t1, m_Radius, already_filled ? FILL_TYPE::NO_FILL : m_Fill, pen_size );
280  }
281 }
282 
283 
285 {
286  // Historically 0 meant "default width" and negative numbers meant "don't stroke".
287  if( m_Width < 0 && GetFillMode() != FILL_TYPE::NO_FILL )
288  return 0;
289  else
290  return std::max( m_Width, 1 );
291 }
292 
293 
294 void LIB_ARC::print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData,
295  const TRANSFORM& aTransform )
296 {
297  bool forceNoFill = static_cast<bool>( aData );
298  int penWidth = GetPenWidth();
299 
300  if( forceNoFill && m_Fill != FILL_TYPE::NO_FILL && penWidth == 0 )
301  return;
302 
303  wxDC* DC = aSettings->GetPrintDC();
304  wxPoint pos1, pos2, posc;
305  COLOR4D color = aSettings->GetLayerColor( LAYER_DEVICE );
306 
307  pos1 = aTransform.TransformCoordinate( m_ArcEnd ) + aOffset;
308  pos2 = aTransform.TransformCoordinate( m_ArcStart ) + aOffset;
309  posc = aTransform.TransformCoordinate( m_Pos ) + aOffset;
310  int pt1 = m_t1;
311  int pt2 = m_t2;
312  bool swap = aTransform.MapAngles( &pt1, &pt2 );
313 
314  if( swap )
315  {
316  std::swap( pos1.x, pos2.x );
317  std::swap( pos1.y, pos2.y );
318  }
319 
320  if( forceNoFill || m_Fill == FILL_TYPE::NO_FILL )
321  {
322  penWidth = std::max( penWidth, aSettings->GetDefaultPenWidth() );
323 
324  GRArc1( nullptr, DC, pos1.x, pos1.y, pos2.x, pos2.y, posc.x, posc.y, penWidth, color );
325  }
326  else
327  {
330 
331  GRFilledArc( nullptr, DC, posc.x, posc.y, pt1, pt2, m_Radius, penWidth, color, color );
332  }
333 }
334 
335 
337 {
338  int minX, minY, maxX, maxY, angleStart, angleEnd;
339  EDA_RECT rect;
340  wxPoint nullPoint, startPos, endPos, centerPos;
341  wxPoint normStart = m_ArcStart - m_Pos;
342  wxPoint normEnd = m_ArcEnd - m_Pos;
343 
344  if( ( normStart == nullPoint ) || ( normEnd == nullPoint ) || ( m_Radius == 0 ) )
345  return rect;
346 
350  angleStart = m_t1;
351  angleEnd = m_t2;
352 
353  if( DefaultTransform.MapAngles( &angleStart, &angleEnd ) )
354  {
355  std::swap( endPos.x, startPos.x );
356  std::swap( endPos.y, startPos.y );
357  }
358 
359  /* Start with the start and end point of the arc. */
360  minX = std::min( startPos.x, endPos.x );
361  minY = std::min( startPos.y, endPos.y );
362  maxX = std::max( startPos.x, endPos.x );
363  maxY = std::max( startPos.y, endPos.y );
364 
365  /* Zero degrees is a special case. */
366  if( angleStart == 0 )
367  maxX = centerPos.x + m_Radius;
368 
369  /* Arc end angle wrapped passed 360. */
370  if( angleStart > angleEnd )
371  angleEnd += 3600;
372 
373  if( angleStart <= 900 && angleEnd >= 900 ) /* 90 deg */
374  maxY = centerPos.y + m_Radius;
375 
376  if( angleStart <= 1800 && angleEnd >= 1800 ) /* 180 deg */
377  minX = centerPos.x - m_Radius;
378 
379  if( angleStart <= 2700 && angleEnd >= 2700 ) /* 270 deg */
380  minY = centerPos.y - m_Radius;
381 
382  if( angleStart <= 3600 && angleEnd >= 3600 ) /* 0 deg */
383  maxX = centerPos.x + m_Radius;
384 
385  rect.SetOrigin( minX, minY );
386  rect.SetEnd( maxX, maxY );
387  rect.Inflate( ( GetPenWidth() / 2 ) + 1 );
388 
389  return rect;
390 }
391 
392 
393 void LIB_ARC::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
394 {
395  wxString msg;
396  EDA_RECT bBox = GetBoundingBox();
397 
398  LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
399 
400  msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Width );
401 
402  aList.emplace_back( _( "Line Width" ), msg, BLUE );
403 
404  msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
405  bBox.GetOrigin().y, bBox.GetEnd().x, bBox.GetEnd().y );
406 
407  aList.emplace_back( _( "Bounding Box" ), msg, BROWN );
408 }
409 
410 
411 wxString LIB_ARC::GetSelectMenuText( EDA_UNITS aUnits ) const
412 {
413  return wxString::Format( _( "Arc, radius %s" ),
414  MessageTextFromValue( aUnits, m_Radius ) );
415 }
416 
417 
419 {
420  return add_arc_xpm;
421 }
422 
423 
424 void LIB_ARC::BeginEdit( const wxPoint aPosition )
425 {
426  m_ArcStart = m_ArcEnd = aPosition;
427  m_editState = 1;
428 }
429 
430 
431 void LIB_ARC::CalcEdit( const wxPoint& aPosition )
432 {
433 #define sq( x ) pow( x, 2 )
434 
435  // Edit state 0: drawing: place ArcStart
436  // Edit state 1: drawing: place ArcEnd (center calculated for 90-degree subtended angle)
437  // Edit state 2: point editing: move ArcStart (center calculated for invariant subtended angle)
438  // Edit state 3: point editing: move ArcEnd (center calculated for invariant subtended angle)
439  // Edit state 4: point editing: move center
440 
441  switch( m_editState )
442  {
443  case 0:
444  m_ArcStart = aPosition;
445  m_ArcEnd = aPosition;
446  m_Pos = aPosition;
447  m_Radius = 0;
448  m_t1 = 0;
449  m_t2 = 0;
450  return;
451 
452  case 1:
453  m_ArcEnd = aPosition;
454  m_Radius = KiROUND( sqrt( pow( GetLineLength( m_ArcStart, m_ArcEnd ), 2 ) / 2.0 ) );
455  break;
456 
457  case 2:
458  case 3:
459  {
460  wxPoint v = m_ArcStart - m_ArcEnd;
461  double chordBefore = sq( v.x ) + sq( v.y );
462 
463  if( m_editState == 2 )
464  m_ArcStart = aPosition;
465  else
466  m_ArcEnd = aPosition;
467 
468  v = m_ArcStart - m_ArcEnd;
469  double chordAfter = sq( v.x ) + sq( v.y );
470  double ratio = chordAfter / chordBefore;
471 
472  if( ratio > 0 )
473  {
474  m_Radius = int( sqrt( m_Radius * m_Radius * ratio ) ) + 1;
475  m_Radius = std::max( m_Radius, int( sqrt( chordAfter ) / 2 ) + 1 );
476  }
477 
478  break;
479  }
480 
481  case 4:
482  {
483  double chordA = GetLineLength( m_ArcStart, aPosition );
484  double chordB = GetLineLength( m_ArcEnd, aPosition );
485  m_Radius = int( ( chordA + chordB ) / 2.0 ) + 1;
486  break;
487  }
488  }
489 
490  // Calculate center based on start, end, and radius
491  //
492  // Let 'l' be the length of the chord and 'm' the middle point of the chord
493  double l = GetLineLength( m_ArcStart, m_ArcEnd );
494  wxPoint m = ( m_ArcStart + m_ArcEnd ) / 2;
495 
496  // Calculate 'd', the vector from the chord midpoint to the center
497  wxPoint d;
498  d.x = KiROUND( sqrt( sq( m_Radius ) - sq( l/2 ) ) * ( m_ArcStart.y - m_ArcEnd.y ) / l );
499  d.y = KiROUND( sqrt( sq( m_Radius ) - sq( l/2 ) ) * ( m_ArcEnd.x - m_ArcStart.x ) / l );
500 
501  wxPoint c1 = m + d;
502  wxPoint c2 = m - d;
503 
504  // Solution gives us 2 centers; we need to pick one:
505  switch( m_editState )
506  {
507  case 1:
508  {
509  // Keep center clockwise from chord while drawing
510  wxPoint chordVector = twoPointVector( m_ArcStart, m_ArcEnd );
511  double chordAngle = ArcTangente( chordVector.y, chordVector.x );
512  NORMALIZE_ANGLE_POS( chordAngle );
513 
514  wxPoint c1Test = c1;
515  RotatePoint( &c1Test, m_ArcStart, -chordAngle );
516 
517  m_Pos = c1Test.x > 0 ? c2 : c1;
518  }
519  break;
520 
521  case 2:
522  case 3:
523  // Pick the one closer to the old center
524  m_Pos = ( GetLineLength( c1, m_Pos ) < GetLineLength( c2, m_Pos ) ) ? c1 : c2;
525  break;
526 
527  case 4:
528  // Pick the one closer to the mouse position
529  m_Pos = ( GetLineLength( c1, aPosition ) < GetLineLength( c2, aPosition ) ) ? c1 : c2;
530  break;
531  }
532 
534 }
535 
536 
538 {
539  wxPoint centerStartVector = twoPointVector( m_Pos, m_ArcStart );
540  wxPoint centerEndVector = twoPointVector( m_Pos, m_ArcEnd );
541 
542  m_Radius = KiROUND( EuclideanNorm( centerStartVector ) );
543 
544  // Angles in eeschema are still integers
545  m_t1 = KiROUND( ArcTangente( centerStartVector.y, centerStartVector.x ) );
546  m_t2 = KiROUND( ArcTangente( centerEndVector.y, centerEndVector.x ) );
547 
549  NORMALIZE_ANGLE_POS( m_t2 ); // angles = 0 .. 3600
550 
551  // Restrict angle to less than 180 to avoid PBS display mirror Trace because it is
552  // assumed that the arc is less than 180 deg to find orientation after rotate or mirror.
553  if( (m_t2 - m_t1) > 1800 )
554  m_t2 -= 3600;
555  else if( (m_t2 - m_t1) <= -1800 )
556  m_t2 += 3600;
557 
558  while( (m_t2 - m_t1) >= 1800 )
559  {
560  m_t2--;
561  m_t1++;
562  }
563 
564  while( (m_t1 - m_t2) >= 1800 )
565  {
566  m_t2++;
567  m_t1--;
568  }
569 
571 
572  if( !IsMoving() )
574 }
575 
576 
578 {
579  VECTOR2D midPoint;
580  double startAngle = static_cast<double>( m_t1 ) / 10.0;
581  double endAngle = static_cast<double>( m_t2 ) / 10.0;
582 
583  if( endAngle < startAngle )
584  endAngle -= 360.0;
585 
586  double midPointAngle = ( ( endAngle - startAngle ) / 2.0 ) + startAngle;
587  double x = cos( DEG2RAD( midPointAngle ) ) * m_Radius;
588  double y = sin( DEG2RAD( midPointAngle ) ) * m_Radius;
589 
590  midPoint.x = KiROUND( x ) + m_Pos.x;
591  midPoint.y = KiROUND( y ) + m_Pos.y;
592 
593  return midPoint;
594 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:134
int m_Radius
Definition: lib_arc.h:44
void Rotate(const wxPoint &aCenter, bool aRotateCCW=true) override
Rotate the object about aCenter point.
Definition: lib_arc.cpp:231
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Definition: base_units.cpp:123
static wxPoint twoPointVector(const wxPoint &startPoint, const wxPoint &endPoint)
Definition: lib_arc.cpp:41
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
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:253
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:209
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
bool IsMoving() const
Definition: eda_item.h:188
int color
Definition: DXF_plotter.cpp:60
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: lib_arc.cpp:336
Definition: color4d.h:62
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.
Definition: eda_rect.cpp:330
void CalcRadiusAngles()
Calculate the radius and angle of an arc using the start, end, and center points.
Definition: lib_arc.cpp:537
EDA_RECT Common(const EDA_RECT &aRect) const
Function Common returns the area that is common with another rectangle.
Definition: eda_rect.cpp:487
virtual void Arc(const wxPoint &centre, double StAngle, double EndAngle, int rayon, FILL_TYPE fill, int width=USE_DEFAULT_LINE_WIDTH)
Generic fallback: arc rendered as a polyline.
Definition: plotter.cpp:157
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Definition: lib_arc.cpp:418
VECTOR2I CalcMidPoint() const
Calculate the arc mid point using the arc start and end angles and radius length.
Definition: lib_arc.cpp:577
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:274
The base class for create windows for drawing purpose.
bool Contains(const wxPoint &aPoint) const
Function Contains.
Definition: eda_rect.cpp:57
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:62
void MirrorVertical(const wxPoint &aCenter) override
Mirror the draw object along the MirrorVertical (Y) axis about aCenter point.
Definition: lib_arc.cpp:204
FILL_TYPE m_Fill
The body fill type.
Definition: lib_item.h:94
const wxPoint GetEnd() const
Definition: eda_rect.h:116
FILL_TYPE GetFillMode() const
Definition: lib_item.h:302
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:117
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:127
#define MINIMUM_SELECTION_DISTANCE
Definition: lib_item.h:48
bool m_isFillable
Definition: lib_item.h:95
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:59
void print(RENDER_SETTINGS *aSettings, const wxPoint &aOffset, void *aData, const TRANSFORM &aTransform) override
Print the item to aDC.
Definition: lib_arc.cpp:294
Define a library symbol object.
void MoveTo(const wxPoint &aPosition) override
Move a draw object to aPosition.
Definition: lib_arc.cpp:168
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:393
double CrossProduct(const wxPoint &vectorA, const wxPoint &vectorB)
Determine the cross product.
Definition: trigo.h:186
#define STRUCT_DELETED
flag indication structures to be erased
Definition: eda_item.h:115
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:431
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:50
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:687
void MirrorHorizontal(const wxPoint &aCenter) override
Mirror the draw object along the horizontal (X) axis about aCenter point.
Definition: lib_arc.cpp:177
int GetRadius() const
Definition: lib_arc.h:103
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
EDA_UNITS
Definition: eda_units.h:38
Base plotter engine class.
Definition: plotter.h:131
Definition: color4d.h:57
int GetWidth() const override
Definition: lib_arc.h:99
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:165
double DEG2RAD(double deg)
Definition: trigo.h:217
int GetPenWidth() const override
Definition: lib_arc.cpp:284
#define _(s)
Definition: 3d_actions.cpp:33
LIB_ARC(LIB_PART *aParent)
Definition: lib_arc.cpp:47
bool HitTestPoints(const wxPoint &pointA, const wxPoint &pointB, double threshold)
Test, if two points are near each other.
Definition: trigo.h:172
void Offset(const wxPoint &aOffset) override
Set the drawing object by aOffset from the current position.
Definition: lib_arc.cpp:160
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: eda_item.h:148
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
Definition: eda_rect.cpp:150
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:133
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:411
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 SKIP_STRUCT
flag indicating that the structure should be ignored
Definition: eda_item.h:117
#define sq(x)
wxPoint m_ArcStart
Definition: lib_arc.h:47
STATUS_FLAGS m_flags
Definition: eda_item.h:164
Message panel definition file.
void BeginEdit(const wxPoint aStartPoint) override
Begin drawing a component library draw item at aPosition.
Definition: lib_arc.cpp:424
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:74
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.
Definition: eda_rect.cpp:363
int m_Width
Definition: lib_arc.h:50
KICAD_T Type() const
Function Type()
Definition: eda_item.h:181
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:638
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:100