2016-11-07 57 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