41SEG GetBisectorOfCornerSegments(
const SEG& aSegA,
const SEG& aSegB,
int aLength )
49 const auto getSegVectorPointingAwayFrom = [](
const SEG& aSeg,
52 const int distA = ( aSeg.
A - aPoint ).EuclideanNorm();
53 const int distB = ( aSeg.
B - aPoint ).EuclideanNorm();
57 return ( distA < distB ) ? ( aSeg.
B - aSeg.
A ) : ( aSeg.
A - aSeg.
B );
61 const int maxLen = std::max( aSegA.
Length(), aSegB.
Length() );
62 const VECTOR2I aVecOutward = getSegVectorPointingAwayFrom( aSegA, *corner ).
Resize( maxLen );
63 const VECTOR2I bVecOutward = getSegVectorPointingAwayFrom( aSegB, *corner ).
Resize( maxLen );
64 const VECTOR2I bisectorOutward = aVecOutward + bVecOutward;
66 return SEG( *corner, *corner + bisectorOutward.
Resize( aLength ) );
77 if( line_a_setback == 0 && line_b_setback == 0 )
85 if( aSegA.
Length() < line_a_setback || aSegB.
Length() < line_b_setback )
109 SEG setback_a( *corner, *corner +
VECTOR2I( a_end_pt - *corner ).Resize( line_a_setback ) );
110 SEG setback_b( *corner, *corner +
VECTOR2I( b_end_pt - *corner ).Resize( line_b_setback ) );
117 std::optional<SEG> new_a;
122 std::optional<SEG> new_b;
132 int aDogboneRadius,
bool aAddSlots )
142 const SEG bisector = GetBisectorOfCornerSegments( aSegA, aSegB, aDogboneRadius );
145 const VECTOR2I dogboneCenter = bisector.
B;
152 const std::vector<VECTOR2I> segAIntersections =
circle.Intersect( aSegA );
153 const std::vector<VECTOR2I> segBIntersections =
circle.Intersect( aSegB );
156 static int s_epsilon = 8;
158 const auto getPointNotOnCorner =
159 [&](
const std::vector<VECTOR2I>& aIntersections,
const VECTOR2I& aCorner )
161 std::optional<VECTOR2I> result;
162 for(
const VECTOR2I& pt : aIntersections )
164 if( aCorner.Distance( pt ) > s_epsilon )
173 const std::optional<VECTOR2I> ptOnSegA = getPointNotOnCorner( segAIntersections, *corner );
174 const std::optional<VECTOR2I> ptOnSegB = getPointNotOnCorner( segBIntersections, *corner );
177 if( !ptOnSegA || !ptOnSegB )
182 SHAPE_ARC arc( *ptOnSegA, *corner, *ptOnSegB, 0 );
193 std::optional<SEG> new_a, new_b;
194 if( aOtherPtA != *ptOnSegA )
195 new_a =
SEG{ aOtherPtA, *ptOnSegA };
197 if( aOtherPtB != *ptOnSegB )
198 new_b =
SEG{ aOtherPtB, *ptOnSegB };
201 if( !small_arc_mouth || !aAddSlots )
227 slotArc.
GetP0() + ( dogboneCenter - *corner ),
231 slotArc.
GetP1() + ( dogboneCenter - *corner ),
234 const OPT_VECTOR2I ext_a_intersect = arc_extension_a.Intersect( aSegA );
235 const OPT_VECTOR2I ext_b_intersect = arc_extension_b.Intersect( aSegB );
237 if( !ext_a_intersect || !ext_b_intersect )
246 std::optional<SEG> new_a, new_b;
247 if( aOtherPtA != *ext_a_intersect )
248 new_a =
SEG{ aOtherPtA, *ext_a_intersect };
250 if( aOtherPtB != *ext_b_intersect )
251 new_b =
SEG{ aOtherPtB, *ext_b_intersect };
264 unsigned int aDistance,
265 int aIndex,
int aErrorMax )
286 for(
int currVertex = 0; currVertex < currContour.PointCount(); currVertex++ )
289 int x1 = currContour.
CPoint( currVertex ).
x;
290 int y1 = currContour.CPoint( currVertex ).y;
299 prevVertex = currVertex == 0 ? currContour.PointCount() - 1 : currVertex - 1;
302 nextVertex = currVertex == currContour.PointCount() - 1 ? 0 : currVertex + 1;
305 double xa = currContour.CPoint( prevVertex ).x - x1;
306 double ya = currContour.CPoint( prevVertex ).y - y1;
309 double xb = currContour.CPoint( nextVertex ).x - x1;
310 double yb = currContour.CPoint( nextVertex ).y - y1;
313 if(
std::abs( xa + xb ) < std::numeric_limits<double>::epsilon()
314 &&
std::abs( ya + yb ) < std::numeric_limits<double>::epsilon() )
320 double lena = hypot( xa, ya );
321 double lenb = hypot( xb, yb );
338 newContour.
Append( x1 + nx1, y1 + ny1 );
343 newContour.
Append( x1 + nx2, y1 + ny2 );
347 double cosine = ( xa * xb + ya * yb ) / ( lena * lenb );
349 double radius = aDistance;
350 double denom = sqrt( 2.0 / ( 1 + cosine ) - 1 );
353 if( std::isinf( denom ) )
357 if( 0.5 * lena * denom <
radius )
358 radius = 0.5 * lena * denom;
360 if( 0.5 * lenb * denom <
radius )
361 radius = 0.5 * lenb * denom;
364 double k =
radius / sqrt( .5 * ( 1 - cosine ) );
365 double lenab = sqrt( ( xa / lena + xb / lenb ) * ( xa / lena + xb / lenb ) +
366 ( ya / lena + yb / lenb ) * ( ya / lena + yb / lenb ) );
367 double xc = x1 + k * ( xa / lena + xb / lenb ) / lenab;
368 double yc = y1 + k * ( ya / lena + yb / lenb ) / lenab;
371 k =
radius / sqrt( 2 / ( 1 + cosine ) - 1 );
372 double xs = x1 + k * xa / lena - xc;
373 double ys = y1 + k * ya / lena - yc;
374 double xe = x1 + k * xb / lenb - xc;
375 double ye = y1 + k * yb / lenb - yc;
378 double argument = ( xs * xe + ys * ye ) / (
radius *
radius );
384 else if( argument > 1 )
387 double arcAngle = acos( argument );
391 double deltaAngle = arcAngle / segments;
392 double startAngle = atan2( -ys, xs );
395 if( xa * yb - ya * xb <= 0 )
401 if( std::isnan( nx ) || std::isnan( ny ) )
410 for(
int j = 0; j < segments; j++ )
412 nx = xc + cos( startAngle + ( j + 1 ) * deltaAngle ) *
radius;
413 ny = yc - sin( startAngle + ( j + 1 ) * deltaAngle ) *
radius;
415 if( std::isnan( nx ) || std::isnan( ny ) )
431 newPoly.push_back( newContour );
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Represent basic circle geometry with utility geometry functions.
bool IsHorizontal() const
int Length() const
Return the length (this).
EDA_ANGLE Angle(const SEG &aOther) const
Determine the smallest angle between two segments.
EDA_ANGLE GetCentralAngle() const
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
CORNER_MODE
Operation ChamferPolygon and FilletPolygon are computed under the private chamferFillet method; this ...
POLYGON & Polygon(int aIndex)
Return the aIndex-th subpolygon in the set.
int RemoveNullSegments()
Look for null segments; ie, segments whose ends are exactly the same and deletes them.
std::vector< SHAPE_LINE_CHAIN > POLYGON
represents a single polygon outline with holes.
POLYGON chamferFilletPolygon(CORNER_MODE aMode, unsigned int aDistance, int aIndex, int aErrorMax)
Return the chamfered or filleted version of the aIndex-th polygon in the set, depending on the aMode ...
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
std::optional< CHAMFER_RESULT > ComputeChamferPoints(const SEG &aSegA, const SEG &aSegB, const CHAMFER_PARAMS &aChamferParams)
Compute the chamfer points for a given line pair and chamfer parameters.
std::optional< DOGBONE_RESULT > ComputeDogbone(const SEG &aSegA, const SEG &aSegB, int aDogboneRadius, bool aAddSlots)
Compute the dogbone geometry for a given line pair and dogbone parameters.
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_180
a few functions useful in geometry calculations.
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
OPT_VECTOR2I GetSharedEndpoint(const SEG &aSegA, const SEG &aSegB)
Get the shared endpoint of two segments, if it exists, or std::nullopt if the segments are not connec...
bool PointsAreInSameDirection(const VECTOR2< T > &aPointA, const VECTOR2< T > &aPointB, const VECTOR2< T > &aFrom)
Check that the two given points are in the same direction from some other point.
const VECTOR2I & GetOtherEnd(const SEG &aSeg, const VECTOR2I &aPoint)
Get the end point of the segment that is not the given point.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
std::optional< VECTOR2I > OPT_VECTOR2I
Utility functions for working with shapes.
Parameters that define a simple chamfer operation.
int m_chamfer_setback_b
Chamfer set-back distance along the second line.
int m_chamfer_setback_a
Chamfer set-back distance along the first line.
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
VECTOR2I GetRotated(const VECTOR2I &aVector, const EDA_ANGLE &aAngle)
Return a new VECTOR2I that is the result of rotating aVector by aAngle.
VECTOR2< int32_t > VECTOR2I
Supplemental functions for working with vectors and simple objects that interact with vectors.