2016-11-07 137 views
0

好家伙,我需要你的帮助,的QGraphicsItem碰撞抖动/发抖

我创建像基础上,QGraphics框架Qt物件的时间表。我的问题是处理我的时间轴轨道中项目的冲突(从QGraphicsRectItem继承)。

我使用itemChange()函数来跟踪碰撞。为了使项目在我使用下面的代码至极父boundingRect就像一个魅力

if (change == ItemPositionChange && scene()) 
    if (thisRect.intersects(parentRect)) { 
     const QPointF offset(mapFromParent(thisRect.topLeft())); 
     QPointF newPos(value.toPointF()); 

     if (snapToGrid) { 
      newPos.setX(floor(qMin(parentRect.right() - offset.x() - thisRect.width(), 
            qMax(newPos.x(), parentRect.left()/2 - offset.x()))/(snapValue * pxPerSec(duration))) * snapValue * pxPerSec(duration)); 
     } 
     else {    
      newPos.setX(qMin(parentRect.right() - offset.x() - thisRect.width(), 
          qMax(newPos.x(), parentRect.left() - offset.x()))); 
     } 

     newPos.setY(parentItem()->boundingRect().height() * 0.1); 
     return newPos; 
    } 
} 

,如果他们达到我timline轨道的左边或右边界这立即停止项目,即使我之外移动鼠标我的观点/场景。它就像一堵无形的墙。 现在我想要一个轨道中的一个项目与另一个项目相冲突时的相同行为。

const QRectF parentRect(parentItem()->sceneBoundingRect()); 
const QRectF thisRect(sceneBoundingRect()); 

    foreach (QGraphicsItem *qgitem, collidingItems()) { 
     TimelineItem *item = qgraphicsitem_cast<TimelineItem *>(qgitem); 
     QPointF newPos(value.toPointF()); 

     if (item) { 
      const QRectF collideRect = item->sceneBoundingRect(); 
      const QPointF offset(mapFromParent(thisRect.topLeft())); 

      if (thisRect.intersects(collideRect) && thisRect.x() < collideRect.x()) { 
       newPos.setX(collideRect.left() - offset.x() - thisRect.width()); 
      } 

      if (thisRect.intersects(collideRect) && thisRect.x() > collideRect.x()) { 
       newPos.setX(collideRect.right() + offset.x()); 
      } 

     } 

     newPos.setY(parentItem()->boundingRect().height() * 0.1); 
     return newPos; 
    } 

的问题是,如果我通过鼠标移动的项目对你看到他们相交的另一个项目/重叠,然后该项目,我搬到弹回到最低不相交的距离。如果碰到另一个物体,我该如何设法立即停止移动物体(不会前后移动相交)。就像物品保存在父母boundingRect(第一个代码块)中的方式一样,隐形墙像行为一样?

回答

0

我认为这里的问题是与“thisRect”。如果您是通过ItemPositionChange调用它,那么sceneBoundingRect会返回该项目的边界矩形,而不是新的边界矩形。即使碰撞发生,当前位置也会成功,但下一个失败是因为您总是检查先前的结果,然后它会回退以避免碰撞。

获得本地项目的现场矩形后,你需要将它转化为项目的新的未来位置:

QPointF new_pos (value.toPointF()); 
QRectF thisRect (sceneBoundingRect()); 
thisRect.translate (new_pos - pos()); 

我搬到循环,使外“new_pos”的创作它可用于矩形转换。它也更快。

+0

感谢您的回复,好点但它没有解决问题。 – RobRobRob

+0

是否有这些项目的父项?如果是这样,那么你有一系列坐标系统,即“newPos”和“offset”在父坐标系中,但“thisRect”和“collideRect”在场景坐标系中。如果他们不是父亲,那么这是所有的场景坐标,在这种情况下,我认为这看起来是正确的。如果涉及父项目,请使用mapToScene而不是mapToParent,然后将newPos映射到场景坐标以进行所有比较和调整,然后在返回之前返回到父坐标。 – goug

+0

这些项目是父项,但它与场景的宽度相同,它的矩形也设置为(0,0)。所以x,y的原点应该是一样的。 – RobRobRob