QGraphicsScene,项目坐标会影响性能?

时间:2011-05-28 21:48:38

标签: performance qt qgraphicsscene

使用下面的代码片段,我创建了一个100.000个矩形的场景 表现很好;视图没有延迟响应。

QGraphicsScene * scene = new QGraphicsScene;
for (int y = -50000; y < 50000; y++) {
   scene->addRect(0, y * 25, 40, 20);
}
...
view->setScene(scene);

现在第二个片段糟透了

for (int y = 0; y < 100000; y++) {
   scene->addRect(0, y * 25, 40, 20);
}

对于场景元素的前半部分,视图延迟响应鼠标和键事件,而另一半看起来似乎没问题?!?

前一个场景有sceneRect(x,y,w,h)=(0,-1250000,40,2499995)。
后一个场景有sceneRect(x,y,w,h)=(0,0,40,2499995)。

我不知道为什么sceneRect会影响性能,因为BSP索引是基于相对项目坐标的。

我错过了什么吗?我没有找到有关文档的任何信息, 加上Qt演示40000 Chips也会在(0,0)周围分配元素,而不解释选择的原因。

 // Populate scene
 int xx = 0;
 int nitems = 0;
 for (int i = -11000; i < 11000; i += 110) {
     ++xx;
     int yy = 0;
     for (int j = -7000; j < 7000; j += 70) {
         ++yy;
         qreal x = (i + 11000) / 22000.0;
         qreal y = (j + 7000) / 14000.0;
         ...

3 个答案:

答案 0 :(得分:6)

我有一个解决方案,但保证不会问我为什么这样做, 因为我真的不知道: - )

QGraphicsScene * scene = new QGraphicsScene;
// Define a fake symetrical scene-rectangle
scene->setSceneRect(0, -(25*100000+20), 40, 2 * (25*100000+20) );

for (int y = 0; y < 100000; y++) {
    scene->addRect(0, y * 25, 40, 20);
}
view->setScene(scene);
// Tell the view to display only the actual scene-objects area
view->setSceneRect(0, 0, 40, 25*100000+20);

答案 1 :(得分:0)

  

对于常见情况,默认索引   方法BspTreeIndex工作正常。如果   你的场景使用了很多动画和   你正在经历缓慢,你可以   通过调用禁用索引   setItemIndexMethod(NOINDEX)。 Qt-doc

您需要在插入前致电setItemIndexMethod(QGraphicsScene::NoIndex)

scene->setItemIndexMethod(QGraphicsScene::NoIndex);

for (int y = 0; y < 100000; y++) {
   scene->addRect(0, y * 25, 40, 20);
}
//...

答案 2 :(得分:0)

可能是由于float导致精度下降。 32位浮点数具有23位尾数(或有效数),1位符号和8位指数。这就像科学记谱法。你有23个“有效数字”(真正24个由于隐含的前导1)和指数为2 ^ exp,其中指数的范围可以从-126到127(其他用于给你NaN和{ {1}})。所以你可以代表真正的大数字,比如2 ^ 24 * 2 ^ 127 但是这个浮点数的下一个最接近的浮点数是(2 ^ 24-1)* 2 ^ 127或1700亿亿十亿之遥。如果您尝试向这样的数字添加较小的数量(如1000),则不会更改。它没有办法代表那个。

这在计算机图形学中变得非常重要,因为您需要留下一些有效数字来构成小数部分。当你的场景范围达到1250000.0时,可以将其加0.1,得到1250000.1。如果您使用2500000.0 + 0.1,则获得2500000.0。任何缩放或旋转都会使问题放大。如果你真的飞到那些坐标并观察你的场景,这可能会导致明显的视觉问题。

为什么以0为中心有帮助?因为浮点表示中有一个单独的符号位。在浮点数中,(-x,+ x)之间存在“更多数字”而不是(0,2x)。如果我是对的,如果你简单地将整个场景缩小1/2,它也会起作用。这会将最重要的位向下移动,使其在另一端自由以获得精确度。

为什么会导致性能不佳?我只能在不读取Qt源的情况下推测,但考虑按位置存储对象的数据结构。如果两个物体由于精度损失而接触(或重叠)时,你可能需要采取哪些不同的做法,而当它们没有重叠时你不必这样做?