2013-10-02 40 views
0

我花了一些时间寻找解决特定矩形放置问题的适当方法。以特定方式放置两个矩形的算法

让我们直接找到问题。

我有两个矩形,它们是固定的大小。其中一个被锁定,不能移动,另一个可以自由移动。

我有两个放在固定宽度和高度的画布上。可以说它是1000x1000。

我需要将第二个可移动的矩形放在与另一个锁定的水平或垂直对齐的位置,而可移动的矩形不能超出1000x1000的范围。

我在水平/垂直对齐的定义下理解的是,如果你只看X(水平方向)或Y(垂直方向)轴,你可以锁定一个在可移动的一个或另一个方向。

我知道我可以解决我的问题,但我希望找到任何更智能的解决方案。

有什么建议吗?

编辑:关于两个矩形的所有信息是已知的。角落,宽度/高度。

回答

0

给定一个X [-inf,+ inf]轴和名义Y [-inf,+ inf]轴上的坐标平面,如果它们在水平轴上的坐标为(我们选择X)是平等的。如果它们在垂直轴(Y)上的坐标相等,则可以说它们处于水平对齐状态。

矩形可以用两对坐标(x1,y1)和(x2,y2)来描述,这样x1 < = x2,y1 < = y2。 (如果你的对子混合在一起,实际上你可以重新排列它们来使用这种格式 - 它会让你的生活更轻松。)

矩形(r1)可以说是驻留在另一个矩形(r2)中如果且仅当r1.x1> = r2.x1,r1.y1> = r2.y1,r1.x2 < = r2.x2,r1.y2 < = r2.y2全部成立。请注意,无论您处于哪个象限或轴向运行的方向都是如此。

如果并且只有当r1.x1和r1.x2落在范围(r2.x1,r2.x2)之外且r1.y1和r1.y1都可以说矩形(r1)位于另一个矩形(r2)的外部和r1.y2超出范围(r2.y1,r2.y2)。请注意,这包括r2是INSIDE r1的情况。

矩形(r1)可以说是从另一个矩形(r2)分离的当且仅当它在该矩形的外部,并且该矩形不是内部的。 (即:R1 R2 OUTSIDE & & NOT R2 INSIDE R1)

的矩形(R1)可以说重叠另一个矩形(R2)当且仅当它既不INSIDE也不之外的矩形。 (或者,您可以选择声明整个矩形内的整个矩形是有效的重叠,并说OVERLAP =!SEPARATE。取决于您的应用程序。)

对齐对于矩形更难。可以说相同尺寸的矩形与点(使用每个矩形的(x1,y1))作为参考点的方式相同。对于不同尺寸的矩形,我建议您使用中心点作为参考:如果(r1.x1 + r1。)矩形是垂直对齐的。(r1.y1 + r1.y2)/ 2 =(r2.y1 + r2.y2)/ 2时,水平对齐。

我会写一个包含这些规则的类,并使用它来检查每个运动,使用三个矩形 - 您提到的两个矩形和边界框作为第三个。

CLASS rectangle 
    x1 
    x2 
    y1 
    y2 

    CONSTRUCT(xx1, yy1, xx2, yy2): 
     Ensure xx1 <= xx2 and yy1 <= yy2 - swap them if you like 
     x1 = xx1, y1 = yy1, x2 = xx2, y2 = yy2 

    IS_INSIDE(rectangle r2): 
     IF r2.x1<=x1 && r2.y1<=y1 && y2 <= r2.y2 && x2 <= r2.x2: 
      RETURN TRUE 
     RETURN FALSE 

    IS_OUTSIDE(rectangle r2): 
     IF r2.x1 <= x1 <= r2.x2 || r2.x1 <= x2 <= r2.x2 || r2.y1 <= y1 <= r2.y2 || r2.y1 <= y2 <= r2.y2 : 
      RETURN FALSE 
     RETURN TRUE 

    IS_SEPARATE(rectangle r2): 
     IF IS_OUTSIDE(r2) && ! r2.IS_INSIDE(me): 
      RETURN TRUE 
     RETURN FALSE 

    IS_OVERLAPPED(rectangle r2): 
     IF ! IS_OUTSIDE(r2) && ! IS_INSIDE(r2): 
      RETURN TRUE 
     RETURN FALSE 

    IS_VERTICALLY_ALIGNED(rectangle r2): 
     IF (x1+x2)/2 = (r2.x1+r2.x2)/2: 
      RETURN TRUE 
     RETURN FALSE 

    IS_HORIZONTALLY_ALIGNED(rectangle r2): 
     IF (y1+y2)/2 = (r2.y1+r2.y2)/2: 
      RETURN TRUE 
     RETURN FALSE 

然后可以写一个非常简单的函数,以查看是否R2被有效地放置,假设R 2是可移动的矩形,R 1是固定的一个,和箱是表示帆布的边界框的未显示的矩形:

IS_VALID_PLACEMENT(r2, r1, box): 
    //In the bounding box 
    IF r2.IS_OUTSIDE(box): 
     RETURN FALSE 

    //Aligned with r1 
    IF ! r2.IS_VERTICALLY_ALIGNED(r1) && ! r2.IS_HORIZONTALLY_ALIGNED(r1): 
     RETURN FALSE 

    //Not overlapping r1 
    IF ! r2.IS_SEPARATE(r1): 
     RETURN FALSE 

    RETURN TRUE 

每当箱子移动时就运行一次。如果它返回false,则撤消移动,或使用边界逻辑进行邻接。

编辑

我在重读你的问题,我注意到你的垂直对齐的定义。完全可行:

IS_VERTICALLY_ALIGNED(rectangle r2): 
     IF x1 <= r2.x1 <= r2.x2 <= x2 || r2.x1 <= x1 <= x2 <= r2.x2: 
      RETURN TRUE 
     RETURN FALSE 

    IS_HORIZONTALLY_ALIGNED(rectangle r2): 
     IF y1 <= r2.y1 <= r2.y2 <= y2 || r2.y1 <= y1 <= y2 <= r2.y2: 
      RETURN TRUE 
     RETURN FALSE 
+0

这就是我一直在寻找的。谢谢 ;) –