Qt Graphics View:检测碰撞方向

Posted

技术标签:

【中文标题】Qt Graphics View:检测碰撞方向【英文标题】:Qt Graphics View: detecting collision direction 【发布时间】:2013-11-01 13:28:22 【问题描述】:

我正在尝试使用 qt 创建游戏。我在图形视图中有一些障碍(QPixmapItem)。我有一个球,我想要的是它可以从障碍物上反弹。如何检测障碍物表面的法线,以便计算新的移动方向?例如:

------------------------------
    / \          |
   /   \         | 
  /     \        v
 /       \       ^
/         \      |

【问题讨论】:

也许你应该看看colliding mice example。 很明显,球从边界反弹后,运动方向与边界的夹角正弦值应该相同。 我已经阅读了该教程,它非常有帮助。然而,在那个例子中,老鼠转向随机方向以避免碰撞,而我需要计算碰撞后球应该移动的角度。 这个问题是题外话,因为它是一个数学问题。此外,您应该使用现有的 2D 物理引擎(例如 Box2d),而不是自己发明。 这不是一道数学题。如果我知道表面法线/切线的角度,计算方向就很容易了。我只能检测是否发生碰撞。查看 QGraphicsItem 的功能,shape() 可能有用,但我仍然没有弄清楚如何使用。 【参考方案1】:

根据您的 cmets,您确实正确地解决了问题。但是,您需要解决的问题是遍历 QPainterPath 元素并确定哪些元素实际上与球的方向线相交(为此使用 QLineF 应该是一项相当容易的任务)。此外,简化路径会将任何贝塞尔曲线减少为直线以便于计算(我将由您决定,因为您不太可能需要自己或根本不需要处理贝塞尔计算)。由于可能有多个交叉点,接下来您需要确定哪个交叉点最靠近球的中心。一旦你确定了哪个点最接近,使用 QLineF 中的那个元素来找到它的法线向量,然后你就可以完成反弹方向的计算。

这里是一些基本的非线程代码,向您展示如何迭代 QPainterPath 并处理它的元素。

QPainterPath path = item->shape();

path = path.simplified(); //optional if you do not want to handle curveTo elements yourself

QPainterPath::Element element;
QPainterPath::Element P1;
QPainterPath::Element P2;
QPainterPath::Element P3;
QPainterPath::Element P4;

for(int i = 0; i < path.elementCount()-1; ++i)

    element = path.elementAt(i);
    if(element.isMoveTo())
    
        //Do something
    
    else if(element.isLineTo())
    
        //Do something with element.x and element.y
    
    else if(element.isCurveTo())
    
        P1 = path.elementAt(i-1); // start point
        P2 = path.elementAt(i);   // control point
        P3 = path.elementAt(i+1); // control point
        P4 = path.elementAt(i+2); // end point

        //Do something with cubic bezier points
    

【讨论】:

以上是关于Qt Graphics View:检测碰撞方向的主要内容,如果未能解决你的问题,请参考以下文章

Egret 矢量绘图遮罩碰撞检测

自定义view刮刮乐

QT Graphics-View图元组使用

Qt基础之二十九:图形视图框架(Graphics View Framework)及其应用

使用Matrix控制图片和组件的变化

Qt之基于Graphics View实现Mesh网络拓扑图