我有一组矩形,矩形的左上角和不同的宽度/高度坐标各不相同。例如,让我们采用带有接地变量的矩形A:1表示X坐标(左上角),2表示Y,1表示宽度,2表示高度。现在矩形B的变量并非全部接地:X为1,Y为[1,2],宽度为2,高度为[1,2]。
根据这些信息,我们应该能够知道2是Y的一个不可能的值,因为它会导致两个矩形的左上角相同,因此它们会重叠。然后将Y接地到1.高度也是如此:如果高度为2,则矩形B的左下角将与矩形A重叠,因此仅允许1。通过这些信息,我们可以通过传播将矩形B接地。但对我来说问题是我需要考虑很多矩形,并且有很多选择。
我在SWI-Prolog中使用CHR来实现。目前我有这样的事情(它只是这里实现的非重叠矩形约束的一小部分):
% verify top left corner
rect(_,c(X,Y),s(W,H))\rect(Hint,c(_X,_Y),S)<=>
number(X),number(Y),number(W),number(H),number(_X),\+ number(_Y),
_X >= X, _X < X+W, Z is Y+H-1, numlist(Y,Z,NY), subtract(_Y,NY,NewY), \+ permutation(NewY,_Y) |
rect(Hint,c(_X,NewY),S).
rect(_,c(X,Y),s(W,H))\rect(Hint,c(_X,_Y),S)<=>
number(X),number(Y),number(W),number(H),\+ number(_X),number(_Y),
_Y >= Y, _Y < Y+H, Z is X+W-1, numlist(X,Z,NX), subtract(_X,NX,NewX), \+ permutation(NewX,_X) |
rect(Hint,c(NewX,_Y),S).
% better version of equals
permutation([], []).
permutation([H|T], R) :-
permutation(T, X),
delete(H, R, X).
permutation(X, Y) :- % in case of numbers instead of lists
X == Y.
标题左侧的矩形是矩形A,我简化的是矩形B.如果X坐标接地(它是一个数字)但是Y没有接地(它是一个列表),然后我尝试从列表中删除Y的所有不可能的值。最佳案例场景只剩下1个元素,我们也可以将Y点。在第二个simpagation规则中我也这样做:如果我们知道Y的值但不知道X的值,我们试图消除X的所有不可能的值。
这是用于验证矩形B的左上角是否在矩形A内的许多代码。我甚至通过假设矩形A首先接地而已经简化了事情,并且这并没有考虑到A的左上角可能在矩形B内。当我试图找出宽度和高度传播时,事情变得复杂得多,因为矩形放置和不同重叠可能性有很多组合。考虑到我必须考虑的所有可能性,我感到非常不知所措。
我尝试查找非重叠矩形放置的算法,但很多人认为我已经掌握了完整的信息。不幸的是,我没有全部基础价值观,而且我要自己完成传播。有没有人建议如何以战略方式解决这个问题?