查找包含或未包含的点

时间:2017-12-09 08:34:23

标签: python list dictionary

我正在为Python 3.5.2写作。我有一个名为coordinate_list的列表:

[
    ['x1', '120;40', '100;0;60;40'],
    ['x2', '200;50', '80;10;30;5'],
    ['x3', '150;15', '120;0;25;10'],
    ['x4', '240;60', '100;10;0;40'],
    ['x5', '260;45', '70;0;10;25'],
    ['x6', '225;15', '75;10;5;10'],
    ['x7', '273;20', '75;0;0;0'],
    ['x8', '221;5', '0;0;0;0'],
    ['x9', '345;20', '0;0;0;0'],
]

首先,我想解释一下列表元素的含义。列表中的每一行都标识一个点。第一个元素,如

  

" X 1" ," x2" " X3",...

是该点的名称。下一个元素是点的坐标,由;分隔。最后一个要素是点的范围。例如,x1的坐标是(120,40)。东边是(120 + 100),西边是(120 - 0),北边是(40 + 60),南边是(40 - 40)。

如果任何其他点在此范围内,我必须将其放在字典或列表中。例如,x1的范围是(220,120,100,0)(东,西,北,南),因此x1包括x2和x3。

我该怎么做?我写了一些东西,但它非常不合情理。我创建了很多列表,但它不可读。此外,我找不到包含的可能点。

2 个答案:

答案 0 :(得分:0)

正如timgeb所提到的,将数据存储在类中比使用列​​表更容易开发和维护代码。

这是一个完成工作的简单类结构。

data = [
    ['x1', '120;40', '100;0;60;40'],
    ['x2', '200;50', '80;10;30;5'],
    ['x3', '150;15', '120;0;25;10'],
    ['x4', '240;60', '100;10;0;40'],
    ['x5', '260;45', '70;0;10;25'],
    ['x6', '225;15', '75;10;5;10'],
    ['x7', '273;20', '75;0;0;0'],
    ['x8', '221;5', '0;0;0;0'],
    ['x9', '345;20', '0;0;0;0'],
]

class Point:
    def __init__(self, name, xy, extent):
        ''' Extract the point's coordinates and compute its bounds ''' 
        self.name = name
        self.x, self.y = [int(u) for u in xy.split(';')]
        east, west, north, south = [int(u) for u in extent.split(';')]
        self.east = self.x + east
        self.west = self.x - west
        self.north = self.y + north
        self.south = self.y - south

    def __repr__(self):
        ''' Create a simple string representation of the Point '''
        fmt = "('{name}', ({x}, {y}), ({east}, {west}, {north}, {south}))"
        return fmt.format(**self.__dict__)

    def includes(self, other):
        ''' Test if `other` is in the bounds of `self` '''
        return (self.west <= other.x <= self.east and 
            self.south <= other.y <= self.north)

# Convert the original data to a list of Points
coords = [Point(*row) for row in data]
for p in coords:
    print(p)
print()

#Find which points p2 are in the bounds of each point p1
for p1 in coords:
    print(p1.name, [p2.name for p2 in coords if p2 != p1 and p1.includes(p2)])

<强>输出

('x1', (120, 40), (220, 120, 100, 0))
('x2', (200, 50), (280, 190, 80, 45))
('x3', (150, 15), (270, 150, 40, 5))
('x4', (240, 60), (340, 230, 60, 20))
('x5', (260, 45), (330, 260, 55, 20))
('x6', (225, 15), (300, 215, 20, 5))
('x7', (273, 20), (348, 273, 20, 20))
('x8', (221, 5), (221, 221, 5, 5))
('x9', (345, 20), (345, 345, 20, 20))

x1 ['x2', 'x3']
x2 ['x4', 'x5']
x3 ['x6', 'x8']
x4 ['x5', 'x7']
x5 ['x7']
x6 ['x7', 'x8']
x7 ['x9']
x8 []
x9 []

答案 1 :(得分:0)

这个问题不是很清楚(可理解的语言困难),如果我误解了这个问题,那么道歉。

我相信您希望确定每个点是否都是&#39;位于每个点周围的矩形范围内。

要解决此问题,我们首先创建一个类来表示每个Rectangle

class Rectangle:
    def __init__(self, center_x, center_y, east, west, north, south):
        self._center_x = center_x
        self._center_y = center_y
        self._north = center_y + north
        self._south = center_y - south
        self._west = center_x - west
        self._east = center_x + east

    def containsPoint(self, other):
        return other._center_y <= self._north and other._center_y >= self._south and other._center_x >= self._west and other._center_x <= self._east

    def __repr__(self):
        return "center=({}, {}), east={}, west={}, north={}, south={}".format(self._center_x, self._center_y, self._east, self._west, self._north, self._south)

此类的每个实例都存储北,东,南和西值与中心点坐标一起。 containsPoint函数然后确定任何给定Rectangle的中心是否在另一个Rectangle的范围内

接下来,我们获取原始输入数据并进行一些简单的解析,以使其更易于管理:

data = [['x1', '120;40', '100;0;60;40'], ['x2', '200;50', '80;10;30;5'], ['x3', '150;15', '120;0;25;10'],
        ['x4', '240;60', '100;10;0;40'], ['x5', '260;45', '70;0;10;25'], ['x6', '225;15', '75;10;5;10'],
        ['x7', '273;20', '75;0;0;0'], ['x8', '221;5', '0;0;0;0'], ['x9', '345;20', '0;0;0;0']]

coords = {}
for coord in data:
    name = coord[0]
    center_x, center_y = [int(n) for n in coord[1].split(';')]
    east, west, north, south = [int(n) for n in coord[2].split(';')]
    coords[name] = Rectangle(center_x, center_y, east, west, north, south)

现在我们有一个名称地图(例如x1x2等等)到Rectangle类的实例。

现在我们可以编写一个简单的O(n ^ 2)算法来比较每个矩形的中心和其他每个矩形:

for name1, coord1 in coords.iteritems():
    for name2, coord2 in coords.iteritems():
        if name1 == name2:
            continue
        print("testing if centre of {}({}) is in {}({}), result is {}".format(name1, coord1, name2, coord2, coord2.containsPoint(coord1)))

产生输出:

testing if centre of x8(center=(221, 5), east=221, west=221, north=5, south=5) is in x9(center=(345, 20), east=345, west=345, north=20, south=20), result is False
testing if centre of x8(center=(221, 5), east=221, west=221, north=5, south=5) is in x2(center=(200, 50), east=280, west=190, north=80, south=45), result is False
testing if centre of x8(center=(221, 5), east=221, west=221, north=5, south=5) is in x3(center=(150, 15), east=270, west=150, north=40, south=5), result is True
testing if centre of x8(center=(221, 5), east=221, west=221, north=5, south=5) is in x1(center=(120, 40), east=220, west=120, north=100, south=0), result is False
... snip long output ...

我希望即使我误解了你的要求,这也会给你足够的线索让你前进。