我有一个应用程序,我在场景中放置了几条曲线。我正在寻找一种简单的方法来检测用户是否按下了线路。当我画多条线时太不准确了boundingRect()
。intersects()
所以我做了这个功能,除了线条是垂直的,它就像一个梦一样工作。
selectionMargin
是用户设置的全局变量(默认值 = 0.5)。它会调整边距,以确保选择检查的准确性。名称基于每个子线的线性函数,y = ax + b
。Pos 是 mousePressEvent 的位置。
bool GraphApp::pointInPath(QPainterPath path, QPointF pos)
{
qreal posY = pos.y();
qreal posX = pos.x();
for (int i = 0; i < path.elementCount()-1; ++i) {
if (posX < path.elementAt(i + 1).x && posX > path.elementAt(i).x) {
qreal dy = path.elementAt(i + 1).y - path.elementAt(i).y;
qreal dx = path.elementAt(i + 1).x - path.elementAt(i).x;
qreal a = dy / dx;
qreal b = path.elementAt(i).y - (path.elementAt(i).x * a);
if (selectionMargin == 0.0)
selectionMargin = 0.5;
qreal lowerBound = (a * posX + b) + selectionMargin;
qreal upperBound = (a * posX + b) - selectionMargin;
if (posY < lowerBound && posY > upperBound)
return true;
}
}
return false;
}
因此,当我从垂直线覆盖的区域发送 mousePressEvent 时,该函数似乎返回 false。我的第一个想法是 if 句:
if (posX < path.elementAt(i + 1).x && posX > path.elementAt(i).x)
关于如何在没有 if 句的情况下实现这一点的任何其他想法?
我还看到其他人正在努力寻找一种好方法来检查 a 是否QPainterPath
包含一个没有boundingRect()
andintersects()
函数的点,所以这可能也可以用于其他人:)
编辑:据我所知,contains()
使用boundingRect()
. 所以我不认为这是一个合适的解决方案