Prevent creating arcs with slightly offset endpoints

This commit is contained in:
Jon Evans 2020-12-31 11:56:49 -05:00
parent 566ada2c0e
commit fbdf31d35a
3 changed files with 41 additions and 14 deletions

View File

@ -46,7 +46,8 @@ public:
{}; {};
/** /**
* SHAPE_ARC ctor. * SHAPE_ARC ctor using center, start, angle. Center and angle are used to calculate the mid
* and end points of the arc, and are not stored
* @param aArcCenter is the arc center * @param aArcCenter is the arc center
* @param aArcStartPoint is the arc start point * @param aArcStartPoint is the arc start point
* @param aCenterAngle is the arc angle in degrees * @param aCenterAngle is the arc angle in degrees
@ -84,6 +85,17 @@ public:
return new SHAPE_ARC( *this ); return new SHAPE_ARC( *this );
} }
/**
* Constructs this arc from the given start, end and angle.
* @param aStart is the arc starting point
* @param aEnd is the arc endpoint
* @param aAngle is the arc included angle
* @param aWidth is the arc line thickness
* @return *this
*/
SHAPE_ARC& ConstructFromStartEndAngle( const VECTOR2I& aStart, const VECTOR2I& aEnd,
double aAngle, double aWidth = 0 );
const VECTOR2I& GetP0() const { return m_start; } const VECTOR2I& GetP0() const { return m_start; }
const VECTOR2I& GetP1() const { return m_end; } const VECTOR2I& GetP1() const { return m_end; }
const VECTOR2I& GetArcMid() const { return m_mid; } const VECTOR2I& GetArcMid() const { return m_mid; }

View File

@ -66,7 +66,6 @@ const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, con
* the distance from A to aP1 (diagLength) to calculate the radius of the arc. * the distance from A to aP1 (diagLength) to calculate the radius of the arc.
*/ */
VECTOR2I arcStart, arcCenter;
int tangentLength; int tangentLength;
if( w > h ) if( w > h )
@ -87,6 +86,9 @@ const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, con
// TODO: if tangentLength zero, we could still place a small arc at the start... // TODO: if tangentLength zero, we could still place a small arc at the start...
if( aFillet ) if( aFillet )
{ {
VECTOR2I arcStart;
VECTOR2D arcCenter;
double diag2 = tangentLength >= 0 ? mp1.SquaredEuclideanNorm() : mp0.SquaredEuclideanNorm(); double diag2 = tangentLength >= 0 ? mp1.SquaredEuclideanNorm() : mp0.SquaredEuclideanNorm();
double diagLength = std::sqrt( ( 2 * diag2 ) - ( 2 * diag2 * std::cos( 3 * M_PI_4 ) ) ); double diagLength = std::sqrt( ( 2 * diag2 ) - ( 2 * diag2 * std::cos( 3 * M_PI_4 ) ) );
int arcRadius = KiROUND( diagLength / ( 2.0 * std::cos( 67.5 * M_PI / 180.0 ) ) ); int arcRadius = KiROUND( diagLength / ( 2.0 * std::cos( 67.5 * M_PI / 180.0 ) ) );
@ -107,7 +109,6 @@ const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, con
arcStart = aP0 + mp1 + mp0.Resize( mp1.EuclideanNorm() ); arcStart = aP0 + mp1 + mp0.Resize( mp1.EuclideanNorm() );
arcCenter = arcStart + centerDir.Resize( arcRadius ); arcCenter = arcStart + centerDir.Resize( arcRadius );
SHAPE_ARC new_arc( arcCenter, aP0, 45 * rotationSign ); SHAPE_ARC new_arc( arcCenter, aP0, 45 * rotationSign );
pl.Append( new_arc ); pl.Append( new_arc );
pl.Append( aP1 ); pl.Append( aP1 );
} }
@ -116,14 +117,12 @@ const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, con
// Negative tangentLength, diagonal start: arc goes at the end // Negative tangentLength, diagonal start: arc goes at the end
arcStart = aP0 + mp1.Resize( std::abs( tangentLength ) ); arcStart = aP0 + mp1.Resize( std::abs( tangentLength ) );
arcCenter = aP1 + centerDir.Resize( arcRadius ); arcCenter = aP1 + centerDir.Resize( arcRadius );
SHAPE_ARC new_arc( arcCenter, arcStart, 45 * rotationSign );
SHAPE_ARC new_arc;
new_arc.ConstructFromStartEndAngle( arcStart, aP1, 45 * rotationSign );
pl.Append( aP0 ); pl.Append( aP0 );
pl.Append( new_arc ); pl.Append( new_arc );
// TODO: nicer way of fixing these up
if( new_arc.GetP1() != aP1 )
pl.Replace( -1, -1, aP1 );
} }
} }
else else
@ -136,14 +135,12 @@ const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, con
// Positive tangentLength: arc goes at the end // Positive tangentLength: arc goes at the end
arcStart = aP0 + mp0.Resize( tangentLength ); arcStart = aP0 + mp0.Resize( tangentLength );
arcCenter = arcStart + centerDir.Resize( arcRadius ); arcCenter = arcStart + centerDir.Resize( arcRadius );
SHAPE_ARC new_arc( arcCenter, arcStart, 45 * rotationSign );
SHAPE_ARC new_arc;
new_arc.ConstructFromStartEndAngle( arcStart, aP1, 45 * rotationSign );
pl.Append( aP0 ); pl.Append( aP0 );
pl.Append( new_arc ); pl.Append( new_arc );
// TODO: nicer way of fixing these up
if( new_arc.GetP1() != aP1 )
pl.Replace( -1, -1, aP1 );
} }
else else
{ {

View File

@ -32,7 +32,7 @@
SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint, SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint,
double aCenterAngle, int aWidth ) : double aCenterAngle, int aWidth ) :
SHAPE( SH_ARC ), m_width( aWidth ) SHAPE( SH_ARC ), m_width( aWidth )
{ {
m_start = aArcStartPoint; m_start = aArcStartPoint;
m_mid = aArcStartPoint; m_mid = aArcStartPoint;
@ -170,6 +170,24 @@ SHAPE_ARC::SHAPE_ARC( const SHAPE_ARC& aOther )
} }
SHAPE_ARC& SHAPE_ARC::ConstructFromStartEndAngle( const VECTOR2I& aStart, const VECTOR2I& aEnd,
double aAngle, double aWidth )
{
m_start = aStart;
m_mid = aStart;
m_end = aEnd;
m_width = aWidth;
VECTOR2I center( GetArcCenter( aStart, aEnd, aAngle ) );
RotatePoint( m_mid, center, -aAngle * 10.0 / 2.0 );
update_bbox();
return *this;
}
bool SHAPE_ARC::Collide( const SEG& aSeg, int aClearance, int* aActual, VECTOR2I* aLocation ) const bool SHAPE_ARC::Collide( const SEG& aSeg, int aClearance, int* aActual, VECTOR2I* aLocation ) const
{ {
int minDist = aClearance + m_width / 2; int minDist = aClearance + m_width / 2;