Python,四面体(scipy.Delaunay)三维点云的一部分

Python,四面体(scipy.Delaunay)三维点云的一部分,python,numpy,3d,delaunay,Python,Numpy,3d,Delaunay,我想在3D空间中绘制船体的“横截面”,即船体与平面的交点 空间由轴X、Y、Z定义,平行于XZ的交叉平面由Y=50定义 首先,我在np.array中加载了一个3D点云: #loading colors points = np.array([(GEO.XYZRGB(rank, name, X, Y, Z)) for rank, name, X, Y, Z in csv.reader(open('colors.csv'))]) 点结构是秩、名、X、Y、Z、R、

我想在3D空间中绘制船体的“横截面”,即船体与平面的交点

空间由轴
X、Y、Z
定义,平行于XZ的交叉平面
Y=50
定义

首先,我在
np.array
中加载了一个3D
点云:

#loading colors

points = np.array([(GEO.XYZRGB(rank, name, X, Y, Z))
                  for rank, name, X, Y, Z in csv.reader(open('colors.csv'))])
  • 点结构是
    秩、名、X、Y、Z、R、G、B

  • 每个点在三维空间中由
    X,Y,Z

举几个例子:

['2' 'Y2    ' '77.89506204' '87.46909733' '42.72168896' '254' '244' '21']
['3' 'Y4    ' '76.95634543' '83.94271933' '39.48573173' '255' '234' '0']
['4' 'PINKwA' '64.93353667' '59.00840333' '84.71839733' '218' '154' '225']
...
现在,我对点进行了
scipy.Delaunay
四面体化:

# Delaunay triangulation    
tri = scipy.spatial.Delaunay(points[:,[2,3,4]], furthest_site=False) 
所以我可以得到所有的
顶点(即船体的每个奇异四面体):

我的问题:从这里开始,我有顶点,我如何找到平面和外壳之间的所有交点


感谢下面的

我给出了python代码,给定一组3d点和一个平面(由其法向量和平面上的点定义)计算3d Delaunay三角剖分(细分)以及Delaunay边与平面的交点

下图显示了单位立方体中二十个随机点与
x=0
平面相交的示例结果(交点为蓝色)。用于可视化的代码将从代码中修改。

为了实际计算平面交点,我使用以下代码。 基本功能
plane\u delaunay\u intersection
使用两个辅助功能--
collect\u edges
收集delaunay三角剖分的边(每个线段只有一个副本),以及
plane\u seg\u intersection
,它将线段与平面相交

代码如下:

from scipy.spatial import Delaunay
import numpy as np

def plane_delaunay_intersection(pts, pln_pt, pln_normal):
    """ 
    Returns the 3d Delaunay triangulation tri of pts and an array of nx3 points that are the intersection
    of tri with the plane defined by the point pln_pt and the normal vector pln_normal.
    """
    tri = Delaunay(points)
    edges = collect_edges(tri)
    res_lst = []
    for (i,j) in edges:
        p0 = pts[i,:]
        p1 = pts[j,:]
        p = plane_seg_intersection(pln_pt, pln_normal, p0, p1)
        if not np.any(np.isnan(p)):
            res_lst.append(p)
    res = np.vstack(res_lst)
    return res, tri 


def collect_edges(tri):
    edges = set()

    def sorted_tuple(a,b):
        return (a,b) if a < b else (b,a)
    # Add edges of tetrahedron (sorted so we don't add an edge twice, even if it comes in reverse order).
    for (i0, i1, i2, i3) in tri.simplices:
        edges.add(sorted_tuple(i0,i1))
        edges.add(sorted_tuple(i0,i2))
        edges.add(sorted_tuple(i0,i3))
        edges.add(sorted_tuple(i1,i2))
        edges.add(sorted_tuple(i1,i3))
        edges.add(sorted_tuple(i2,i3))
    return edges


def plane_seg_intersection(pln_pt, pln_normal, p0, p1):
    t0 = np.dot(p0 - pln_pt, pln_normal)
    t1 = np.dot(p1 - pln_pt, pln_normal)
    if t0*t1 > 0.0:
        return np.array([np.nan, np.nan, np.nan])  # both points on same side of plane

    # Interpolate the points to get the intersection point p.
    denom = (np.abs(t0) + np.abs(t1))
    p = p0 * (np.abs(t1) / denom) + p1 * (np.abs(t0) / denom)
    return p
from scipy.spatial import Delaunay
import numpy as np

def plane_delaunay_intersection(pts, pln_pt, pln_normal):
    """ 
    Returns the 3d Delaunay triangulation tri of pts and an array of nx3 points that are the intersection
    of tri with the plane defined by the point pln_pt and the normal vector pln_normal.
    """
    tri = Delaunay(points)
    edges = collect_edges(tri)
    res_lst = []
    for (i,j) in edges:
        p0 = pts[i,:]
        p1 = pts[j,:]
        p = plane_seg_intersection(pln_pt, pln_normal, p0, p1)
        if not np.any(np.isnan(p)):
            res_lst.append(p)
    res = np.vstack(res_lst)
    return res, tri 


def collect_edges(tri):
    edges = set()

    def sorted_tuple(a,b):
        return (a,b) if a < b else (b,a)
    # Add edges of tetrahedron (sorted so we don't add an edge twice, even if it comes in reverse order).
    for (i0, i1, i2, i3) in tri.simplices:
        edges.add(sorted_tuple(i0,i1))
        edges.add(sorted_tuple(i0,i2))
        edges.add(sorted_tuple(i0,i3))
        edges.add(sorted_tuple(i1,i2))
        edges.add(sorted_tuple(i1,i3))
        edges.add(sorted_tuple(i2,i3))
    return edges


def plane_seg_intersection(pln_pt, pln_normal, p0, p1):
    t0 = np.dot(p0 - pln_pt, pln_normal)
    t1 = np.dot(p1 - pln_pt, pln_normal)
    if t0*t1 > 0.0:
        return np.array([np.nan, np.nan, np.nan])  # both points on same side of plane

    # Interpolate the points to get the intersection point p.
    denom = (np.abs(t0) + np.abs(t1))
    p = p0 * (np.abs(t1) / denom) + p1 * (np.abs(t0) / denom)
    return p
np.random.seed(0)
x = 2.0 * np.random.rand(20) - 1.0
y = 2.0 * np.random.rand(20) - 1.0
z = 2.0 * np.random.rand(20) - 1.0

points = np.vstack([x, y, z]).T
pln_pt = np.array([0,0,0])  # point on plane
pln_normal = np.array([1,0,0])  # normal to plane
inter_pts, tri = plane_delaunay_intersection(points, pln_pt, pln_normal)