41 m_endsSwapped( false ),
47 m_annotationProxy( false )
60 return _(
"Number Box" );
64 case SHAPE_T::SEGMENT:
return _(
"Line" );
65 case SHAPE_T::RECT:
return _(
"Rect" );
66 case SHAPE_T::ARC:
return _(
"Arc" );
67 case SHAPE_T::CIRCLE:
return _(
"Circle" );
68 case SHAPE_T::BEZIER:
return _(
"Bezier Curve" );
69 case SHAPE_T::POLY:
return _(
"Polygon" );
70 default:
return wxT(
"??" );
79 case SHAPE_T::SEGMENT:
return wxS(
"S_SEGMENT" );
80 case SHAPE_T::RECT:
return wxS(
"S_RECT" );
81 case SHAPE_T::ARC:
return wxS(
"S_ARC" );
82 case SHAPE_T::CIRCLE:
return wxS(
"S_CIRCLE" );
83 case SHAPE_T::POLY:
return wxS(
"S_POLYGON" );
84 case SHAPE_T::BEZIER:
return wxS(
"S_CURVE" );
85 case SHAPE_T::LAST:
return wxS(
"!S_LAST!" );
103 else if(
m_shape == SHAPE_T::POLY )
116 case SHAPE_T::BEZIER:
122 case SHAPE_T::SEGMENT:
145 case SHAPE_T::CIRCLE:
150 case SHAPE_T::SEGMENT:
159 case SHAPE_T::BEZIER:
178 case SHAPE_T::SEGMENT:
180 case SHAPE_T::CIRCLE:
182 m_end += aMoveVector;
190 case SHAPE_T::BEZIER:
192 m_end += aMoveVector;
212 pt.x =
KiROUND( pt.x * aScale );
213 pt.y =
KiROUND( pt.y * aScale );
219 case SHAPE_T::SEGMENT:
226 case SHAPE_T::CIRCLE:
234 std::vector<VECTOR2I> pts;
240 pts.emplace_back( pt );
241 scalePt( pts.back() );
249 case SHAPE_T::BEZIER:
267 case SHAPE_T::SEGMENT:
268 case SHAPE_T::CIRCLE:
302 case SHAPE_T::BEZIER:
324 case SHAPE_T::SEGMENT:
340 case SHAPE_T::CIRCLE:
371 m_poly.
Mirror( aFlipLeftRight, !aFlipLeftRight, aCentre );
374 case SHAPE_T::BEZIER:
408 if(
m_shape != SHAPE_T::BEZIER )
433 std::vector<VECTOR2I> bezierPoints;
438 converter.
GetPoly( bezierPoints, aMinSegLen );
451 case SHAPE_T::CIRCLE:
454 case SHAPE_T::SEGMENT:
460 case SHAPE_T::BEZIER:
478 case SHAPE_T::CIRCLE:
510 if( aEndAngle == aStartAngle )
513 if( aStartAngle > aEndAngle )
533 case SHAPE_T::CIRCLE:
542 return std::max( 1,
KiROUND( radius ) );
592 return endAngle - startAngle;
603 if( aCheckNegativeAngle && aAngle <
ANGLE_0 )
615 case SHAPE_T::CIRCLE:
return _(
"Circle" );
616 case SHAPE_T::ARC:
return _(
"Arc" );
617 case SHAPE_T::BEZIER:
return _(
"Curve" );
618 case SHAPE_T::POLY:
return _(
"Polygon" );
620 case SHAPE_T::SEGMENT:
return _(
"Segment" );
621 default:
return _(
"Unrecognized" );
631 wxString shape =
_(
"Shape" );
636 case SHAPE_T::CIRCLE:
642 aList.emplace_back(
_(
"Angle" ), msg );
647 case SHAPE_T::BEZIER:
652 msg.Printf( wxS(
"%d" ),
GetPolyShape().Outline(0).PointCount() );
653 aList.emplace_back(
_(
"Points" ), msg );
657 aList.emplace_back(
_(
"Width" ),
660 aList.emplace_back(
_(
"Height" ),
664 case SHAPE_T::SEGMENT:
666 aList.emplace_back(
_(
"Length" ),
696 case SHAPE_T::SEGMENT:
701 case SHAPE_T::CIRCLE:
719 case SHAPE_T::BEZIER:
740 int maxdist = aAccuracy;
747 case SHAPE_T::CIRCLE:
755 return dist <= radius + maxdist;
757 return abs( radius - dist ) <= maxdist;
772 KiROUND<double, VECTOR2I::extended_type>(
EuclideanNorm( relPos ) );
777 if( dist > radius + maxdist )
783 if( abs( radius - dist ) > maxdist )
798 if( endAngle > startAngle )
799 return relPosAngle >= startAngle && relPosAngle <= endAngle;
801 return relPosAngle >= startAngle || relPosAngle <= endAngle;
804 case SHAPE_T::BEZIER:
815 case SHAPE_T::SEGMENT:
827 return poly.
Collide( aPosition, maxdist );
862 case SHAPE_T::CIRCLE:
918 case SHAPE_T::SEGMENT:
950 for(
int jj = 0; jj < count; jj++ )
980 case SHAPE_T::BEZIER:
996 for(
unsigned ii = 1; ii < count; ii++ )
1022 std::vector<VECTOR2I> pts;
1026 pts.emplace_back( topLeft );
1027 pts.emplace_back( botRight.
x, topLeft.
y );
1028 pts.emplace_back( botRight );
1029 pts.emplace_back( topLeft.
x, botRight.
y );
1056 if( t1 < ANGLE_0 && t2 >
ANGLE_0 )
1059 if( t1 < ANGLE_90 && t2 >
ANGLE_90 )
1070 if( t1 < ANGLE_0 || t2 >
ANGLE_0 )
1073 if( t1 < ANGLE_90 || t2 >
ANGLE_90 )
1097 std::vector<SHAPE*> effectiveShapes;
1106 case SHAPE_T::SEGMENT:
1115 effectiveShapes.emplace_back(
new SHAPE_SIMPLE( pts ) );
1117 if( width > 0 || !
IsFilled() || aEdgeOnly )
1119 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[0], pts[1], width ) );
1120 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[1], pts[2], width ) );
1121 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[2], pts[3], width ) );
1122 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[3], pts[0], width ) );
1127 case SHAPE_T::CIRCLE:
1132 if( width > 0 || !
IsFilled() || aEdgeOnly )
1138 case SHAPE_T::BEZIER:
1141 VECTOR2I start_pt = bezierPoints[0];
1143 for(
unsigned int jj = 1; jj < bezierPoints.size(); jj++ )
1145 VECTOR2I end_pt = bezierPoints[jj];
1146 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( start_pt, end_pt, width ) );
1162 if( aLineChainOnly )
1168 if( width > 0 || !
IsFilled() || aEdgeOnly )
1182 return effectiveShapes;
1194 aBuffer.reserve( pointCount );
1197 aBuffer.emplace_back( iter->x, iter->y );
1230 case SHAPE_T::SEGMENT:
1231 case SHAPE_T::CIRCLE:
1262 case SHAPE_T::SEGMENT:
1263 case SHAPE_T::CIRCLE:
1273 poly.
Append( aPosition,
true );
1286#define sq( x ) pow( x, 2 )
1290 case SHAPE_T::SEGMENT:
1291 case SHAPE_T::CIRCLE:
1322 double chordBefore =
sq( v.
x ) +
sq( v.
y );
1330 double chordAfter =
sq( v.
x ) +
sq( v.
y );
1331 double ratio = chordAfter / chordBefore;
1335 radius = std::max(
int( sqrt(
sq( radius ) * ratio ) ) + 1,
1336 int( sqrt( chordAfter ) / 2 ) + 1 );
1345 radius = int( ( radialA + radialB ) / 2.0 ) + 1;
1419 case SHAPE_T::SEGMENT:
1420 case SHAPE_T::CIRCLE:
1451 #define SWAPITEM( x ) std::swap( x, image->x )
1473#define TEST( a, b ) { if( a != b ) return a - b; }
1474#define TEST_E( a, b ) { if( abs( a - b ) > EPSILON ) return a - b; }
1475#define TEST_PT( a, b ) { TEST_E( a.x, b.x ); TEST_E( a.y, b.y ); }
1486 else if(
m_shape == SHAPE_T::BEZIER )
1491 else if(
m_shape == SHAPE_T::POLY )
1511 ERROR_LOC aErrorLoc,
bool ignoreLineWidth )
const
1513 int width = ignoreLineWidth ? 0 :
GetWidth();
1515 width += 2 * aClearance;
1519 case SHAPE_T::CIRCLE:
1559 case SHAPE_T::SEGMENT:
1587 for(
int jj = 0; jj < (int) poly.
SegmentCount(); ++jj )
1598 case SHAPE_T::BEZIER:
1602 std::vector<VECTOR2I> poly;
1605 for(
unsigned ii = 1; ii < poly.size(); ii++ )
1680 angle->SetAvailableFunc(
1689 filled->SetAvailableFunc(
1698 catch( std::runtime_error& err )
1700 wxFAIL_MSG( err.what() );
Bezier curves to polygon converter.
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMinSegLen=0, int aMaxSegCount=32)
Convert a Bezier curve to a polygon.
void SetOrigin(const Vec &pos)
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
bool Intersects(const BOX2< Vec > &aRect) const
bool IntersectsCircleEdge(const Vec &aCenter, const int aRadius, const int aWidth) const
bool Contains(const Vec &aPoint) const
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
void SetEnd(coord_type x, coord_type y)
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
ORIGIN_TRANSFORMS & GetOriginTransforms() override
Return a reference to the default ORIGIN_TRANSFORMS object.
The base class for create windows for drawing purpose.
EDA_ANGLE GetArcAngle() const
wxString GetFriendlyName() const
const VECTOR2I & GetBezierC2() const
void move(const VECTOR2I &aMoveVector)
void SetCenter(const VECTOR2I &aCenter)
VECTOR2I getCenter() const
void rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
void flip(const VECTOR2I &aCentre, bool aFlipLeftRight)
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
virtual int GetEffectiveWidth() const
const std::vector< VECTOR2I > buildBezierToSegmentsPointsList(int aMinSegLen) const
void calcEdit(const VECTOR2I &aPosition)
SHAPE_POLY_SET & GetPolyShape()
void CalcArcAngles(EDA_ANGLE &aStartAngle, EDA_ANGLE &aEndAngle) const
Calc arc start and end angles such that aStartAngle < aEndAngle.
void ShapeGetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
void SetFilled(bool aFlag)
bool continueEdit(const VECTOR2I &aPosition)
wxString ShowShape() const
std::vector< SHAPE * > makeEffectiveShapes(bool aEdgeOnly, bool aLineChainOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
bool hitTest(const VECTOR2I &aPosition, int aAccuracy=0) const
void SetCachedArcData(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, const VECTOR2I &aCenter)
Set the data used for mid point caching.
EDA_SHAPE(SHAPE_T aType, int aLineWidth, FILL_T aFill)
void beginEdit(const VECTOR2I &aStartPoint)
int GetPointCount() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
void DupPolyPointsList(std::vector< VECTOR2I > &aBuffer) const
Duplicate the list of corners in a std::vector<VECTOR2I>
void endEdit(bool aClosed=true)
Finishes editing the shape.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SwapShape(EDA_SHAPE *aImage)
std::vector< VECTOR2I > GetRectCorners() const
std::vector< VECTOR2I > m_bezierPoints
void setPosition(const VECTOR2I &aPos)
void computeArcBBox(BOX2I &aBBox) const
void SetEnd(const VECTOR2I &aEnd)
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
double GetLength() const
Return the length of the track using the hypotenuse calculation.
wxString SHAPE_T_asString() const
void scale(double aScale)
const VECTOR2I & GetBezierC1() const
const BOX2I getBoundingBox() const
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
VECTOR2I getPosition() const
bool IsAnnotationProxy() const
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the shape to a closed polygon.
void SetWidth(int aWidth)
bool IsPolyShapeValid() const
int Compare(const EDA_SHAPE *aOther) const
VECTOR2I GetArcMid() const
static ENUM_MAP< T > & Instance()
Class that other classes need to inherit from, in order to be inspectable.
wxAny Get(PROPERTY_BASE *aProperty) const
A color representation with 4 components: red, green, blue, alpha.
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
Provide class metadata.Helper macro to map type hashes to names.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
int Length() const
Return the length (this).
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
bool IsClosed() const override
virtual const VECTOR2I GetPoint(int aIndex) const override
void SetPoint(int aIndex, const VECTOR2I &aPos)
Move a point to a specific location.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
virtual size_t GetPointCount() const override
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
virtual const SEG GetSegment(int aIndex) const override
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
const std::vector< VECTOR2I > & CPoints() const
SEG Segment(int aIndex)
Return a copy of the aIndex-th segment in the line chain.
Represent a set of closed polygons.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
void RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
bool CollideEdge(const VECTOR2I &aPoint, VERTEX_INDEX *aClosestVertex=nullptr, int aClearance=0) const
Check whether aPoint collides with any edge of any of the contours of the polygon.
int VertexCount(int aOutline=-1, int aHole=-1) const
Return the number of vertices in a given outline/hole.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
int TotalVertices() const
Return total number of vertices stored in the set.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
int OutlineCount() const
Return the number of outlines in the set.
void Move(const VECTOR2I &aVector) override
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
void GetMsgPanelInfo(UNITS_PROVIDER *aUnitsProvider, std::vector< MSG_PANEL_ITEM > &aList, bool aIncludeStyle=true, bool aIncludeWidth=true)
PLOT_DASH_TYPE GetPlotStyle() const
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A lower-precision version of StringFromValue().
extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
VECTOR2_TRAITS< int >::extended_type extended_type
void TransformRingToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aCentre, int aRadius, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arcs to multiple straight segments.
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
void TransformArcToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arc to multiple straight segments.
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
static constexpr EDA_ANGLE & ANGLE_180
static constexpr EDA_ANGLE & ANGLE_360
static constexpr EDA_ANGLE & ANGLE_90
static constexpr EDA_ANGLE & ANGLE_0
static constexpr EDA_ANGLE & ANGLE_270
static struct EDA_SHAPE_DESC _EDA_SHAPE_DESC
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
#define UNIMPLEMENTED_FOR(type)
wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
#define NO_SETTER(owner, type)
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
@ PT_COORD
Coordinate expressed in distance units (mm/inch)
@ PT_DECIDEGREE
Angle expressed in decidegrees.
@ PT_SIZE
Size expressed in distance units (mm/inch)
PLOT_DASH_TYPE
Dashed line types.
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
double GetLineLength(const VECTOR2I &aPointA, const VECTOR2I &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
double EuclideanNorm(const VECTOR2I &vector)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".