53#include <api/common/types/base_types.pb.h>
92 switch( aShape.
Type() )
96 auto rect = static_cast<const SHAPE_RECT&>( aShape );
97 m_shape = SHAPE_T::RECTANGLE;
98 SetStart( rect.GetPosition() );
99 SetEnd( rect.GetPosition() + rect.GetSize() );
105 auto seg = static_cast<const SHAPE_SEGMENT&>( aShape );
106 m_shape = SHAPE_T::SEGMENT;
107 SetStart( seg.GetSeg().A );
108 SetEnd( seg.GetSeg().B );
109 SetWidth( seg.GetWidth() );
115 auto line = static_cast<const SHAPE_LINE_CHAIN&>( aShape );
116 m_shape = SHAPE_T::POLY;
117 GetPolyShape() = SHAPE_POLY_SET();
118 GetPolyShape().AddOutline( line );
119 SetWidth( line.Width() );
125 auto circle = static_cast<const SHAPE_CIRCLE&>( aShape );
126 m_shape = SHAPE_T::CIRCLE;
127 SetStart( circle.GetCenter() );
128 SetEnd( circle.GetCenter() + circle.GetRadius() );
134 auto arc = static_cast<const SHAPE_ARC&>( aShape );
135 m_shape = SHAPE_T::ARC;
136 SetArcGeometry( arc.GetP0(), arc.GetArcMid(), arc.GetP1() );
137 SetWidth( arc.GetWidth() );
143 auto poly = static_cast<const SHAPE_SIMPLE&>( aShape );
144 m_shape = SHAPE_T::POLY;
145 poly.TransformToPolygon( GetPolyShape(), 0, ERROR_INSIDE );
151 auto ellipse = static_cast<const SHAPE_ELLIPSE&>( aShape );
152 m_shape = ellipse.IsArc() ? SHAPE_T::ELLIPSE_ARC : SHAPE_T::ELLIPSE;
153 SetEllipseCenter( ellipse.GetCenter() );
154 SetEllipseMajorRadius( ellipse.GetMajorRadius() );
155 SetEllipseMinorRadius( ellipse.GetMinorRadius() );
156 SetEllipseRotation( ellipse.GetRotation() );
158 if( ellipse.IsArc() )
160 SetEllipseStartAngle( ellipse.GetStartAngle() );
161 SetEllipseEndAngle( ellipse.GetEndAngle() );
202 m_poly = std::make_unique<SHAPE_POLY_SET>( *aOther.
m_poly );
208 if(
this == &aOther )
230 m_poly = std::make_unique<SHAPE_POLY_SET>( *aOther.
m_poly );
252 types::GraphicFillAttributes* fill = shape.mutable_attributes()->mutable_fill();
265 types::GraphicSegmentAttributes* segment = shape.mutable_segment();
273 types::GraphicRectangleAttributes* rectangle = shape.mutable_rectangle();
282 types::GraphicArcAttributes* arc = shape.mutable_arc();
291 types::GraphicCircleAttributes*
circle = shape.mutable_circle();
305 types::GraphicBezierAttributes* bezier = shape.mutable_bezier();
315 types::GraphicEllipseAttributes* ellipse = shape.mutable_ellipse();
325 types::GraphicEllipseArcAttributes* arc = shape.mutable_ellipse_arc();
336 wxASSERT_MSG(
false,
"Unhandled shape in EDA_SHAPE::Serialize" );
352 kiapi::common::types::GraphicShape shape;
354 aContainer.PackFrom( shape );
385 if( shape.attributes().has_fill() )
389 if( shape.attributes().fill().has_color() )
393 if( shape.has_segment() )
399 else if( shape.has_rectangle() )
406 else if( shape.has_arc() )
413 else if( shape.has_circle() )
419 else if( shape.has_polygon() )
424 else if( shape.has_bezier() )
433 else if( shape.has_ellipse() )
441 else if( shape.has_ellipse_arc() )
452 if( shape.has_start_ending() )
455 if( shape.has_end_ending() )
463 kiapi::common::types::GraphicShape shape;
465 if( !aContainer.UnpackTo( &shape ) )
480 default:
return wxT(
"??" );
495 default:
return wxT(
"??" );
516 return wxEmptyString;
611 int maxRadius = std::min( width, height ) / 2;
778 std::vector<double> slopes;
788 slopes = { 1.0, -1.0 };
823 for(
int ii = 0; ii < shapeBuffer.
OutlineCount(); ++ii )
843 chain.SetClosed(
true );
863 if( majorAxis / spacing > 100 )
864 spacing = majorAxis / 100;
881 for(
const SEG& seg : hatchSegs )
884 int maxError = lineWidth;
898 int gridsize = spacing;
907 hole_base.
Append( corner );
908 corner.
x += hole_size;
909 hole_base.
Append( corner );
910 corner.
y += hole_size;
911 hole_base.
Append( corner );
913 hole_base.
Append( corner );
920 int x_offset = bbox.
GetX() - ( bbox.
GetX() ) % gridsize - gridsize;
921 int y_offset = bbox.
GetY() - ( bbox.
GetY() ) % gridsize - gridsize;
923 for(
int xx = x_offset; xx <= bbox.
GetRight(); xx += gridsize )
925 for(
int yy = y_offset; yy <= bbox.
GetBottom(); yy += gridsize )
967 m_end += aMoveVector;
976 m_end += aMoveVector;
989 m_end += aMoveVector;
1004 seg.
A += aMoveVector;
1005 seg.
B += aMoveVector;
1020 pt.x =
KiROUND( pt.x * aScale );
1021 pt.y =
KiROUND( pt.y * aScale );
1039 std::vector<VECTOR2I> pts;
1045 pts.emplace_back( pt );
1046 scalePt( pts.back() );
1190 m_ellipse.Mirror( aCentre, aFlipDirection );
1219 std::vector<VECTOR2I> bezierPoints;
1224 converter.
GetPoly( bezierPoints, aMaxError );
1226 return bezierPoints;
1247 const double phi =
m_ellipse.Rotation.AsRadians();
1262 const double phi =
m_ellipse.Rotation.AsRadians();
1263 const double cosPhi = std::cos( phi );
1264 const double sinPhi = std::sin( phi );
1267 auto eval = [&](
double theta ) ->
VECTOR2I
1269 const double lx = a * std::cos( theta );
1270 const double ly = b * std::sin( theta );
1360 if( aEndAngle == aStartAngle )
1363 while( aEndAngle < aStartAngle )
1387 if(
radius > (
double) INT_MAX / 2.0 )
1388 radius = (double) INT_MAX / 2.0;
1451 return endAngle - startAngle;
1479 if( aCheckNegativeAngle && aAngle <
ANGLE_0 )
1495 default:
return _(
"Unrecognized" );
1500 return _(
"Connected Lines" );
1514 default:
return _(
"Unrecognized" );
1524 wxString shape =
_(
"Shape" );
1537 aList.emplace_back(
_(
"Angle" ), msg );
1569 msg.Printf( wxS(
"%d" ), pointCount );
1570 aList.emplace_back(
_(
"Points" ), msg );
1593 m_stroke.GetMsgPanelInfo( aFrame, aList );
1630 for(
auto iter =
GetPolyShape().CIterate(); iter; iter++ )
1631 bbox.
Merge( *iter );
1663 const SHAPE& hitShape = shape;
1665 return hitShape.
Collide( aPosition, std::max( 0, aAccuracy ) );
1668 double maxdist = aAccuracy;
1681 return dist <=
radius + maxdist;
1682 else if( abs(
radius - dist ) <= maxdist )
1706 if( dist >
radius + maxdist )
1712 if( abs(
radius - dist ) > maxdist )
1727 if( endAngle > startAngle )
1728 return relPosAngle >= startAngle && relPosAngle <= endAngle;
1730 return relPosAngle >= startAngle || relPosAngle <= endAngle;
1736 std::vector<VECTOR2I> updatedBezierPoints;
1741 converter.
GetPoly( updatedBezierPoints, aAccuracy / 2 );
1742 pts = &updatedBezierPoints;
1745 for(
unsigned int i = 1; i < pts->size(); i++ )
1747 if(
TestSegmentHit( aPosition, ( *pts )[i - 1], ( *pts )[i], maxdist ) )
1765 return poly.
Collide( aPosition, maxdist );
1773 if( poly.
CollideEdge( aPosition,
nullptr, maxdist ) )
1804 copy.SetClosed(
true );
1805 return copy.Collide( aPosition, maxdist );
1814 if(
GetPolyShape().CollideEdge( aPosition,
nullptr, maxdist ) )
1828 const double maxdistSq = maxdist * maxdist;
1833 if(
static_cast<double>( e.
SquaredDistance( aPosition,
false ) ) <= maxdistSq )
1839 if(
static_cast<double>( e.
SquaredDistance( aPosition,
true ) ) <= maxdistSq )
1875 int count = (int) outline.GetPointCount();
1877 for(
int ii = 0; ii < count; ii++ )
1879 VECTOR2I vertex = outline.GetPoint( ii );
1885 if( ii + 1 < count )
1887 VECTOR2I vertexNext = outline.GetPoint( ii + 1 );
1893 else if( outline.IsClosed() )
1895 VECTOR2I vertexNext = outline.GetPoint( 0 );
1961 return checkOutline( poly.
Outline( 0 ) );
2026 std::vector<VECTOR2I> updatedBezierPoints;
2031 converter.
GetPoly( updatedBezierPoints, aAccuracy / 2 );
2032 pts = &updatedBezierPoints;
2035 for(
unsigned ii = 1; ii < pts->size(); ii++ )
2037 VECTOR2I vertex = ( *pts )[ii - 1];
2038 VECTOR2I vertexNext = ( *pts )[ii];
2063 const int tessError = std::max( 1, aAccuracy / 2 );
2068 return checkOutline(
chain );
2090 std::vector<VECTOR2I> pts;
2094 pts.emplace_back( topLeft );
2095 pts.emplace_back( botRight.
x, topLeft.
y );
2096 pts.emplace_back( botRight );
2097 pts.emplace_back( topLeft.
x, botRight.
y );
2105 std::vector<VECTOR2I> pts;
2158 pts.emplace_back( tl );
2159 pts.emplace_back( tr );
2160 pts.emplace_back( br );
2161 pts.emplace_back( bl );
2174 std::vector<VECTOR2I> corners;
2179 corners.emplace_back( pt );
2182 if( corners.empty() )
2185 while( corners.size() < 4 )
2186 corners.emplace_back( corners.back() +
VECTOR2I( 10, 10 ) );
2193 for(
const VECTOR2I& corner : corners )
2195 if( corner.x < minX.
x )
2198 if( corner.x > maxX.
x )
2201 if( corner.y < minY.
y )
2204 if( corner.y > maxY.
y )
2210 pts.emplace_back( minX );
2211 pts.emplace_back( minY );
2212 pts.emplace_back( maxX );
2213 pts.emplace_back( maxY );
2217 pts.emplace_back( maxY );
2218 pts.emplace_back( minX );
2219 pts.emplace_back( minY );
2220 pts.emplace_back( maxX );
2224 pts.emplace_back( maxX );
2225 pts.emplace_back( maxY );
2226 pts.emplace_back( minX );
2227 pts.emplace_back( minY );
2231 pts.emplace_back( minY );
2232 pts.emplace_back( maxX );
2233 pts.emplace_back( maxY );
2234 pts.emplace_back( minX );
2263 if( t1 < ANGLE_0 && t2 >
ANGLE_0 )
2266 if( t1 < ANGLE_90 && t2 >
ANGLE_90 )
2277 if( t1 < ANGLE_0 || t2 >
ANGLE_0 )
2280 if( t1 < ANGLE_90 || t2 >
ANGLE_90 )
2306 if( aLineWidth < 0 )
2318 std::vector<VECTOR2I> pts;
2321 pts.emplace_back(
VECTOR2I( pt ) );
2352 std::vector<SHAPE*> effectiveShapes;
2382 effectiveShapes.emplace_back(
new SHAPE_SIMPLE( outline ) );
2384 if( width > 0 || !solidFill )
2386 std::set<size_t> arcsHandled;
2392 size_t arcIndex = outline.
ArcIndex( ii );
2394 if( !arcsHandled.contains( arcIndex ) )
2396 arcsHandled.insert( arcIndex );
2397 effectiveShapes.emplace_back(
new SHAPE_ARC( outline.
Arc( arcIndex ), width ) );
2412 effectiveShapes.emplace_back(
new SHAPE_SIMPLE( pts ) );
2414 if( width > 0 || !solidFill )
2416 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[0], pts[1], width ) );
2417 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[1], pts[2], width ) );
2418 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[2], pts[3], width ) );
2419 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[3], pts[0], width ) );
2430 if( width > 0 || !solidFill )
2439 VECTOR2I start_pt = bezierPoints[0];
2441 for(
unsigned int jj = 1; jj < bezierPoints.size(); jj++ )
2443 VECTOR2I end_pt = bezierPoints[jj];
2444 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( start_pt, end_pt, width ) );
2467 if( aLineChainOnly && l.
IsClosed() )
2470 for(
int jj = 0; jj < segCount; jj++ )
2485 std::vector<VECTOR2I> pts;
2487 for(
int ii = 0; ii <
chain.PointCount(); ++ii )
2488 pts.emplace_back(
chain.CPoint( ii ) );
2490 effectiveShapes.emplace_back(
new SHAPE_SIMPLE( pts ) );
2493 if( width > 0 || !solidFill )
2498 for(
int ii = 0; ii <
chain.SegmentCount(); ++ii )
2510 return effectiveShapes;
2518 for(
size_t ii = 0; ii < aPolygon.size(); ++ii )
2520 if( ii == aPolygon.size() - 1 && aPolygon[ii] == aPolygon.front() )
2523 chain.Append( aPolygon[ii] );
2526 chain.SetClosed(
true );
2543 std::vector<VECTOR2I> polygon;
2544 aEnding.
GetShapes( aPoint, aTangent, aLineWidth, polygon );
2546 if( polygon.empty() )
2553 if( polygon.size() >= 3 )
2555 aShapes.emplace_back(
new SHAPE_SEGMENT( polygon[0], polygon[1], std::max( 0, width ) ) );
2556 aShapes.emplace_back(
new SHAPE_SEGMENT( polygon[1], polygon[2], std::max( 0, width ) ) );
2562 if( polygon.size() < 3 )
2580 std::vector<SHAPE*> effectiveShapes;
2585 return effectiveShapes;
2588 return effectiveShapes;
2598 return effectiveShapes;
2604 std::vector<SHAPE*> effectiveShapes;
2605 bool shortenBody =
m_startEnding.GetShortenDepth( aLineWidth ) > 0 ||
m_endEnding.GetShortenDepth( aLineWidth ) > 0;
2634 EDA_ANGLE originalStartAngle = startAngle;
2635 EDA_ANGLE arcAngle = endAngle - startAngle;
2651 for(
size_t ii = 1; ii < pts.size(); ++ii )
2653 effectiveShapes.emplace_back(
2676 std::vector<VECTOR2I> pts;
2681 for(
size_t jj = 1; jj < pts.size(); ++jj )
2682 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[jj - 1], pts[jj], width ) );
2685 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts.back(), pts.front(), width ) );
2695 return effectiveShapes;
2704 effectiveShapes.emplace_back( shape );
2706 return effectiveShapes;
2717 std::vector<VECTOR2I> polygon;
2718 aEnding.
GetShapes( aPoint, aTangent, aLineWidth, polygon );
2720 if( polygon.empty() )
2723 auto addStrokedSegment = [&](
const VECTOR2I& aStart,
const VECTOR2I& aEnd,
int aStrokeWidth )
2725 int width = std::max( 0, aStrokeWidth ) + 2 * aClearance;
2735 if( polygon.size() >= 3 )
2737 addStrokedSegment( polygon[0], polygon[1], strokeWidth );
2738 addStrokedSegment( polygon[1], polygon[2], strokeWidth );
2744 if( polygon.size() < 3 )
2754 for(
int ii = 0; ii < outline.
PointCount(); ++ii )
2757 if( aClearance > 0 )
2759 int inflate = aClearance;
2782 int aLineWidth )
const
2804 ERROR_LOC aErrorLoc,
bool ignoreLineWidth )
const
2815 int width = ignoreLineWidth ? 0 :
GetWidth();
2816 width += 2 * aClearance;
2837 EDA_ANGLE originalStartAngle = startAngle;
2838 EDA_ANGLE arcAngle = endAngle - startAngle;
2856 for(
size_t ii = 1; ii < pts.size(); ++ii )
2882 std::vector<VECTOR2I> pts;
2887 for(
size_t jj = 1; jj < pts.size(); ++jj )
2917 std::vector<VECTOR2I> polygon;
2918 aEnding.
GetShapes( aPoint, aTangent, aLineWidth, polygon );
2920 if( polygon.empty() )
2925 for(
const VECTOR2I& point : polygon )
2926 endingBBox.
Merge( point );
2931 stroke = aLineWidth;
2933 endingBBox.
Inflate( std::max( 0, stroke ) / 2 );
2942 aBBox.
Merge( endingBBox );
2955 bool hasBox =
false;
2961 mergeEnding(
m_startEnding, startPoint, startTangent, hasBox );
2962 mergeEnding(
m_endEnding, endPoint, endTangent, hasBox );
2976 std::vector<VECTOR2I> points;
2982 points.reserve( totalCount );
2987 points.emplace_back( pt );
2997 m_poly = std::make_unique<SHAPE_POLY_SET>();
3005 m_poly = std::make_unique<SHAPE_POLY_SET>();
3120 poly.
Append( aPosition,
true );
3131#define sq( x ) pow( x, 2 )
3178 case 0:
SetArcGeometry( aPosition, aPosition, aPosition );
return;
3201 if( chordBefore > 0 )
3202 ratio = chordAfter / chordBefore;
3205 radius = std::max( sqrt(
sq(
radius ) * ratio ), sqrt( chordAfter ) / 2 );
3211 double radialA =
m_start.Distance( aPosition );
3212 double radialB =
m_end.Distance( aPosition );
3213 radius = ( radialA + radialB ) / 2.0;
3225 double sqRadDiff = (
radius *
radius ) - ( l * l ) / 4.0;
3230 if( l > 0 && sqRadDiff >= 0 )
3278 const VECTOR2I secondCorner = aPosition;
3280 const int halfW =
std::abs( secondCorner.
x - firstCorner.
x ) / 2;
3281 const int halfH =
std::abs( secondCorner.
y - firstCorner.
y ) / 2;
3287 if( halfW >= halfH )
3289 majorRadius = std::max( halfW, 1 );
3290 minorRadius = std::max( halfH, 1 );
3295 majorRadius = std::max( halfH, 1 );
3296 minorRadius = std::max( halfW, 1 );
3317 const VECTOR2I secondCorner = aPosition;
3319 const int halfW =
std::abs( secondCorner.
x - firstCorner.
x ) / 2;
3320 const int halfH =
std::abs( secondCorner.
y - firstCorner.
y ) / 2;
3326 if( halfW >= halfH )
3328 majorRadius = std::max( halfW, 1 );
3329 minorRadius = std::max( halfH, 1 );
3334 majorRadius = std::max( halfH, 1 );
3335 minorRadius = std::max( halfW, 1 );
3357 const double a = std::max( 1,
m_ellipse.MajorRadius );
3358 const double b = std::max( 1,
m_ellipse.MinorRadius );
3361 const double dx = aPosition.
x -
center.x;
3362 const double dy = aPosition.
y -
center.y;
3364 const double cosRot = rotation.
Cos();
3365 const double sinRot = rotation.
Sin();
3366 const double lx = dx * cosRot + dy * sinRot;
3367 const double ly = -dx * sinRot + dy * cosRot;
3381 while( cursorAngle <=
m_ellipse.StartAngle )
3438#define SWAPITEM( x ) std::swap( x, image->x )
3466#define TEST( a, b ) \
3471#define TEST_E( a, b ) \
3473 if( abs( a - b ) > EPSILON ) \
3476#define TEST_PT( a, b ) \
3478 TEST_E( a.x, b.x ); \
3479 TEST_E( a.y, b.y ); \
3536 bool ignoreLineWidth,
bool includeFill )
const
3539 int width = ignoreLineWidth ? 0 :
GetWidth();
3541 width += 2 * aClearance;
3568 width / 2, aError, aErrorLoc );
3578 std::set<size_t> arcsHandled;
3584 size_t arcIndex = outline.
ArcIndex( ii );
3586 if( arcsHandled.contains( arcIndex ) )
3589 arcsHandled.insert( arcIndex );
3615 if( width > 0 || !solidFill )
3652 int inflate = width / 2;
3669 for(
int jj = 0; jj < (int) poly.
SegmentCount(); ++jj )
3684 std::vector<VECTOR2I> poly;
3685 converter.
GetPoly( poly, aError );
3687 for(
unsigned ii = 1; ii < poly.size(); ii++ )
3706 for(
int ii = 0; ii <
chain.PointCount(); ++ii )
3711 int inflate = width / 2;
3724 for(
int ii = 0; ii <
chain.SegmentCount(); ++ii )
3726 const SEG& seg =
chain.CSegment( ii );
3863 default:
return false;
3881 double similarity = 1.0;
3916 similarity *= std::pow( 0.9, m + n - 2 * longest );
3922 std::vector<VECTOR2I> poly;
3923 std::vector<VECTOR2I> otherPoly;
3931 for(
int ii = 0; ii < m; ++ii )
3933 poly.emplace_back( lastPt -
GetPolyShape().CVertex( ii ) );
3939 for(
int ii = 0; ii < n; ++ii )
3947 similarity *= std::pow( 0.9, m + n - 2 * longest );
3976 aEndTangent = lineAngle;
3989 if( aLineWidth > 0 &&
radius > 0 )
3991 int startDepth =
m_startEnding.GetCurveOrientationDepth( aLineWidth );
3993 if( startDepth > 0 )
3998 startRadius -= offset;
4000 startRadius += offset;
4003 int endDepth =
m_endEnding.GetCurveOrientationDepth( aLineWidth );
4010 endRadius += offset;
4012 endRadius -= offset;
4018 aStartTangent = startRadius +
ANGLE_90;
4019 aEndTangent = endRadius -
ANGLE_90;
4023 aStartTangent = startRadius -
ANGLE_90;
4024 aEndTangent = endRadius +
ANGLE_90;
4036 std::optional<double> totalLength;
4040 auto fallbackStartTangent = [&]() ->
EDA_ANGLE
4045 if( bpts.size() >= 2 )
4046 return EDA_ANGLE( bpts.front() - bpts[1] );
4051 auto fallbackEndTangent = [&]() ->
EDA_ANGLE
4056 if( bpts.size() >= 2 )
4057 return EDA_ANGLE( bpts.back() - bpts[bpts.size() - 2] );
4062 auto openArrowFlexTangent = [&](
const LINE_ENDING& aEnding,
bool aStart ) -> std::optional<EDA_ANGLE>
4065 return std::nullopt;
4070 return std::nullopt;
4075 if( *totalLength <= 0.0 )
4076 return std::nullopt;
4078 double distanceFromStart = std::min<double>( depth, *totalLength );
4081 distanceFromStart = *totalLength - distanceFromStart;
4084 VECTOR2D sample = sourceCurve.PointAt( t );
4088 if(
delta.EuclideanNorm() <= 0.0 )
4089 return std::nullopt;
4099 aStartTangent =
EDA_ANGLE( startDelta );
4101 aStartTangent = fallbackStartTangent();
4108 aEndTangent = fallbackEndTangent();
4112 aStartTangent = fallbackStartTangent();
4113 aEndTangent = fallbackEndTangent();
4116 if( std::optional<EDA_ANGLE> startFlex = openArrowFlexTangent(
m_startEnding,
true ) )
4117 aStartTangent = *startFlex;
4119 if( std::optional<EDA_ANGLE> endFlex = openArrowFlexTangent(
m_endEnding,
false ) )
4120 aEndTangent = *endFlex;
4174 aStartPoint = outline.
CPoint( 0 );
4183 if( bpts.size() < 2 )
4186 aStartPoint = bpts.front();
4187 aEndPoint = bpts.back();
4191 default:
return false;
4200 double len =
delta.EuclideanNorm();
4207 int totalDepth = std::max( 0, startDepth ) + std::max( 0, endDepth );
4209 if( totalDepth <= 0 )
4212 if( totalDepth >= len )
4220 if( startDepth > 0 )
4222 aStart.
x +=
KiROUND( dir.
x * startDepth );
4223 aStart.
y +=
KiROUND( dir.
y * startDepth );
4237 int aLineWidth )
const
4242 int startDepth =
m_startEnding.GetShortenDepth( aLineWidth );
4243 int endDepth =
m_endEnding.GetShortenDepth( aLineWidth );
4244 int totalDepth = std::max( 0, startDepth ) + std::max( 0, endDepth );
4246 if( totalDepth <= 0 )
4251 if( totalDepth >= arcLength )
4262 aStartAngle += startOffset;
4263 aArcAngle -= totalOffset;
4267 aStartAngle -= startOffset;
4268 aArcAngle += totalOffset;
4277 double tInv = 1.0 - aT;
4279 VECTOR2D derivative = 3.0 * tInv * tInv * ( aBezier.
C1 - aBezier.
Start )
4280 + 6.0 * tInv * aT * ( aBezier.
C2 - aBezier.
C1 )
4281 + 3.0 * aT * aT * ( aBezier.
End - aBezier.
C2 );
4294 static constexpr double nodes[] = {
4295 0.0950125098376374, 0.2816035507792590, 0.4580167776572274, 0.6178762444026438,
4296 0.7554044083550030, 0.8656312023878318, 0.9445750230732326, 0.9894009349916499
4299 static constexpr double weights[] = { 0.1894506104550685, 0.1826034150449236, 0.1691565193950025,
4300 0.1495959888165767, 0.1246289712555339, 0.0951585116824928,
4301 0.0622535239386479, 0.0271524594117541 };
4303 static_assert( std::size( nodes ) == std::size( weights ) );
4305 double halfWidth = ( aT1 - aT0 ) / 2.0;
4306 double center = ( aT0 + aT1 ) / 2.0;
4307 double length = 0.0;
4309 for(
size_t ii = 0; ii < std::size( nodes ); ++ii )
4311 double offset = halfWidth * nodes[ii];
4316 return halfWidth * length;
4322 if( aTargetLength <= 0.0 )
4325 if( aTargetLength >= aTotalLength )
4332 static constexpr int paramSearchIterations = 24;
4334 for(
int ii = 0; ii < paramSearchIterations; ++ii )
4336 double mid = ( low + high ) / 2.0;
4339 if( len < aTargetLength )
4345 return ( low + high ) / 2.0;
4352 return std::nullopt;
4356 int startDepth =
m_startEnding.GetShortenDepth( aLineWidth );
4357 int endDepth =
m_endEnding.GetShortenDepth( aLineWidth );
4359 if( startDepth <= 0 && endDepth <= 0 )
4364 if( totalLength <= 0.0 || startDepth + endDepth >= totalLength )
4365 return std::nullopt;
4371 return std::nullopt;
4373 return curve.SubCurve( t0, t1 );
4379 std::vector<VECTOR2D> pts;
4387 std::vector<VECTOR2D> ctrlPts = { curve->Start, curve->C1, curve->C2, curve->End };
4397 const VECTOR2D& aPenultimate,
int aLineWidth )
const
4399 int startDepth =
m_startEnding.GetShortenDepth( aLineWidth );
4400 int endDepth =
m_endEnding.GetShortenDepth( aLineWidth );
4401 int totalDepth = std::max( 0, startDepth ) + std::max( 0, endDepth );
4403 if( totalDepth <= 0 )
4406 double startSegLen = ( aSecond - aFirst ).EuclideanNorm();
4407 double endSegLen = ( aLast - aPenultimate ).EuclideanNorm();
4408 bool twoPointPoly = aSecond == aLast && aPenultimate == aFirst;
4410 if( twoPointPoly && startSegLen <= totalDepth )
4416 if( startDepth > 0 && startSegLen <= startDepth )
4422 if( endDepth > 0 && endSegLen <= endDepth )
4428 if( startDepth > 0 )
4432 if( startSegLen > 0 )
4433 aFirst = aFirst + dir * ( startDepth / startSegLen );
4438 VECTOR2D dir = aLast - aPenultimate;
4441 aLast = aLast - dir * ( endDepth / endSegLen );
4449 int aLineWidth )
const
4451 if( aPoints.size() < 2 )
4454 if( aClosed || aOutlineIdx != 0 )
4467 aPoints.front() =
VECTOR2I( first );
4475 std::vector<VECTOR2I>& aPoints,
int aLineWidth )
const
4485 aPoints.emplace_back( pt );
4513 if( lineStyleEnum.
Choices().GetCount() == 0 )
4524 if( hatchModeEnum.
Choices().GetCount() == 0 )
4536 auto isNotPolygonOrCircle =
4566 auto isEllipseOrEllipseArc =
4586 const wxString shapeProps =
_HKI(
"Shape Properties" );
4652 wxASSERT_MSG( aValue.CheckType<
int>(),
4653 "Expecting int-containing value" );
4655 int radius = aValue.As<
int>();
4660 return std::nullopt;
4662 int maxRadius = std::min( prop_shape->GetRectangleWidth(),
4663 prop_shape->GetRectangleHeight() ) / 2;
4666 return std::make_unique<VALIDATION_ERROR_TOO_LARGE<int>>(
radius, maxRadius );
4668 return std::make_unique<VALIDATION_ERROR_TOO_SMALL<int>>(
radius, 0 );
4670 return std::nullopt;
4729 double degrees = 0.0;
4731 if( aValue.GetAs( °rees ) && degrees == 0.0 )
4733 return std::make_unique<VALIDATION_ERROR_MSG>(
_(
"Arc angle must not be zero." ) );
4736 return std::nullopt;
4739 auto fillAvailable =
4752 switch( edaShape->GetShape() )
4783 return !shape->IsClosed();
4790 if( endingStyleEnum.
Choices().GetCount() == 0 )
KICOMMON_API types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICOMMON_API KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Bezier curves to polygon converter.
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMaxError=10)
Convert a Bezier curve to a polygon.
Generic cubic Bezier representation.
VECTOR2< NumericType > Start
VECTOR2< NumericType > C1
VECTOR2< NumericType > C2
VECTOR2< NumericType > End
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr void SetOrigin(const Vec &pos)
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr Vec Centre() const
constexpr coord_type GetX() const
bool IntersectsCircleEdge(const Vec &aCenter, const int aRadius, const int aWidth) const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr const Vec GetCenter() const
constexpr size_type GetHeight() const
constexpr coord_type GetLeft() const
constexpr bool Contains(const Vec &aPoint) const
constexpr coord_type GetRight() const
constexpr void SetEnd(coord_type x, coord_type y)
constexpr coord_type GetTop() const
constexpr bool Intersects(const BOX2< Vec > &aRect) const
constexpr coord_type GetBottom() const
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
int AsTenthsOfADegree() const
FRAME_T GetFrameType() const
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
UI_FILL_MODE GetFillModeProp() const
static bool ShortenSegmentForEndings(VECTOR2I &aStart, VECTOR2I &aEnd, const LINE_ENDING &aStartEnding, const LINE_ENDING &aEndEnding, int aLineWidth)
Shorten a segment body for line endings.
virtual int GetHatchLineSpacing() const
EDA_ANGLE GetArcAngle() const
int GetStartEndingLength() const
virtual void SetEnd(const VECTOR2I &aEnd)
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false, bool includeFill=false) const
Convert the shape to a closed polygon.
int GetEllipseMinorRadius() const
const VECTOR2I & GetBezierC2() const
const VECTOR2I & GetEllipseCenter() const
bool GetLineEndingsBoundingBox(BOX2I &aBBox, int aLineWidth) const
void move(const VECTOR2I &aMoveVector)
void SetCenter(const VECTOR2I &aCenter)
VECTOR2I getCenter() const
void SetFillModeProp(UI_FILL_MODE)
virtual int getMaxError() const
void rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
std::vector< SHAPE * > MakeEffectiveShapesWithLineEndings(int aLineWidth) const
Make effective geometry for the shape body shortened for line endings plus the line-ending geometry i...
const std::vector< VECTOR2I > buildBezierToSegmentsPointsList(int aMaxError) const
void SetEndEndingLength(int aLength)
void SetStartEndingStyle(LINE_ENDING_STYLE aStyle)
const SHAPE_POLY_SET & GetHatching() const
EDA_ANGLE GetEllipseEndAngle() const
FILL_T GetFillMode() const
void SetEndEndingWidth(int aWidth)
virtual void SetCornerRadius(int aRadius)
long long int m_rectangleHeight
int GetEllipseMajorRadius() const
std::unique_ptr< EDA_SHAPE_HATCH_CACHE_DATA > m_hatchingCache
virtual int GetEffectiveWidth() const
std::vector< VECTOR2I > GetPolyPoints() const
Duplicate the polygon outlines into a flat list of VECTOR2I points.
void TransformWithLineEndingsToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the shape body shortened for line endings plus line-ending geometry to polygons.
COLOR4D GetLineColor() const
SHAPE_ELLIPSE buildShapeEllipse() const
void TransformLineEndingsToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, int aLineWidth) const
Append only the line-ending geometry associated with this shape to a polygon set.
std::vector< SHAPE * > makeEffectiveShapes(bool aEdgeOnly, bool aLineChainOnly=false, bool aHittesting=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
int GetRectangleWidth() const
void SetLineStyle(const LINE_STYLE aStyle)
std::vector< SHAPE * > makeShortenedBodyShapes(int aLineWidth, bool aEdgeOnly=false) const
Make effective geometry for the shape body shortened for line endings, without the line-ending geomet...
void recalcEllipseArcEndpoints()
When m_shape == ELLIPSE_ARC, recompute m_start/m_end from m_ellipse.
void calcEdit(const VECTOR2I &aPosition)
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
bool ShortenPolyForEndings(VECTOR2D &aFirst, VECTOR2D &aLast, const VECTOR2D &aSecond, const VECTOR2D &aPenultimate, int aLineWidth) const
SHAPE_POLY_SET & GetPolyShape()
void GetEndingTangents(EDA_ANGLE &aStartTangent, EDA_ANGLE &aEndTangent, int aLineWidth=0) const
Compute outward-facing tangent angles at the start and end of the shape.
int GetStartEndingStrokeWidth() const
void CalcArcAngles(EDA_ANGLE &aStartAngle, EDA_ANGLE &aEndAngle) const
Calc arc start and end angles such that aStartAngle < aEndAngle.
virtual std::vector< VECTOR2I > GetCornersInSequence(EDA_ANGLE angle) const
EDA_ANGLE GetEllipseRotation() const
void ShapeGetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
void SetEndEndingStyle(LINE_ENDING_STYLE aStyle)
virtual bool isMoving() const
virtual void SetEllipseEndAngle(const EDA_ANGLE &aA)
int GetEndEndingStrokeWidth() const
bool operator==(const EDA_SHAPE &aOther) const
std::vector< SHAPE * > MakeEffectiveShapesForStroking(int aLineWidth=-1) const
Make a set of SHAPE objects to hand to STROKE_PARAMS::Stroke().
virtual void SetBezierC2(const VECTOR2I &aPt)
bool GetShortenedBodyPolyPoints(const SHAPE_LINE_CHAIN &aOutline, int aOutlineIdx, std::vector< VECTOR2I > &aPoints, int aLineWidth) const
Copy an outline and apply line-ending body shortening when applicable.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
const std::vector< SEG > & GetHatchLines() const
void SetRectangleHeight(const int &aHeight)
SHAPE_POLY_SET & hatching() const
bool IsHatchedFill() const
virtual SHAPE_POLY_SET getHatchingKnockouts() const
virtual void SetBezierC1(const VECTOR2I &aPt)
int GetStartEndingWidth() const
bool GetLineEndingEndpoints(VECTOR2I &aStartPoint, VECTOR2I &aEndPoint) const
Return the source endpoints used to place line endings.
virtual void SetFilled(bool aFlag)
virtual bool IsFilledForHitTesting() const
virtual void SetEllipseRotation(const EDA_ANGLE &aA)
bool continueEdit(const VECTOR2I &aPosition)
virtual void SetArcAngle(const EDA_ANGLE &aAngle)
wxString ShowShape() const
LINE_ENDING_STYLE GetStartEndingStyle() const
void SetFillColor(const COLOR4D &aColor)
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.
virtual int GetHatchLineWidth() const
void flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
int GetEndEndingWidth() const
EDA_SHAPE(SHAPE_T aType, int aLineWidth, FILL_T aFill)
std::vector< SEG > & hatchLines() const
void beginEdit(const VECTOR2I &aStartPoint)
int GetEndEndingLength() const
int GetPointCount() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
LINE_STYLE GetLineStyle() const
void endEdit(bool aClosed=true)
Finish editing the shape.
virtual void SetEllipseCenter(const VECTOR2I &aPt)
void SetStartEndingLength(int aLength)
void SetEndEndingStrokeWidth(int aWidth)
virtual void SetEllipseMinorRadius(int aR)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
virtual void SetEllipseMajorRadius(int aR)
void SetLineColor(const COLOR4D &aColor)
COLOR4D GetFillColor() const
void SetRectangle(const long long int &aHeight, const long long int &aWidth)
virtual void SetShape(SHAPE_T aShape)
void SwapShape(EDA_SHAPE *aImage)
std::vector< VECTOR2I > GetRectCorners() const
std::vector< SHAPE * > MakeLineEndingEffectiveShapes(int aLineWidth) const
Make the line-ending geometry associated with this shape.
void SetStartEndingWidth(int aWidth)
std::vector< VECTOR2I > m_bezierPoints
void setPosition(const VECTOR2I &aPos)
EDA_ANGLE GetEllipseStartAngle() const
const std::vector< VECTOR2I > & GetBezierPoints() const
virtual bool IsProxyItem() const
void computeArcBBox(BOX2I &aBBox) const
virtual void UpdateHatching() const
LINE_ENDING m_startEnding
void SetRectangleWidth(const int &aWidth)
virtual void SetEllipseStartAngle(const EDA_ANGLE &aA)
virtual void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
wxString SHAPE_T_asString() const
void scale(double aScale)
double Similarity(const EDA_SHAPE &aOther) const
const VECTOR2I & GetBezierC1() const
std::optional< BEZIER< double > > ShortenedBezierCurve(int aLineWidth) const
Return the cubic Bezier curve shortened for line endings.
const BOX2I getBoundingBox() const
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
int GetRectangleHeight() const
virtual int GetWidth() const
bool ShortenBodyPolyPoints(std::vector< VECTOR2I > &aPoints, bool aClosed, int aOutlineIdx, int aLineWidth) const
Apply line-ending body shortening to copied/generated polyline points.
bool ShortenArcForEndings(EDA_ANGLE &aStartAngle, EDA_ANGLE &aArcAngle, double aRadius, int aLineWidth) const
Shorten an arc body for line endings.
std::vector< VECTOR2D > ShortenedBezierPolyline(int aLineWidth) const
Return the flattened Bezier polyline after line-ending shortening.
VECTOR2I getPosition() const
bool IsClockwiseArc() const
LINE_ENDING_STYLE GetEndEndingStyle() const
void RebuildBezierToSegmentsPointsList()
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
EDA_SHAPE & operator=(const EDA_SHAPE &aOther)
virtual void SetWidth(int aWidth)
EDA_ANGLE GetSegmentAngle() const
void SetStartEndingStrokeWidth(int aWidth)
int GetCornerRadius() const
void SetFillMode(FILL_T aFill)
std::unique_ptr< SHAPE_POLY_SET > m_poly
virtual void SetPolyShape(const SHAPE_POLY_SET &aShape)
virtual void SetStart(const VECTOR2I &aStart)
wxString getFriendlyName(FRAME_T aFrameType) const
long long int m_rectangleWidth
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
bool IsPolyShapeValid() const
int Compare(const EDA_SHAPE *aOther) const
VECTOR2I GetArcMid() const
VECTOR2< NumericType > Center
ENUM_MAP & Map(T aValue, const wxString &aName)
static ENUM_MAP< T > & Instance()
Class that other classes need to inherit from, in order to be inspectable.
A color representation with 4 components: red, green, blue, alpha.
Decorative shape (arrowhead, circle, square) at the start or end of a graphic line,...
int GetShortenDepth(int aLineWidth) const
Return how far the line should be shortened at this ending.
int GetCurveOrientationDepth(int aLineWidth) const
Return how far along a curved body to look when orienting this ending.
LINE_ENDING_STYLE GetStyle() const
void GetShapes(const VECTOR2I &aPoint, const EDA_ANGLE &aTangent, int aLineWidth, std::vector< VECTOR2I > &aPolygon) const
Generate ending geometry as polygon vertices at the given point and direction.
int GetStrokeWidth() const
Outline stroke width.
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
PROPERTY_BASE & SetValidator(PROPERTY_VALIDATOR_FN &&aValidator)
PROPERTY_BASE & SetIsCopyable(bool aIsCopyable=true)
PROPERTY_BASE & SetIsHiddenFromRulesEditor(bool aHide=true)
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
A round rectangle shape, based on a rectangle and a radius.
void TransformToPolygon(SHAPE_POLY_SET &aBuffer, int aMaxError) const
Get the polygonal representation of the roundrect.
int Length() const
Return the length (this).
EDA_ANGLE GetCentralAngle() const
Get the "central angle" of the arc - this is the angle at the point of the "pie slice".
const VECTOR2I & GetArcMid() const
EDA_ANGLE GetEndAngle() const
const VECTOR2I & GetP1() const
EDA_ANGLE GetStartAngle() const
const VECTOR2I & GetP0() const
SHAPE_TYPE Type() const
Return the type of the shape.
SHAPE_LINE_CHAIN ConvertToPolyline(int aMaxError) const
Build a polyline approximation of the ellipse or arc.
SEG::ecoord SquaredDistance(const VECTOR2I &aP, bool aOutlineOnly=false) const override
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Move(const VECTOR2I &aVector) override
const SHAPE_ARC & Arc(size_t aArc) const
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.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
SEG Segment(int aIndex) const
Return a copy of the aIndex-th segment in the 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.
bool IsArcSegment(size_t aSegment) const
const std::vector< VECTOR2I > & CPoints() const
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.
void ClearArcs()
Removes all arc references from all the outlines and holes in the polyset.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
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)
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.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
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)
const std::vector< SEG > GenerateHatchLines(const std::vector< double > &aSlopes, int aSpacing, int aLineLength) const
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.
void Mirror(const VECTOR2I &aRef, FLIP_DIRECTION aFlipDirection)
Mirror the line points about y or x (or both)
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
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
SHAPE_POLY_SET CloneDropTriangulation() const
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
An abstract shape on 2D plane.
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
LINE_STYLE GetLineStyle() const
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
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 TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
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.
@ ROUND_ALL_CORNERS
All angles are rounded.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
static constexpr EDA_ANGLE ANGLE_270
static constexpr EDA_ANGLE ANGLE_360
static constexpr EDA_ANGLE ANGLE_180
static void addLineEndingEffectiveShapes(std::vector< SHAPE * > &aShapes, const LINE_ENDING &aEnding, const VECTOR2I &aPoint, const EDA_ANGLE &aTangent, int aLineWidth)
static void addLineEndingPolygon(SHAPE_POLY_SET &aBuffer, const LINE_ENDING &aEnding, const VECTOR2I &aPoint, const EDA_ANGLE &aTangent, int aClearance, int aError, ERROR_LOC aErrorLoc, int aLineWidth)
static bool hasLineEnding(const LINE_ENDING &aStartEnding, const LINE_ENDING &aEndEnding)
static double bezierSpeedAt(const BEZIER< double > &aBezier, double aT)
static double findBezierTAtLength(const BEZIER< double > &aBezier, double aTargetLength, double aTotalLength)
static struct EDA_SHAPE_DESC _EDA_SHAPE_DESC
static double bezierLength(const BEZIER< double > &aBezier, double aT0, double aT1)
static SHAPE_LINE_CHAIN lineEndingClosedChain(const std::vector< VECTOR2I > &aPolygon)
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
@ FRAME_SCH_SYMBOL_EDITOR
a few functions useful in geometry calculations.
LINE_ENDING_STYLE
Line ending styles for graphic lines, arcs, and beziers.
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)
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
KICOMMON_API 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.
bool ShapeHitTest(const SHAPE_LINE_CHAIN &aHitter, const SHAPE &aHittee, bool aHitteeContained)
Perform a shape-to-shape hit test.
SHAPE_LINE_CHAIN BoxToLineChain(const BOX2I &aBox)
Get a SHAPE_LINE_CHAIN representing the outline of a box.
size_t longest_common_subset(const _Container &__c1, const _Container &__c2)
Returns the length of the longest common subset of values between two containers.
KICOMMON_API void PackLineEnding(types::LineEnding &aOutput, const LINE_ENDING &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackColor(types::Color &aOutput, const KIGFX::COLOR4D &aInput)
KICOMMON_API void UnpackStroke(STROKE_PARAMS &aOutput, const types::StrokeAttributes &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API int UnpackDistance(const types::Distance &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackPolySet(types::PolySet &aOutput, const SHAPE_POLY_SET &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API LINE_ENDING UnpackLineEnding(const types::LineEnding &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API KIGFX::COLOR4D UnpackColor(const types::Color &aInput)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackDistance(types::Distance &aOutput, int aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackStroke(types::StrokeAttributes &aOutput, const STROKE_PARAMS &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API SHAPE_POLY_SET UnpackPolySet(const types::PolySet &aInput, const EDA_IU_SCALE &aScale)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
#define IMPLEMENT_ENUM_TO_WXANY(type)
#define NO_SETTER(owner, 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)
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names.
std::optional< std::unique_ptr< VALIDATION_ERROR > > VALIDATOR_RESULT
Null optional means validation succeeded.
@ SH_POLY_SET
set of polygons (with holes, etc.)
@ SH_SIMPLE
simple polygon
@ SH_ELLIPSE
ellipse or elliptical arc
@ SH_NULL
empty shape (no shape...),
@ SH_POLY_SET_TRIANGLE
a single triangle belonging to a POLY_SET triangulation
@ SH_LINE_CHAIN
line chain (polyline)
@ SH_COMPOUND
compound shape, consisting of multiple simple shapes
static bool Collide(const SHAPE_CIRCLE &aA, const SHAPE_CIRCLE &aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)
Utility functions for working with shapes.
LINE_STYLE
Dashed line types.
const SHAPE_LINE_CHAIN chain
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
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)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
double RAD2DEG(double rad)
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.
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D