Пример #1
0
void POLYGON_GEOM_MANAGER::updateLeaderPoints( const VECTOR2I& aEndPoint )
{
    SHAPE_LINE_CHAIN newChain;

    if( m_leaderMode == LEADER_MODE::DEG45 )
    {
        // get a restricted 45/H/V line from the last fixed point to the cursor
        DIRECTION_45 direction( m_lockedPoints.back() - aEndPoint );
        newChain = direction.BuildInitialTrace( m_lockedPoints.back(), aEndPoint );

        // Can also add chain back to start, but this rearely produces
        // usable result
        //DIRECTION_45 directionToStart( aEndPoint - m_lockedPoints.front() );
        //newChain.Append( directionToStart.BuildInitialTrace( aEndPoint, m_lockedPoints.front() ) );
    }
    else
    {
        // direct segment
        newChain = SHAPE_LINE_CHAIN( m_lockedPoints.back(), aEndPoint );
    }

    // rebuild leader point list from the chain
    m_leaderPts.clear();

    for( int i = 0; i < newChain.PointCount(); ++i )
    {
        m_leaderPts.push_back( newChain.Point( i ) );
    }

    m_client.OnGeometryChange( *this );
}
Пример #2
0
/**
 * Function TestLineChainEqualCPolyLine
 * tests the equality between a SHAPE_LINE_CHAIN polygon and a polygon inside a
 * CPolyLine object using Boost test suite.
 * @param lineChain is a SHAPE_LINE_CHAIN polygon object.
 * @param polyLine  is a CPolyLine polygon object.
 * @param contourIdx is the index of the contour inside polyLine that has to be tested
 *                   against lineChain.
 */
void TestLineChainEqualCPolyLine(SHAPE_LINE_CHAIN& lineChain, CPolyLine& polyLine,
                                 int contourIdx = 0)
{
    // Arrays to store the polygon points lexicographically ordered
    std::vector<VECTOR2I> chainPoints;
    std::vector<VECTOR2I> polyPoints;

    // Populate the array storing the new data with the lineChain corners
    for (int pointIdx = 0; pointIdx < lineChain.PointCount(); pointIdx++) {
        chainPoints.push_back(lineChain.Point(pointIdx));
    }

    int start = polyLine.GetContourStart(contourIdx);
    int end = polyLine.GetContourEnd(contourIdx);

    // Populate the array storing the legacy data with the polyLine corners
    for (int pointIdx = start; pointIdx <= end; pointIdx++) {
        polyPoints.push_back( VECTOR2I(polyLine.GetX(pointIdx), polyLine.GetY(pointIdx)) );
    }

    // Order the vectors in a lexicographic way
    std::sort(chainPoints.begin(), chainPoints.end(), lexicographicOrder);
    std::sort(polyPoints.begin(), polyPoints.end(), lexicographicOrder);

    // Compare every point coordinate to check the equality
    BOOST_CHECK_EQUAL_COLLECTIONS(chainPoints.begin(), chainPoints.end(),
                                  polyPoints.begin(), polyPoints.end());
}
bool PNS_LINE_PLACER::buildInitialLine( const VECTOR2I& aP, PNS_LINE& aHead )
{
    SHAPE_LINE_CHAIN l;

    if( m_p_start == aP )
    {
        l.Clear();
    }
    else
    {
        if( Settings().GetFreeAngleMode() && Settings().Mode() == RM_MarkObstacles )
        {
            l = SHAPE_LINE_CHAIN( m_p_start, aP );
        }
        else
        {
            l = m_direction.BuildInitialTrace( m_p_start, aP );
        }

        if( l.SegmentCount() > 1 && m_orthoMode )
        {
            VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );

            l.Remove( -1, -1 );
            l.Point( 1 ) = newLast;
        }
    }

    aHead.SetShape( l );

    if( !m_placingVia )
        return true;

    PNS_VIA v( makeVia( aP ) );
    v.SetNet( aHead.Net() );

    if( m_currentMode == RM_MarkObstacles )
    {
        aHead.AppendVia( v );
        return true;
    }

    VECTOR2I force;
    VECTOR2I lead = aP - m_p_start;

    bool solidsOnly = ( m_currentMode != RM_Walkaround );

    if( v.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
    {
        SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP + force );
        aHead = PNS_LINE( aHead, line );

        v.SetPos( v.Pos() + force );
        return true;
    }

    return false; // via placement unsuccessful
}
Пример #4
0
void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const
{
    VECTOR2I cursorPos = m_controls->GetCursorPosition();
    VECTOR2I origin( aSegment->GetStart() );
    DIRECTION_45 direction( origin - cursorPos );
    SHAPE_LINE_CHAIN newChain = direction.BuildInitialTrace( origin, cursorPos );

    if( newChain.PointCount() > 2 )
    {
        aSegment->SetEnd( wxPoint( newChain.Point( -2 ).x, newChain.Point( -2 ).y ) );
        aHelper->SetStart( wxPoint( newChain.Point( -2 ).x, newChain.Point( -2 ).y ) );
        aHelper->SetEnd( wxPoint( newChain.Point( -1 ).x, newChain.Point( -1 ).y ) );
    }
    else
    {
        aSegment->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
        aHelper->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
        aHelper->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
    }
}
Пример #5
0
SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape( VECTOR2D aP, VECTOR2D aDir,
        bool aSide, PNS_MEANDER_TYPE aType, int aAmpl, int aBaselineOffset )
{
    const PNS_MEANDER_SETTINGS& st = Settings();
    int cr = cornerRadius();
    int offset = aBaselineOffset;
    int spc = spacing();

    if( aSide )
        offset *= -1;

    VECTOR2D dir_u_b( aDir.Resize( offset ) );
    VECTOR2D dir_v_b( dir_u_b.Perpendicular() );

    if( 2 * cr > aAmpl )
    {
        cr = aAmpl / 2;
    }

    if( 2 * cr > spc )
    {
        cr = spc / 2;
    }

    SHAPE_LINE_CHAIN lc;

    start( &lc, aP + dir_v_b, aDir );

    switch( aType )
    {
        case MT_EMPTY:
        {
            lc.Append( aP + dir_v_b + aDir );
            break;
        }
        case MT_START:
        {
            arc( cr - offset, false );
            uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
            forward( std::min( cr - offset, cr + offset ) );
            forward( std::abs( offset ) );

            break;
        }

        case MT_FINISH:
        {
            start( &lc, aP - dir_u_b, aDir );
            turn ( 90 );
            forward( std::min( cr - offset, cr + offset ) );
            forward( std::abs( offset ) );
            uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
            arc( cr - offset, false );
            break;
        }

        case MT_TURN:
        {
            start( &lc, aP - dir_u_b, aDir );
            turn( 90 );
            forward( std::abs( offset ) );
            uShape ( aAmpl - cr, cr + offset, spc - 2 * cr );
            forward( std::abs( offset ) );
            break;
        }

        case MT_SINGLE:
        {
            arc( cr - offset, false );
            uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
            arc( cr - offset, false );
            lc.Append( aP + dir_v_b + aDir.Resize ( 2 * st.m_spacing ) );
            break;
        }

        default:
            break;
    }

    if( aSide )
    {
        SEG axis ( aP, aP + aDir );

        for( int i = 0; i < lc.PointCount(); i++ )
            lc.Point( i ) = reflect( lc.CPoint( i ), axis );
    }

    return lc;
}