diff --git a/libs/kimath/include/geometry/shape_arc.h b/libs/kimath/include/geometry/shape_arc.h index a87a5c6e0e..95055029db 100644 --- a/libs/kimath/include/geometry/shape_arc.h +++ b/libs/kimath/include/geometry/shape_arc.h @@ -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 aArcStartPoint is the arc start point * @param aCenterAngle is the arc angle in degrees @@ -84,6 +85,17 @@ public: 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& GetP1() const { return m_end; } const VECTOR2I& GetArcMid() const { return m_mid; } diff --git a/libs/kimath/src/geometry/direction_45.cpp b/libs/kimath/src/geometry/direction_45.cpp index 45eee1bd3e..3a2018f2e6 100644 --- a/libs/kimath/src/geometry/direction_45.cpp +++ b/libs/kimath/src/geometry/direction_45.cpp @@ -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. */ - VECTOR2I arcStart, arcCenter; int tangentLength; 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... if( aFillet ) { + VECTOR2I arcStart; + VECTOR2D arcCenter; + double diag2 = tangentLength >= 0 ? mp1.SquaredEuclideanNorm() : mp0.SquaredEuclideanNorm(); 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 ) ) ); @@ -107,7 +109,6 @@ const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, con arcStart = aP0 + mp1 + mp0.Resize( mp1.EuclideanNorm() ); arcCenter = arcStart + centerDir.Resize( arcRadius ); SHAPE_ARC new_arc( arcCenter, aP0, 45 * rotationSign ); - pl.Append( new_arc ); 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 arcStart = aP0 + mp1.Resize( std::abs( tangentLength ) ); 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( new_arc ); - - // TODO: nicer way of fixing these up - if( new_arc.GetP1() != aP1 ) - pl.Replace( -1, -1, aP1 ); } } else @@ -136,14 +135,12 @@ const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, con // Positive tangentLength: arc goes at the end arcStart = aP0 + mp0.Resize( tangentLength ); 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( new_arc ); - - // TODO: nicer way of fixing these up - if( new_arc.GetP1() != aP1 ) - pl.Replace( -1, -1, aP1 ); } else { diff --git a/libs/kimath/src/geometry/shape_arc.cpp b/libs/kimath/src/geometry/shape_arc.cpp index da40fedba1..7d16963e68 100644 --- a/libs/kimath/src/geometry/shape_arc.cpp +++ b/libs/kimath/src/geometry/shape_arc.cpp @@ -32,7 +32,7 @@ SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint, double aCenterAngle, int aWidth ) : - SHAPE( SH_ARC ), m_width( aWidth ) + SHAPE( SH_ARC ), m_width( aWidth ) { m_start = 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 { int minDist = aClearance + m_width / 2;