Python代码来检查一个点是否在给定的网格内

问题描述 投票:0回答:2

我正在使用 trimesh 库来检查这个。它有 mesh.contains 用于执行这些检查。我正在尝试使用 mesh.contains 截断一组线,这样新线只包含网格内部的点。

虽然这在某些情况下工作得很好,但在其他多种情况下却失败了。我附上几张图片,蓝色是截断线,红色是原始线。灰色阴影区域是网格。在一种情况下,它能够检测到外部的点并正确截断。但是,如果外部区域夹在域之间,则会出现问题。点在外面,但是这个函数无法消除它们。

代码块如下:

# create an empty array to store truncated lines
truncated_arr = []

# loop over each line in the array
for line in arr:
    new_line = []
    # loop over each point in the line and check if it's inside the mesh
    for point in line:
        if ((mesh1.contains([point])) or (mesh2.contains([point])) or (mesh3.contains([point]))):
            new_line.append(point)
    # append the truncated line to the new array
    if len(new_line) > 1:
        truncated_arr.append(new_line)

我正在寻找克服这个问题的想法?有没有办法让这个算法检测域外但夹在域的两个翼之间的点,如图所示?理想情况下,我希望这个库可以工作,但不幸的是,如果它不能工作,对其他人的建议也可能会有帮助。

谢谢。

python mesh scientific-computing stl-format trimesh
2个回答
0
投票

一种可能的解决方案是使用 mesh.ray.intersects_location() 方法对每个点进行光线投射,并计算交叉点的数量以确定该点是在网格内部还是外部。

这是实现此方法的代码的修改版本:

import numpy as np
import trimesh

def is_inside(point, meshes, direction=np.array([1.0, 0.0, 0.0]), tol=1e-5):
    count = 0

    for mesh in meshes:
        intersections, _ = mesh.ray.intersects_location(
            ray_origins=[point - direction * tol],
            ray_directions=[direction],
        )

        count += len(intersections) % 2

    return count % 2 == 1

# create an empty array to store truncated lines
truncated_arr = []

# the list of meshes
meshes = [mesh1, mesh2, mesh3]

# loop over each line in the array
for line in arr:
    new_line = []
    # loop over each point in the line and check if it's inside the meshes
    for point in line:
        if is_inside(point, meshes):
            new_line.append(point)
    # append the truncated line to the new array
    if len(new_line) > 1:
        truncated_arr.append(new_line)

给定一个点,

is_inside()
函数沿正 X 方向的轴对该点进行射线投射,然后计算射线与网格相交的次数。如果交叉点的数量是奇数,则假定该点位于网格内部。您可以通过更改
direction
参数来更改光线的方向。
tol
参数是一个小的公差值,以避免在网格表面上开始光线相交。

请注意,由于额外的光线相交计算,这种方法可能比使用 mesh.contains() 方法慢。然而,它应该更好地处理域外但夹在域的两个翼之间的点。


0
投票

另一个答案中提出的光线追踪似乎过于耗费资源,您已经拥有(大概调整良好的)

.contains
功能。我认为您需要更改操作顺序。我无法运行这段代码,但在我看来,如果不是链接这三个
mesh.contain(.) or...
,而是将所有三个分开,然后在三个结果线上使用 numpy 的集合交集,你可能会有更好的运气。

只是快速尝试一下,希望它比尝试重新实现光线追踪效果更好。并不是说它行不通,idk 但我打赌它会,但它会做大量的工作,老实说,它已经为你完成了。这是一个逻辑错误,而不是你工具的缺陷。

© www.soinside.com 2019 - 2024. All rights reserved.