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?
- Sind Sie mit Qt 4 oder Qt 5. Es kann gut sein, um mehr bestimmten tag, um Ihre Frage.
- Duplikat von: stackoverflow.com/questions/9393672/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als Antwort auf Schnittpunkt von QPainterPath und line (finden QPainterPath y durch x) Punkte aus, QPainterPath::Durchschnitt() nur Konten für Wege, die Bereiche füllen. Die rechteckigen Pfad trick, das ist auch erwähnt, es kann implementiert werden, wie diesen:
Dieser hat ziemlich gute Genauigkeit (± 1 pixel, da QLineF::length() ist eine ganze Zahl), aber es könnte ein eleganter Weg, das gleiche zu erreichen.
Nur für das Protokoll (und wenn jemand anderes Schritte hier). Die obige Antwort ist ausgezeichnet. Es gibt nur einen kleinen Fehler in der closestPoint-Funktion passiert, wenn der erste Punkt ist bereits der nächste. Es sollte return elementAt(0) anstelle von elementAt(0) - Ziel.
Hier ist die Feste Funktion: