Commit 0459b4da authored by jean-pierre charras's avatar jean-pierre charras
Browse files

Pcbnew: fix incorrect detection of arcs having angles != 90 degrees

parent b7c56494
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -376,8 +376,8 @@ wxString BOARD::GetLayerName( int aLayerIndex, bool aTranslate ) const




// Default layer names are statically initialized,
// Default layer names are statically initialized,
// because we want the Enghish name and the translation
// because we want the English name and the translation
// The Enghish name is stored here, and to get the tranlation
// The English name is stored here, and to get the tranlation
// wxGetTranslation must be called explicitely
// wxGetTranslation must be called explicitely
static const wxChar * layer_FRONT_name  = _( "Front" );
static const wxChar * layer_FRONT_name  = _( "Front" );
static const wxChar * layer_INNER1_name = _( "Inner1" );
static const wxChar * layer_INNER1_name = _( "Inner1" );
+41 −49
Original line number Original line Diff line number Diff line
@@ -112,7 +112,6 @@ void DRAWSEGMENT::Flip( const wxPoint& aCentre )
    SetLayer( BOARD::ReturnFlippedLayerNumber( GetLayer() ) );
    SetLayer( BOARD::ReturnFlippedLayerNumber( GetLayer() ) );
}
}



const wxPoint DRAWSEGMENT::GetArcEnd() const
const wxPoint DRAWSEGMENT::GetArcEnd() const
{
{
    wxPoint endPoint;         // start of arc
    wxPoint endPoint;         // start of arc
@@ -134,44 +133,22 @@ const wxPoint DRAWSEGMENT::GetArcEnd() const
    return endPoint;   // after rotation, the end of the arc.
    return endPoint;   // after rotation, the end of the arc.
}
}



const double DRAWSEGMENT::GetArcAngleStart() const
/* use GetArcStart() now
const wxPoint DRAWSEGMENT::GetStart() const
{
{
    switch( m_Shape )
    // due to the Y axis orient atan2 needs - y value
    {
    double angleStart = atan2( (double)(GetArcStart().y - GetCenter().y),
    case S_ARC:
                               (double)(GetArcStart().x - GetCenter().x) );
        return m_End;  // the start of the arc is held in field m_End, center point is in m_Start.
    // angleStart is in radians, convert it in 1/10 degrees

    angleStart = angleStart / M_PI * 1800.0;
    case S_SEGMENT:
    default:
        return m_Start;
    }
}


    // Normalize it to 0 ... 360 deg, to avoid discontinuity for angles near 180 deg
    // because 180 deg and -180 are very near angles when ampping betewwen -180 ... 180 deg.
    // and this is not easy to handle in calculations
    if( angleStart < 0 )
        angleStart += 3600.0;


const wxPoint DRAWSEGMENT::GetEnd() const
    return angleStart;
{
    wxPoint endPoint;         // start of arc

    switch( m_Shape )
    {
    case S_ARC:
        // rotate the starting point of the arc, given by m_End, through the
        // angle m_Angle to get the ending point of the arc.
        // m_Start is the arc centre
        endPoint  = m_End;         // m_End = start point of arc
        RotatePoint( &endPoint, m_Start, -m_Angle );
        return endPoint;   // after rotation, the end of the arc.
        break;

    case S_SEGMENT:
    default:
        return m_End;
    }
}
}
*/



void DRAWSEGMENT::SetAngle( double aAngle )
void DRAWSEGMENT::SetAngle( double aAngle )
{
{
@@ -450,14 +427,12 @@ EDA_RECT DRAWSEGMENT::GetBoundingBox() const


bool DRAWSEGMENT::HitTest( const wxPoint& aPosition )
bool DRAWSEGMENT::HitTest( const wxPoint& aPosition )
{
{
    /* Calculate coordinates to test relative to segment origin. */
    wxPoint relPos = aPosition - m_Start;

    switch( m_Shape )
    switch( m_Shape )
    {
    {
    case S_CIRCLE:
    case S_CIRCLE:
    case S_ARC:
    case S_ARC:
        {
        {
            wxPoint relPos = aPosition - GetCenter();
            int radius = GetRadius();
            int radius = GetRadius();
            int dist  = (int) hypot( (double) relPos.x, (double) relPos.y );
            int dist  = (int) hypot( (double) relPos.x, (double) relPos.y );


@@ -466,19 +441,36 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition )
                if( m_Shape == S_CIRCLE )
                if( m_Shape == S_CIRCLE )
                    return true;
                    return true;


                wxPoint startVec = wxPoint( m_End.x - m_Start.x, m_End.y - m_Start.y );
                // For arcs, the test point angle must be >= arc angle start
                wxPoint endVec = m_End - m_Start;
                // and <= arc angle end
                RotatePoint( &endVec, -m_Angle );
                // However angle values > 360 deg are not easy to handle
                // so we calculate the relative angle between arc start point and teast point
                // this relative arc should be < arc angle if arc angle > 0 (CW arc)
                // and > arc angle if arc angle < 0 (CCW arc)
                double arc_angle_start = GetArcAngleStart();    // Always 0.0 ... 360 deg, in 0.1 deg


                // Check dot products
                double arc_hittest = atan2( (double) relPos.y, (double) relPos.x );
                if( (long long)relPos.x*startVec.x + (long long)relPos.y*startVec.y < 0 )
                arc_hittest = arc_hittest / M_PI * 1800;    // angles are in 1/10 deg
                    return false;


                if( (long long)relPos.x*endVec.x + (long long)relPos.y*endVec.y < 0 )
                // Calculate relative angle between the starting point of the arc, and the test point
                    return false;
                arc_hittest -= arc_angle_start;

                // Normalise arc_hittest between 0 ... 360 deg
                NORMALIZE_ANGLE_POS( arc_hittest );


                // Check angle: inside the arc angle when it is > 0
                // and outside the not drawn arc when it is < 0
                if( GetAngle() >= 0.0 )
                {
                    if( arc_hittest <= GetAngle() )
                        return true;
                        return true;
                }
                }
                else
                {
                    if( arc_hittest >= (3600.0 + GetAngle()) )
                        return true;
                }
            }
        }
        }
        break;
        break;


+6 −0
Original line number Original line Diff line number Diff line
@@ -120,6 +120,12 @@ public:
    const wxPoint& GetArcStart() const      { return m_End; }
    const wxPoint& GetArcStart() const      { return m_End; }
    const wxPoint GetArcEnd() const;
    const wxPoint GetArcEnd() const;


    /**
     * function GetArcAngleStart()
     * @return the angle of the stating point of this arc, between 0 and 3600 in 0.1 deg
     */
    const double GetArcAngleStart() const;

    /**
    /**
     * Function GetRadius
     * Function GetRadius
     * returns the radius of this item
     * returns the radius of this item