问候,
我正在尝试将点数组(x, y)
分成一个方框数[(x0, y0), (x1, y0), (x0, y1), (x1, y1)]
(元组是角点)
到目前为止,我有以下例程:
def isInside(self, point, x0, x1, y0, y1):
pr1 = getProduct(point, (x0, y0), (x1, y0))
if pr1 >= 0:
pr2 = getProduct(point, (x1, y0), (x1, y1))
if pr2 >= 0:
pr3 = getProduct(point, (x1, y1), (x0, y1))
if pr3 >= 0:
pr4 = getProduct(point, (x0, y1), (x0, y0))
if pr4 >= 0:
return True
return False
def getProduct(origin, pointA, pointB):
product = (pointA[0] - origin[0])*(pointB[1] - origin[1]) - (pointB[0] - origin[0])*(pointA[1] - origin[1])
return product
有没有更好的方法然后逐点查找?也许一些不明显的numpy常规?
谢谢!
答案 0 :(得分:2)
如果我正确理解您的问题,那么假设您的积分也是2元组,则以下情况应该有效。
def in_bin(point, lower_corner, upper_corner):
"""
lower_corner is a 2-tuple - the coords of the lower left hand corner of the
bin.
upper_corner is a 2-tuple - the coords of the upper right hand corner of the
bin.
"""
return lower_corner <= point <= upper_corner
if __name__ == '__main__':
p_min = (1, 1) # lower left corner of bin
p_max = (5, 5) # upper right corner of bin
p1 = (3, 3) # inside
p2 = (1, 0) # outside
p3 = (5, 6) # outside
p4 = (1, 5) # inside
points = [p1, p2, p3, p4]
for p in points:
print '%s in bin: %s' % (p, in_bin(p, x_min, x_max))
此代码显示您可以直接比较元组 - 文档中有关于此的一些信息:http://docs.python.org/tutorial/datastructures.html#comparing-sequences-and-other-types
答案 1 :(得分:1)
如果没有太多变化,您的代码可以压缩到:
def isInside(self, point, x0, x1, y0, y1):
return getProduct(point, (x0, y0), (x1, y0)) >= 0 and
getProduct(point, (x1, y0), (x1, y1)) >= 0 and
getProduct(point, (x1, y1), (x0, y1)) >= 0 and
getProduct(point, (x0, y1), (x0, y0)) >= 0
def getProduct(origin, pointA, pointB):
product = (pointA[0] - origin[0])*(pointB[1] - origin[1]) - (pointB[0] - origin[0])*(pointA[1] - origin[1])
return product
答案 2 :(得分:1)
您的解决方案是O(N)
,其中N是点数。如果N足够大并且您运行查询isInside
很多次,您可能会考虑对点进行排序,然后使用二进制搜索来查找相关点。
与往常一样,首先要了解您是否真的需要此优化。
答案 3 :(得分:1)
您确定首先需要这么复杂的检查吗?
def isInside(self, point, x0, y0, x1, y1):
x,y = point
if x0 > x1: x0,x1 = x1,x0 #these cause no
if y0 > y1: y0,y1 = y1,y0 #side effect.
return x0 <= x <= x1 and y0 <= y <= y1
答案 4 :(得分:1)
我使用类似的例程来制作彩色图密度图:
#calculate densities
rho = zeros((nx,ny));
for i in range(N):
x_sample = int(round(ix[i]))
y_sample = int(round(iy[i]))
if (x_sample > 0) and (y_sample > 0) and (x_sample<nx) and (y_sample<ny):
rho[y_sample,x_sample] = rho[y_sample,x_sample] + 1
您可以存储x和y样本,而不是计算密度。
答案 5 :(得分:1)
如果你真的需要使用getProduct
...打包,拆包和好的变量名称ftw!
def isInside(self, point, x0, x1, y0, y1):
A = x0,y0
B = x1,y0
C = x1,y1
D = x0,y1
return getProduct(point, A, B) and
getProduct(point, B, C) and
getProduct(point, C, D) and
getProduct(point, D, A)
def getProduct(origin, pointA, pointB):
xA,yA = pointA
xB,yB = pointB
x,y = point
return (xA - x)*(yB - y) - (xB - x)*(yB - y)
答案 6 :(得分:1)
这些盒子轴是否对齐?即边缘是否平行于坐标轴?如果是这样,这可以通过NumPy阵列上的矢量化比较非常有效地完成。
def in_box(X, B):
"""
Takes an Nx2 NumPy array of points and a 4x2 NumPy array of corners that
form an axis aligned box.
"""
xmin = B[:,0].min(); xmax = B[:,0].max()
ymin = X[:,1].min(); ymax = X[:,1].max()
return X[X[:,0] > xmin & X[:,0] < xmax & X[:,1] > ymin & X[:,1] < ymax]
修改为&gt; =和&lt; =如果您希望它们具有包容性。
如果你需要任意四边形,matplotlib
实际上有一个你可以使用的例程matplotlib.nxutils.points_inside_poly
(如果已安装它)或者复制它(它是BSD许可的)。有关所用算法和其他多边形内部测试算法的讨论,请参阅this page。
答案 7 :(得分:0)
假设您的盒子是矩形的,不重叠,没有间隙,那你为什么不打电话给numpy.histogram2d
?请参阅the numpy docs。