在python中,从复杂的曲面交集中均匀地采样随机二维数字的最有效方法是什么?
例如,考虑许多磁盘的交叉或许多磁盘联合的补充。我知道我可以简单地从包含二维感兴趣区域的框中绘制点,然后检查是否满足所需的条件,但我想知道是否有一个非常有效的解决方案来直接从中抽取均匀的随机点划界的表面!
由于
答案 0 :(得分:0)
如果有任意圈子,则无法避免进入或退出
加快此类检查的好方法是构建Quadtree,其中每个节点都有固定的(一个或零是最好的)指针,以便进行检查。
树搜索(线性变换)将通过一次循环检查(在此接受或拒绝)或不进行循环检查(无条件接受)进入节点。
更新
一些简单的实现。但您可能会阅读有关QuadTrees,R-trees和类似树的更多信息以进行空间数据搜索(请参阅QuadTree页面底部的链接), 因为这个想法的变化可能会帮助你建立更好的算法
一些示例代码,键入UNTESTED,递归地构建给定磁盘列表的四叉树,然后在到达点处递归地遍历树并对点进行分类。 树行走是O(log2(N))复杂度,最后是一个磁盘检查
def squared(x):
return x*x
class Disk(object):
def __init__(self, x, y, r):
self._x = x
self._y = y
self._r = r
def check(self, x, y):
return squared(x-self._x) + squared(y-self._y) <= squared(self._r)
class Node(object):
def __init__(self, llx, lly, urx, ury):
# nodes, in CCW
self._NE = None
self._NW = None
self._SW = None
self._SE = None
# corners
self._llx = llx
self._lly = lly
self._urx = urx
self._ury = ury
# dividers
self._dx = 0.5*(llx + urx)
self._dy = 0.5*(lly + ury)
# disk to check
self._disk = None
def is_leaf_node(self):
"""
True if node has no children
"""
if self._NE is None:
if self._NW is None:
if self._SW is None:
if self._SE is None:
return True
return False
def check_point(self, x, y):
"""
True if not covered by circle
"""
if self._disk is None:
return True
return not self._disk.check(x, y)
def check_node(node, disks):
"""
return sublist of disks which affects the node
"""
rc = []
for disk in disks:
if disk.check(node._llx, node._lly):
rc.append(disk)
elif disk.check(node._llx, node._ury):
rc.append(disk)
elif disk.check(node._urx, node._lly):
rc.append(disk)
elif disk.check(node._urx, node._ury):
rc.append(disk)
if len(rc) == 0:
return None
return rc
def build(node, disks):
subdisks = check_node(node, disks)
if subdisks is None: # empty type of leaf node
node._disk = None
return node
if len(subdisks) == 1: # simple circle leaf node
node._disk = subdisks
return node
node._NE = build(Node(self._dx, self._dy, self._urx, self._ury), disks)
node._NW = build(Node(self._llx, self._dy, self._dx, self._ury), disks)
node._SW = build(Node(self._llx, self._lly, self._dx, self._dy), disks)
node._SE = build(Node(self._dx, self._lly, self._urx, self._dy), disks)
return node
def check_point(node, x, y):
if node.is_leaf_node():
return node.check_point(x, y)
if x > node._dx: # SE of NE nodes
y > node._dy: # NE
return check_point(node._NE, x, y)
return check_point(node._SE, x, y)
# SW or NW
y > node._dy: # NW
return check_point(node._NW, x, y)
return check_point(node._SW, x, y)
# main
# in the (0,0):(1,1) square
root = build( Node(0.0, 0.0, 1.0, 1.0), disks )
rc = check_point(root, x, y)