我有一个存储为点的矩形列表。目前,数据看起来像这样:
boxes = [{'p1': (0,0), 'p2': (100,20)},
{'p1': (5,5), 'p2': (15,15)},
{'p1': (20,5), 'p2': (30,15)},
{'p1': (35,5), 'p2': (45,15)},
{'p1': (70,5), 'p2': (80,15)}]
我还有一个基本功能,可以测试矩形是否包含在另一个矩形中:
def isChild(b1,b2):
return (b1 != b2 and
(b1['p2'][0]-b1['p1'][0] * b1['p2'][1]-b1['p1'][1]) > (b2['p2'][0]-b2['p1'][0] * b2['p2'][1]-b2['p1'][1]) and
b1['p1'][0] < b2['p2'][0] and
b1['p2'][0] > b2['p1'][0] and
b1['p1'][1] < b2['p2'][1] and
b1['p2'][1] > b2['p1'][1])
我想结束一组长方形和他们的孩子,但我不确定应该如何储存它们。我在想这样的事情:
[{'p1': (0,0),
'p2': (100,20),
'children': [{'p1': (5,5), 'p2': (15,15)},
{'p1': (20,5), 'p2': (30,15)},
{'p1': (35,5), 'p2': (45,15)},
{'p1': (70,5), 'p2': (80,15)}]}]
这样的上下文是框表示网页上的元素。数据结构用于生成基本标记,因此上面的结构最终将会是这样的:
<div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
答案 0 :(得分:3)
使用课程。这是OO编程的典型用例。创建一个Rectangle
类from random import random
class Rectangle(object):
def __init__(self, x1, y1, x2, y2):
self._p1 = (x1, y1)
self._p2 = (x2,y2)
self._children = []
def __str__(self):
return "Rectangle defined by %s, %s, %i children" % (self._p1, self._p2, len(self._children))
def is_child_of(self, other):
return (self is not other and
self._p1[0] > other._p1[0] and
self._p2[0] < other._p2[0] and
self._p1[1] > other._p1[1] and
self._p2[1] < other._p2[1])
def add_child(self, other):
self._children.append(other)
def check_relation_and_connect(self, other):
if self.is_child_of(other):
other.add_child(self)
elif other.is_child_of(self):
self.add_child(other)
if __name__=="__main__":
rectangles = [Rectangle(random()*5, random()*5, random()*5+5, random()*5+5) for i in range(10)]
for i in range(len(rectangles)):
for j in range(i):
rectangles[i].check_relation_and_connect(rectangles[j])
for rectangle in rectangles:
print rectangle
该类包含两个点,_p1和_p2,以及一个子列表。找到父子关系的逻辑进入了这个类的一个方法(顺便说一句,你的方法是否有效?我改变了它,因为它对我来说是无意义的。也许我对如何定义矩形有不同的理解。)
当你在谈论网站和<div>
时,我假设你不会有数以千计的矩形。所以这种方法应该没问题。
此示例也可以扩展为绘制所有矩形,因此可以检查矩形和计算的亲缘关系。保持类Rectangle不变,可以写:
if __name__=="__main__":
import matplotlib.pyplot as plt
from matplotlib import patches
rectangles = [Rectangle(random()*5, random()*5, random()*5+5, random()*5+5) for i in range(5)]
for i in range(len(rectangles)):
for j in range(i):
rectangles[i].check_relation_and_connect(rectangles[j])
for rectangle in rectangles:
print rectangle
colormap = plt.get_cmap("Paired")
for i, rect in enumerate(rectangles):
ax = plt.axes()
color = colormap((1.*i)/len(rectangles))
patch = patches.Rectangle(rect.p1, rect.p2[0]-rect.p1[0], rect.p2[1]-rect.p1[1], fc="none", ec=color, lw=2)
ax.add_patch(patch)
plt.xlim(-1,11)
plt.ylim(-1,11)
plt.show()
这给出了如下情节:
对于这个例子,只有一个Rectangle有一个孩子(紫色是绿色的孩子)。
答案 1 :(得分:0)
四叉树或R树(或任何其他2维空间数据结构)将非常适合。但是如果你没有很多这样的嵌套框(数十或数百),你可以在每次需要查询数据结构时枚举它们。如果您有许多,数千或更多,并且需要有效地查询它们 - 使用空间数据结构。