def row(x, transitions):
""" generator spitting all cells in a row given a list of transition (in/out) columns."""
i = 1
in_poly = True
y = transitions[0]
while i < len(transitions):
if in_poly:
while y < transitions[i]:
yield (x,y)
y += 1
in_poly = False
else:
in_poly = True
y = transitions[i]
i += 1
def get_same_row_vert(i, vertices):
""" find all vertex columns in the same row as vertices[i], and return next vertex index as well."""
vert = []
x = vertices[i][0]
while i < len(vertices) and vertices[i][0] == x:
vert.append(vertices[i][1])
i += 1
return vert, i
def update_transitions(old, new):
""" update old transition columns for a row given new vertices.
That is: merge both lists and remove duplicate values (2 transitions at the same column cancel each other)"""
if old == []:
return new
if new == []:
return old
o0 = old[0]
n0 = new[0]
if o0 == n0:
return update_transitions(old[1:], new[1:])
if o0 < n0:
return [o0] + update_transitions(old[1:], new)
return [n0] + update_transitions(old, new[1:])
def polygon(vertices):
""" generator spitting all cells in the polygon defined by given vertices."""
vertices.sort()
x = vertices[0][0]
transitions, i = get_same_row_vert(0, vertices)
while i < len(vertices):
while x < vertices[i][0]:
for cell in row(x, transitions):
yield cell
x += 1
vert, i = get_same_row_vert(i, vertices)
transitions = update_transitions(transitions, vert)
# define a "strange" polygon (hook shaped)
vertices = [(0,0),(0,3),(4,3),(4,0),(3,0),(3,2),(1,2),(1,1),(2,1),(2,0)]
for cell in polygon(vertices):
print cell
# or do whatever you need to do
2条答案
按热度按时间vmjh9lq91#
我相信这能解决你的问题。
下面的代码生成由顶点列表定义的多边形中的所有单元。它逐行“扫描”多边形,跟踪您(重新)进入或退出多边形的过渡列。
vq8itlhq2#
一般的问题被称为"Point in Polygon",其中(相当)标准的算法是基于通过所考虑的点绘制一条测试线,并计算它穿过多边形边界的次数(它真的很酷/奇怪,它的工作如此简单,* 我认为 *)。This is a really good overview which includes implementation information。
特别是对于 * 您的问题 *,因为每个区域都是基于少量的方形单元定义的-我认为更暴力的方法可能更好。可能是这样的:
numpy.digitize
的方法。如果你仍然有问题,请提供更多关于你的问题的细节(特别是,你的区域是如何定义的)-这将使你更容易提供建议。