Ejemplo n.º 1
0
QPointF RoundCornersCommand::tangentAtEnd( const KoPathSegment &s )
{
    QList<QPointF> cp = s.controlPoints();
    QPointF tn = cp[cp.count()-2] - cp.last();
    qreal length = sqrt( tn.x()*tn.x() + tn.y()*tn.y() );
    return tn / length;
}
Ejemplo n.º 2
0
QPointF RoundCornersCommand::tangentAtStart(const KoPathSegment &s)
{
    QVector<QPointF> cp = s.controlPoints();
    QPointF tn = cp[1] - cp.first();
    qreal length = sqrt(tn.x() * tn.x() + tn.y() * tn.y());
    return tn / length;
}
Ejemplo n.º 3
0
void KoPathSegmentChangeStrategy::handleMouseMove(const QPointF &mouseLocation, Qt::KeyboardModifiers modifiers)
{
    m_tool->canvas()->updateCanvas(m_tool->canvas()->snapGuide()->boundingRect());
    QPointF snappedPosition = m_tool->canvas()->snapGuide()->snap(mouseLocation, modifiers);
    m_tool->canvas()->updateCanvas(m_tool->canvas()->snapGuide()->boundingRect());

    QPointF localPos = m_path->documentToShape(snappedPosition);

    if (m_segment.degree() == 1) {
        // line segment is converted to a curve
        KoPathSegmentTypeCommand cmd(m_pointData1, KoPathSegmentTypeCommand::Curve);
        cmd.redo();
    }

    QPointF move1, move2;

    if (m_segment.degree() == 2) {
        // interpolate quadratic segment between segment start, mouse position and segment end
        KoPathSegment ipol = KoPathSegment::interpolate(m_segment.first()->point(),
                                                         localPos,
                                                         m_segment.second()->point(),
                                                         m_segmentParam);
        if (ipol.isValid()) {
            move1 = move2 = ipol.controlPoints()[1] - m_segment.controlPoints()[1];
        }
    }
    else if (m_segment.degree() == 3) {
        /*
        * method from inkscape, original method and idea borrowed from Simon Budig
        * <*****@*****.**> and the GIMP
        * cf. app/vectors/gimpbezierstroke.c, gimp_bezier_stroke_point_move_relative()
        *
        * feel good is an arbitrary parameter that distributes the delta between handles
        * if t of the drag point is less than 1/6 distance form the endpoint only
        * the corresponding handle is adjusted. This matches the behavior in GIMP
        */
        const qreal t = m_segmentParam;
        qreal feel_good;
        if (t <= 1.0 / 6.0)
            feel_good = 0;
        else if (t <= 0.5)
            feel_good = (pow((6 * t - 1) / 2.0, 3)) / 2;
        else if (t <= 5.0 / 6.0)
            feel_good = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5;
        else
            feel_good = 1;

        QPointF lastLocalPos = m_path->documentToShape(m_lastPosition);
        QPointF delta = localPos - lastLocalPos;
        move2 = ((1-feel_good)/(3*t*(1-t)*(1-t))) * delta;
        move1 = (feel_good/(3*t*t*(1-t))) * delta;
    }

    m_path->update();
    if(m_segment.first()->activeControlPoint2()) {
        KoPathControlPointMoveCommand cmd(m_pointData1, move2, KoPathPoint::ControlPoint2);
        cmd.redo();
    }
    if(m_segment.second()->activeControlPoint1()) {
        KoPathControlPointMoveCommand cmd(m_pointData2, move1, KoPathPoint::ControlPoint1);
        cmd.redo();
    }
    m_path->normalize();
    m_path->update();

    m_ctrlPoint1Move += move1;
    m_ctrlPoint2Move += move2;

    // save last mouse position
    m_lastPosition = mouseLocation;
}