将 boundingRect() 映射到父项并相交会产生意外的碰撞处理结果

Posted

技术标签:

【中文标题】将 boundingRect() 映射到父项并相交会产生意外的碰撞处理结果【英文标题】:Mapping boundingRect()'s to parent item and intersecting yields unexpected results for collision handling 【发布时间】:2018-09-16 03:43:56 【问题描述】:

这是我如何处理两个图形项的冲突。它在 mouseMoveEvent 和 itemChange 中被调用。像这样:

void GraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)

    auto delta = event->pos() - event->lastPos();
    auto new_pos = handleCollisions(pos() + delta);
    setPos(new_pos);

new_pos 是这样我可以在 itemChange 中调用它并将其作为值返回。但是,此版本的碰撞处理使 new_pos 保持不变。相反,我们移动与这个碰撞的项目(当我们用鼠标移动这个时)。我试图取两个涉及的边界矩形的交集,并将另一个移动矩形交叉点的较短尺寸。结果是出乎意料的,矩形并没有移动那么小的量,而是移动了任何一个 boundingRects() 的整个宽度(或高度)(它们的大小相同)。我已经追踪到了这一点,所以下面的代码计算了父位置空间中边界矩形的交集(pos()、setPos() 是相对的)是错误的。

那么我该怎么做呢?

这是我想要的图片:

QPointF GraphicsItem::handleCollisions(const QPointF& new_pos) const 
    auto collisions = collidingItems();
    auto rect = mapToParent(boundingRect().translated(new_pos - pos())).boundingRect();
    for(int k=0; k < collisions.count(); k++)
    
        auto item = collisions[k];
        if (item->parentItem() == parentItem()) 
            auto rect1 = mapToParent(item->boundingRect()).boundingRect();
            rect1 = rect1.intersected(rect);
            qDebug() << (rect1.width());
            qDebug() << (rect1.height());
            auto v = rect1.center() - rect.center();
            if (v.x() >= 0) 
                if (v.y() >= 0) 
                    if (rect1.width() <= rect1.height())
                        item->setPos(item->pos() + QPointF(-rect1.width(), 0));
                    else
                        item->setPos(item->pos() + QPointF(0, -rect1.height()));
                
                else 
                    if (rect1.width() <= rect1.height())
                        item->setPos(item->pos() + QPointF(rect1.width(), 0));
                    else
                        item->setPos(item->pos() + QPointF(0, rect1.height()));
                
            
            else 
                if (v.y() >= 0) 
                    if (rect1.width() <= rect1.height())
                        item->setPos(item->pos() + QPointF(rect1.width(), 0));
                    else
                        item->setPos(item->pos() + QPointF(0, -rect1.height()));
                
                else 
                    if (rect1.width() <= rect1.height())
                        item->setPos(item->pos() + QPointF(rect1.width(), 0));
                    else
                        item->setPos(item->pos() + QPointF(0, rect1.height()));
                
            
        
    
    return new_pos;     // return this position unchanged

【问题讨论】:

【参考方案1】:

我找到了。

item->mapToParent(...)

而不是

mapToParent(...)

应该在循环中调用。

【讨论】:

以上是关于将 boundingRect() 映射到父项并相交会产生意外的碰撞处理结果的主要内容,如果未能解决你的问题,请参考以下文章

如何将下拉菜单的子项居中到父项?

Nhibernate 在子集合更新时未检测到父项的更改

当文本太多时,flexbox布局中的子项扩展到父项外部

如何找到 QLineF 超出父边界矩形

JQuery Draggable 包含到父级和一些额外的

关于程序中数据库报错“父项未找到”