/**
 * Draw labelled ticks on a line. Ticks are spaced according to a
 * maximum density. Miror ticks are not labelled.
 *
 * @param aGal the GAL to draw on
 * @param aOrigin start of line to draw ticks on
 * @param aLine line vector
 * @param aMinorTickLen length of minor ticks in IU
 */
void drawTicksAlongLine( KIGFX::GAL& aGal, const VECTOR2D& aOrigin,
        const VECTOR2D& aLine, double aMinorTickLen )
{
    VECTOR2D tickLine = aLine.Rotate( -M_PI_2 );

    double tickSpace;
    TICK_FORMAT tickF = getTickFormatForScale( aGal.GetWorldScale(), tickSpace );

    // number of ticks in whole ruler
    int numTicks = (int) std::ceil( aLine.EuclideanNorm() / tickSpace );

    // work out which way up the tick labels go
    double labelAngle = -tickLine.Angle();

    if( aLine.Angle() > 0 )
    {
        aGal.SetHorizontalJustify( GR_TEXT_HJUSTIFY_LEFT );
    }
    else
    {
        aGal.SetHorizontalJustify( GR_TEXT_HJUSTIFY_RIGHT );
        labelAngle += M_PI;
    }

    // text and ticks are dimmed
    aGal.SetStrokeColor( PreviewOverlayDefaultColor().WithAlpha( PreviewOverlayDeemphAlpha( true ) ) );

    const auto labelOffset = tickLine.Resize( aMinorTickLen * ( majorTickLengthFactor + 1 ) );

    for( int i = 0; i < numTicks; ++i )
    {
        const auto tickPos = aOrigin + aLine.Resize( tickSpace * i );

        double length = aMinorTickLen;
        bool drawLabel = false;

        if( i % tickF.majorStep == 0)
        {
            drawLabel = true;
            length *= majorTickLengthFactor;
        }
        else if( tickF.midStep && i % tickF.midStep == 0 )
        {
            drawLabel = true;
            length *= midTickLengthFactor;
        }

        aGal.DrawLine( tickPos, tickPos + tickLine.Resize( length ) );

        if( drawLabel )
        {
            wxString label = DimensionLabel( "", tickSpace * i, g_UserUnit );

            // FIXME: spaces choke OpenGL lp:1668455
            label.erase( std::remove( label.begin(), label.end(), ' ' ), label.end() );

            aGal.BitmapText( label, tickPos + labelOffset, labelAngle );
        }
    }
}
/**
 * Draw simple ticks on the back of a line such that the line is
 * divided into n parts.
 *
 * @param aGal the GAL to draw on
 * @param aOrigin start of line to draw ticks on
 * @param aLine line vector
 * @param aTickLen length of ticks in IU
 * @param aNumDivisions number of parts to divide the line into
 */
void drawBacksideTicks( KIGFX::GAL& aGal, const VECTOR2D& aOrigin,
        const VECTOR2D& aLine, double aTickLen, int aNumDivisions )
{
    const double backTickSpace = aLine.EuclideanNorm() / aNumDivisions;
    const auto backTickVec = aLine.Rotate( M_PI_2 ).Resize( aTickLen );

    for( int i = 0; i < aNumDivisions + 1; ++i )
    {
        const auto backTickPos = aOrigin + aLine.Resize( backTickSpace * i );
        aGal.DrawLine( backTickPos, backTickPos + backTickVec );
    }
}
Ejemplo n.º 3
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;
}