Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 布置重叠矩形_Algorithm_User Interface_Qt_Layout - Fatal编程技术网

Algorithm 布置重叠矩形

Algorithm 布置重叠矩形,algorithm,user-interface,qt,layout,Algorithm,User Interface,Qt,Layout,我正在尝试布局一组重叠的矩形,开始时是这样的: 我想出的2次通过算法大致如下: // Pass 1 - Move all rectangles to the right until they do not overlap any other rectangles rects = getRectsSortedOnTopLeft(); // topmost first, all rects same size foreach(rect in rects) { while(rect.colli

我正在尝试布局一组重叠的矩形,开始时是这样的:

我想出的2次通过算法大致如下:

// Pass 1 - Move all rectangles to the right until they do not overlap any other rectangles
rects = getRectsSortedOnTopLeft(); // topmost first, all rects same size
foreach(rect in rects)
{
   while(rect.collidingRects().size() != 0)
   {
       rect.x += RECT_SIZE;
   }
}
这(可能)以矩形结束,如下所示:

这在美学上并不令人满意,因此我想到了第二次传球,这将使他们从最顶端再次向左移动:

// Pass 2
foreach(rect in rects)
{
    while(rect.x >= LEFT_MARGIN)
    {
        assert(rect.collidingRects().size() == 0);
        rect.x -= RECT_WIDTH;
        if(rect.collidingRects().size() != 0)
        {
           rect.x += RECT_WIDTH;
           break;
        }
    }
}
我认为这最终应该如下所示(在实践中看起来完全正确):


然而,我对这个算法很谨慎,因为我不确定它是否在所有情况下都能正确布局,而且它可能真的很慢。你认为这个算法行得通吗?你能就更好的算法提出一些建议吗?

我认为这个问题是多项式复杂性的。假设您的示例在任何给定点仅重叠两个矩形的限制不是问题的真正限制,您需要尝试将矩形向右碰撞的所有可能顺序,以产生最佳(最小宽度)结果。这是一种空间布局问题,除非您的数据集足够小,足以使用暴力,否则这些问题很难解决

然而,对伪代码的一个小小的改进是可能的,这将在许多情况下提高其性能

考虑这一期望的最终结果:

A
A C
A C E
A C E
B C E
B D E
B D F
B D F
  D F
    F
(其中一个字符的四个字符都是一个矩形)

你的第一个通行证会把除了A之外的所有东西移到右边,形成一个楼梯。然后在第二遍中,您的代码将拒绝将B移动到左边距,因为第一次尝试移动它时会与E重叠。您需要做的是从左边距开始,并检查在第二遍中可以将每个矩形移动到的最左边的位置

伪代码:

// Pass 1 - Move all rectangles to the right until they do not overlap any other rectangles
rects = getRectsSortedOnTopLeft(); // topmost first, all rects same width
foreach(rect in rects)
    while(rect.collidingRects())
        rect.x += RECT_WIDTH;
// Pass 2 - Move all rectangles to the leftmost position in which they don't overlap any other rectangles
foreach(rect in rects)
    for(i=LEFT_MARGIN; i+=RECT_WIDTH; i<rect.x)
    {
        o = rect.x;
        rect.x = i;
        if(rect.collidingRects())
            rect.x = o;
    }
//传递1-向右移动所有矩形,直到它们不与任何其他矩形重叠
rects=getrectsortedontopleft();//最上面的第一个,所有矩形的宽度相同
foreach(矩形中的矩形)
while(rect.collingrects())
矩形x+=矩形宽度;
//通过2-将所有矩形移动到最左边的位置,使其不与任何其他矩形重叠
foreach(矩形中的矩形)

对于(i=LEFT_MARGIN;i+=RECT_WIDTH;i可以使用基于物理的方法,其中块是刚体,向左倾斜:


不,这不会一直产生最好的效果,但看过你的屏幕广播后,我认为在交互式程序中使用它会非常直观,而且可能很合适:)

你的伪代码需要做一些工作。。。“rect.size-=rect_size;”应该是“rect.x-=rect_size;”,如果最后一次向左移动导致碰撞,则需要将其向右移动一次。是的,您是对的。我注意到在实现了伪代码之后。我将在问题中解决它。在实现之后,它通常表现得非常糟糕:-/Hmm,我撒谎,它实际上工作得非常好(一些小的边界矩形问题)。但是,x顺序没有被保留,我需要x顺序被“尽可能”保留,这就是为什么我们不再使用imageshack。嗯,我认为这实际上修复了我在测试原始代码时发现的一个错误。。。它仍然有一些奇怪的行为,我想纠正。我将对我想要修复的运行时行为进行U/L屏幕广播。这是屏幕广播。我想,就算法本身而言,算法做的是正确的,但我想做的是尽可能多地保持所有矩形的x位置:有什么想法吗?好的,为了避免选定的矩形在x轴上被重新定位,我在这个算法中忽略它。似乎有效。当然,我仍然对想法持开放态度。在我对我想要的行为有更好的描述之前,请将你的答案标记为正确:)这真是个好主意。我将制作这部电影的原型,感谢您抽出时间观看这部电影。