解析alphashape库中lambda函数:r的来源与[:,0]含义
alphashape库中lambda函数的疑问解答
问题背景
用户给出alphashape库的示例代码:
points_2d = [(0., 0.), (0., 1.), (1., 1.), (1., 0.),(0.5, 0.25), (0.5, 0.75), (0.25, 0.5), (0.75, 0.5)] alpha_shape = alphashape( points_2d, lambda ind, r: 1.0 + any(np.array(points_2d)[ind][:,0] == 0.0))
结合库的上下文代码,对两个疑问进行解答:
疑问1:变量r的来源是什么?
从库的源码上下文可以梳理出参数传递路径:
alphasimplices函数通过Delaunay三角剖分生成所有单纯形(simplex),对每个单纯形计算其外接圆半径,通过yield simplex, circumradius(simplex_points)返回单纯形的点索引和该单纯形的外接圆半径。- 在
alphashape函数的循环中,每次迭代拿到point_indices(即上述的simplex)和circumradius(外接圆半径)。 - 当传入的
alpha是可调用对象(比如示例中的lambda)时,会调用alpha(point_indices, circumradius),所以lambda里的r就是当前单纯形的外接圆半径。示例中的lambda没有使用r,但为了匹配调用时的参数数量,必须保留这个参数。
疑问2:语法[:,0]的含义是什么?
这是NumPy数组的切片索引语法,拆解来看:
np.array(points_2d)[ind]:将原始点列表转为NumPy数组后,取出索引为ind的所有点,得到一个二维数组(每行是一个点的(x,y)坐标)。[:,0]::表示选取所有行,0表示选取第0列,也就是这些点的x坐标。- 后续
== 0.0是判断这些x坐标是否为0,any()函数只要有一个点的x坐标为0就返回True(在Python中True等价于1,False等价于0)。
最终lambda函数的逻辑是:如果当前单纯形包含x坐标为0的点,返回1.0+1=2.0作为alpha值;否则返回1.0+0=1.0。
库上下文代码参考
def alphashape(points: Union[List[Tuple[float]], np.ndarray], alpha: Union[None, float] = None): coords = np.array(points) for point_indices, circumradius in alphasimplices(coords): if callable(alpha): resolved_alpha = alpha(point_indices, circumradius)
from scipy.spatial import Delaunay def alphasimplices(points: Union[List[Tuple[float]], np.ndarray]) -> \ Union[List[Tuple[float]], np.ndarray]: coords = np.asarray(points) tri = Delaunay(coords) for simplex in tri.simplices: simplex_points = coords[simplex] try: yield simplex, circumradius(simplex_points)
def circumradius(points: Union[List[Tuple[float]], np.ndarray]) -> float: points = np.asarray(points) return np.linalg.norm(points[0, :] - np.dot(circumcenter(points), points))
def circumcenter(points: Union[List[Tuple[float]], np.ndarray]) -> np.ndarray: points = np.asarray(points) num_rows, num_columns = points.shape A = np.bmat([[2 * np.dot(points, points.T), np.ones((num_rows, 1))], [np.ones((1, num_rows)), np.zeros((1, 1))]]) b = np.hstack((np.sum(points * points, axis=1), np.ones((1)))) return np.linalg.solve(A, b)[:-1]
内容的提问来源于stack exchange,提问作者David H. J.
相关产品推荐
相关产品推荐

