Fix some issues with new polygonization of arcs and arc collision test.
Test should not be testing against the polygonization error; if done correctly that should all be on the correct side of the shape. Use an epsilon instead (I chose polygonization error / 10, but the value isn't terribly important). Fixes https://gitlab.com/kicad/code/kicad/issues/10724
This commit is contained in:
parent
b7c31d3b5b
commit
3f8cada334
|
@ -583,6 +583,14 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aStar
|
||||||
EDA_ANGLE arc_angle_start = arc.GetStartAngle();
|
EDA_ANGLE arc_angle_start = arc.GetStartAngle();
|
||||||
EDA_ANGLE arc_angle = arc.GetCentralAngle();
|
EDA_ANGLE arc_angle = arc.GetCentralAngle();
|
||||||
EDA_ANGLE arc_angle_end = arc_angle_start + arc_angle;
|
EDA_ANGLE arc_angle_end = arc_angle_start + arc_angle;
|
||||||
|
EDA_ANGLE sweep = arc_angle < ANGLE_0 ? -ANGLE_180 : ANGLE_180;
|
||||||
|
|
||||||
|
if( arc_angle < ANGLE_0 )
|
||||||
|
{
|
||||||
|
std::swap( arc_angle_start, arc_angle_end );
|
||||||
|
arc = SHAPE_ARC( aEnd, aMid, aStart, aWidth );
|
||||||
|
arc_angle = -arc_angle;
|
||||||
|
}
|
||||||
|
|
||||||
int radial_offset = arc.GetWidth() / 2;
|
int radial_offset = arc.GetWidth() / 2;
|
||||||
int arc_outer_radius = arc.GetRadius() + radial_offset;
|
int arc_outer_radius = arc.GetRadius() + radial_offset;
|
||||||
|
@ -596,27 +604,24 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aStar
|
||||||
SHAPE_LINE_CHAIN& outline = polyshape.Outline( 0 );
|
SHAPE_LINE_CHAIN& outline = polyshape.Outline( 0 );
|
||||||
|
|
||||||
// Starting end
|
// Starting end
|
||||||
ConvertArcToPolyline( outline, arc.GetP0(), radial_offset, -arc_angle_start, ANGLE_180, aError,
|
ConvertArcToPolyline( outline, arc.GetP0(), radial_offset, arc_angle_start - ANGLE_180,
|
||||||
aErrorLoc );
|
ANGLE_180, aError, aErrorLoc );
|
||||||
|
|
||||||
// Outside edge
|
// Outside edge
|
||||||
ConvertArcToPolyline( outline, arc.GetCenter(), arc_outer_radius, arc_angle_start, arc_angle,
|
ConvertArcToPolyline( outline, arc.GetCenter(), arc_outer_radius, arc_angle_start, arc_angle,
|
||||||
aError, errorLocOuter );
|
aError, errorLocOuter );
|
||||||
|
|
||||||
// Other end
|
// Other end
|
||||||
ConvertArcToPolyline( outline, arc.GetP1(), radial_offset, -arc_angle_end, ANGLE_180, aError,
|
ConvertArcToPolyline( outline, arc.GetP1(), radial_offset, arc_angle_end, ANGLE_180, aError,
|
||||||
aErrorLoc );
|
aErrorLoc );
|
||||||
|
|
||||||
// Inside edge
|
// Inside edge
|
||||||
if( arc_inner_radius > 0 )
|
if( arc_inner_radius > 0 )
|
||||||
{
|
{
|
||||||
ConvertArcToPolyline( outline, arc.GetCenter(), arc_inner_radius, arc_angle_end, -arc_angle,
|
ConvertArcToPolyline( outline, arc.GetCenter(), arc_inner_radius, arc_angle_end,
|
||||||
aError, errorLocInner );
|
-arc_angle, aError, errorLocInner );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required. Otherwise Clipper has fits with duplicate points generating winding artefacts.
|
|
||||||
polyshape.Simplify( SHAPE_POLY_SET::PM_FAST );
|
|
||||||
|
|
||||||
aCornerBuffer.Append( polyshape );
|
aCornerBuffer.Append( polyshape );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -886,7 +886,7 @@ BOOST_AUTO_TEST_CASE( CollideArcToShapeLineChain )
|
||||||
BOOST_AUTO_TEST_CASE( CollideArcToPolygonApproximation )
|
BOOST_AUTO_TEST_CASE( CollideArcToPolygonApproximation )
|
||||||
{
|
{
|
||||||
SHAPE_ARC arc( VECTOR2I( 73843527, 74355869 ), VECTOR2I( 71713528, 72965869 ),
|
SHAPE_ARC arc( VECTOR2I( 73843527, 74355869 ), VECTOR2I( 71713528, 72965869 ),
|
||||||
EDA_ANGLE( -76.36664803, DEGREES_T ), 2000000 );
|
EDA_ANGLE( -76.36664803, DEGREES_T ), 1000000 );
|
||||||
|
|
||||||
// Create a polyset approximation from the arc - error outside (simulating the zone filler)
|
// Create a polyset approximation from the arc - error outside (simulating the zone filler)
|
||||||
SHAPE_POLY_SET arcBuffer;
|
SHAPE_POLY_SET arcBuffer;
|
||||||
|
@ -917,14 +917,11 @@ BOOST_AUTO_TEST_CASE( CollideArcToPolygonApproximation )
|
||||||
|
|
||||||
int actual = 0;
|
int actual = 0;
|
||||||
VECTOR2I location;
|
VECTOR2I location;
|
||||||
|
int epsilon = polygonApproximationError / 10;
|
||||||
|
|
||||||
int clearanceReduced = clearance - polygonApproximationError;
|
BOOST_CHECK_EQUAL( zoneFill.Collide( &arc, clearance + epsilon, &actual, &location ), true );
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL( zoneFill.Collide( &arc, clearanceReduced, &actual, &location ), false );
|
BOOST_CHECK_EQUAL( zoneFill.Collide( &arc, clearance - epsilon, &actual, &location ), false );
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL( zoneFill.Collide( &arc, clearance * 2, &actual, &location ), true );
|
|
||||||
|
|
||||||
BOOST_CHECK( KI_TEST::IsWithin( actual, clearance, polygonApproximationError ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue