Suche nach dem Schnittpunkt zwischen einer Linie und einer QPainterPath

Ich versuche, den Punkt zu ermitteln, wo ein hitscan Projektil Weg (im Grunde eine Linie, aber ich habe Sie dargestellt als QPainterPath in meinem Beispiel) schneidet mit einem Punkt in meiner Szene. Ich bin nicht sicher, ob es eine Möglichkeit gibt, diesen Punkt zu finden mit den Funktionen QPainterPath, QLineF usw. Der folgende code veranschaulicht, was ich versuche zu tun:

#include <QtWidgets>

bool hit(const QPainterPath &projectilePath, QGraphicsScene *scene, QPointF &hitPos)
{
    const QList<QGraphicsItem *> itemsInPath = scene->items(projectilePath, Qt::IntersectsItemBoundingRect);
    if (!itemsInPath.isEmpty()) {
        const QPointF projectileStartPos = projectilePath.elementAt(0);
        float shortestDistance = std::numeric_limits<float>::max();
        QGraphicsItem *closest = 0;
        foreach (QGraphicsItem *item, itemsInPath) {
            QPointF distanceAsPoint = item->pos() - projectileStartPos;
            float distance = abs(distanceAsPoint.x() + distanceAsPoint.y());
            if (distance < shortestDistance) {
                shortestDistance = distance;
                closest = item;
            }
        }
        QPainterPath targetShape = closest->mapToScene(closest->shape());
        //hitPos = /* the point at which projectilePath hits targetShape */
        hitPos = closest->pos(); //incorrect; always gives top left
        qDebug() << projectilePath.intersects(targetShape); //true
        qDebug() << projectilePath.intersected(targetShape); //QPainterPath: Element count=0
        //To show that they do actually intersect..
        QPen p1(Qt::green);
        p1.setWidth(2);
        QPen p2(Qt::blue);
        p2.setWidth(2);
        scene->addPath(projectilePath, p1);
        scene->addPath(targetShape, p2);
        return true;
    }
    return false;
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QGraphicsView view;
    view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
    QGraphicsScene *scene = new QGraphicsScene;
    view.setScene(scene);
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    QGraphicsItem *target = scene->addRect(0, 0, 25, 25);
    target->setTransformOriginPoint(QPointF(12.5, 12.5));
    target->setRotation(35);
    target->setPos(100, 100);

    QPainterPath projectilePath;
    projectilePath.moveTo(200, 200);
    projectilePath.lineTo(0, 0);
    projectilePath.lineTo(200, 200);

    QPointF hitPos;
    if (hit(projectilePath, scene, hitPos)) {
        scene->addEllipse(hitPos.x() - 2, hitPos.y() - 2, 4, 4, QPen(Qt::red));
    }

    scene->addPath(projectilePath, QPen(Qt::DashLine));
    scene->addText("start")->setPos(180, 150);
    scene->addText("end")->setPos(20, 0);

    view.show();

    return app.exec();
}

projectilePath.intersects(targetShape) zurück true, aber projectilePath.intersected(targetShape) gibt einen leeren Pfad.

Gibt es eine Möglichkeit, dies zu erreichen?

InformationsquelleAutor Mitch | 2013-07-07
Schreibe einen Kommentar