0

Qtで曲線を描く必要があります:ユーザーが(QGraphicsViewを介して)QGraphicsSceneをクリックすると、ユーザーがクリックしたポイント間に直線が描画されます。ユーザーが(右ボタンをクリックして)直線を描き終えると、線のセットは曲線になります。

そのためには、QPainterPath::cubicTo(...)メソッドを使用し、を使用してQGraphicsSceneへのパスを追加する必要がありますQGraphicsScene::addPath(...)

問題は、に渡されるパラメータ値を計算する方法がわからないことcubicTo(...)です。

たとえば、次の図では、ユーザーは点ABとCをクリックして2本の灰色の線を描画しています。右ボタンをクリックすると、次のコマンドを使用して赤い線を描画しますcubicTo(...)

意図した線と曲線

ユーザーがクリックしたポイント位置に、、、および値をc1設定しc2d1ため、現在のコードは灰色の線のみを描画します。d2

void Visuel::mousePressEvent(QMouseEvent *event)
{
    int x = ((float)event->pos().x()/(float)this->rect().width())*(float)scene()->sceneRect().width();
    int y = ((float)event->pos().y()/(float)this->rect().height())*(float)scene()->sceneRect().height();
    qDebug() << x << y;

    if(event->button() == Qt::LeftButton)
    {
        path->cubicTo(x,y,x,y,x,y);
    }
    if(event->button() == Qt::RightButton)
    {
        if(path == NULL)
        {
            path = new QPainterPath();
            path->moveTo(x,y);

        }
        else
        {

            path->cubicTo(x,y,x,y,x,y);
            scene()->addPath(*path,QPen(QColor(79, 106, 25)));
            path = NULL;
        }
    }
}
4

1 に答える 1

1

どうやら制御点 c1、c2、d1、d2 は、写真の点 B の座標にすぎません。より一般的な場合、点 C は AB 線上にあり、点 D は BC 線上にあります。

Qt コードでは、これは次のように記述できます。 Visuel クラスには次のプロパティが必要です。

QPoint A, B, C;
unsigned int count;

Visuel のコンストラクターで初期化する必要があります。

void Visuel::Visuel()
{
    count = 0;
    // Initialize other stuff as well
}

次に、QGraphicsScene::mousePressEvent() をオーバーロードして、ユーザーのマウス イベントを検出します。

void Visuel::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    /* Ignore everything else except left button's press */
    if (event->type() != QEvent::GraphicsSceneMousePress ||
        event->button() != Qt::LeftButton) {
        return;
    }
    switch (count) {
    case 0:
        A = event->scenePos();
        break;
    case 1: {
        B = event->scenePos();

        /* Draw AB line */
        QPainterPath path(A);
        path.lineTo(B);
        scene()->addPath(path, Qt::grey);
        }
        break;
    case 2: {
        C = event->scenePos();

        /* Draw BC line */
        QPainterPath path(B);
        path.lineTo(C);
        scene()->addPath(path, Qt::grey);

        /* Draw ABBC cubic Bezier curve */
        QPainterPath path2(A);
        path2.cubicTo(B, B, C);
        scene()->addPath(path2, Qt::red);
        }
        break;
    default:
        break;
    }
    if (count >= 2) {
        count = 0;
    } else {
        count++;
    }
}
于 2012-10-22T12:33:51.623 に答える