[英]Python, section of a tetrahedralized (scipy.Delaunay) 3D cloud of points
I want to draw a "cross section" of a hull in a 3D space, the intersection of the hull with a plane . 我想在3D空间中绘制船体的“横截面” ,即船体与平面的交点 。
The space is defined by axis X, Y, Z
, and the crossing plane, parallel to XZ is defined by Y = 50
该空间由
X, Y, Z
轴定义, 平行于XZ的交叉平面由Y = 50
定义
First, I loaded a cloud of 3D points
in a np.array
: 首先,我在
np.array
加载了3D points
云:
#loading colors
points = np.array([(GEO.XYZRGB(rank, name, X, Y, Z))
for rank, name, X, Y, Z in csv.reader(open('colors.csv'))])
point structure is rank, name, X, Y, Z, R, G, B
点结构是
rank, name, X, Y, Z, R, G, B
and each points is defined in the 3D space by X, Y, Z
每个点在3D空间中由
X, Y, Z
a few examples: 一些例子:
['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']
...
Now, I made a scipy.Delaunay
tetrahedralization of the points: 现在,我做了一
scipy.Delaunay
。
# Delaunay triangulation
tri = scipy.spatial.Delaunay(points[:,[2,3,4]], furthest_site=False)
So I can get all the vertices
(ie each singular tetrahedron of the hull): 这样我就可以获得所有
vertices
(即,船体的每个奇异的四面体):
# indices of vertices
indices = tri.simplices
# the vertices for each tetrahedron
vertices = points[indices]
print vertices
My question: from here, I have the vertices, how do I find all the points of intersection between the plane and the hull? 我的问题:从这里有顶点,如何找到飞机和船体之间的所有交点?
Thanks 谢谢
Below I give python code that, given a set of 3d points and a plane (defined by its normal vector and a point on the plane) computes the 3d Delaunay triangulation (tessellation) and the intersection points of the Delaunay edges with the plane. 下面,我给出python代码,给定一组3d点和一个平面(由其法向矢量和平面上的点定义),计算3d Delaunay三角剖分(镶嵌)以及Delaunay边缘与平面的交点。
The following figure visualizes the result on an example of twenty random points in the unit cube intersecting with the x=0
plane (the intersection points are colored blue). 下图以单位多维数据集中与
x=0
平面相交的二十个随机点(交点为蓝色)的示例显示了结果。 The code used for the visualization is modified from the code in this answer . 从此答案中的代码修改了用于可视化的代码。
To actually compute the plane intersection points I use the following code. 为了实际计算平面相交点,我使用以下代码。 The basic function
plane_delaunay_intersection
uses two auxiliary functions - collect_edges
to gather the edges of the Delaunay triangulation (only one copy of each segment), and plane_seg_intersection
, which intersects a line segment with a plane. 基本函数
plane_delaunay_intersection
使用两个辅助函数collect_edges
收集Delaunay三角剖分的边缘(每个线段只有一个副本),以及plane_seg_intersection
,该线与平面与线段相交。
Here is the code: 这是代码:
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
The following code was used to generate the input for the example figure above: 以下代码用于生成以上示例图的输入:
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.