python - 如何根据python中的一些平面分割3D中的一些点
问题描述
在 3D 空间中,我有一些点 (和) x
,并希望通过重建一些现有平面来拆分它们。这些是我的简化点:y
z
points=[[np.array([[20., 20., 60.], [20., 30., 65.], [55., 30., 80.], [80., 10., 60.]]),\
np.array([[20., 10., 55.], [60., 30., 70.], [70., 15., 20.]])]]
大列表有一个包含两个数组的子列表。我现实points
有更多的子列表,每个子列表也可能有几个数组。然后,在这个简化的例子中,我在点之间有两个平面。我有两个表面的四个角:
four_corners= [[np.array([[50., 5., 5.],
[50., 45., 5.],
[70., 45., 95.],
[70., 5., 95.]]),
np.array([[30., 5., 95.],
[30., 45., 95.],
[60., 5., 5.],
[60., 45., 5.]])]]
four_corners
有一个子列表,这个子列表也有两个数组,即两个表面。然后,第一个子列表的每个数组points
应该分为三个部分,因为有两个表面正在穿过它们。如果有一个平面,我将对每个阵列进行两次拆分。我想根据曲面拆分我的观点。我试图修改这个解决方案,但我无法达到我想要的。我尝试了以下代码,但没有成功:
splitted_arr=[]
for m in points:
for surfaces in four_corners:
for i, j in zip (m, surfaces):
j=np.array(j)
corners = [j[0], j[1], j[2]]
v1 = np.subtract(corners[1], corners[0])
v1 = v1 / np.linalg.norm(v1)
v2 = np.subtract(corners[-1], corners[0])
v2 = v2 / np.linalg.norm(v2)
orth = np.cross(v1, v2)
for p in i:
p_moved = np.subtract(p, corners[0])
d = np.dot(orth, p_moved)
if d < 0:
splitted_arr.append (p)
else:
splitted_arr.append (p)
我想得到:
[[np.array([[20., 20., 60.], [20., 30., 65.]]), np.array([[55., 30., 80.]]), np.array([[80., 10., 60.]]),\
np.array([[20., 10., 55.]]), np.array([[60., 30., 70.]]), np.array([[70., 15., 20.]])]]
关键规则是我想总是使用现有的平面来分割我的点。在此之前,我非常感谢任何帮助和贡献。
解决方案
你的方法的一般原则似乎是合理的。您在案例区分的每个分支中都调用了这一事实,这一事实splitted_arr.append (p)
几乎没有实际意义。所以说这是你的主要问题。
一些观察:
请注意,您从未使用过
j[3]
. 因此,您可以通过仅使用三个点而不是四个点来定义平面来简化事情,这样做可以消除 for 点不位于单个平面上的不一致的可能性。您可能希望计算
ortho
循环外的每个表面点,以减少重复计算并提高性能。您的应用程序不需要将每个
v1
,除以长度的标准化步骤,因此您可以省略它。v2
这将影响结果的大小,但不会影响符号。与其
corners[0]
在 for 乘积之前进行减法,不如从 for 乘积的结果中减去该乘积的 for 和p
(ienp.dot(orth, corners[0])
)。这用标量减法代替向量减法。或者,更好的是,与其减去该数字并与零进行比较,不如立即与该数字进行比较。同样,拐角的点积是您可以在所有点的循环之外计算的东西。所有这些都将有助于提高性能而不改变结果(除了可能的舍入差异)。
为每个平面预先计算ortho
矢量和角点积在概念上与将其转换为标准形式相同,即为平面上的每个点找到a, b, c, d
这样的。a*x+b*y+c*z=d
对于那些没有在 numpy 库上构建的读者来说,这种表述可能特别有吸引力。
在您的问题中,您写下(我的重新格式化除外)您想得到
[[np.array([[20., 20., 60.], [20., 30., 65.]]),
np.array([[55., 30., 80.]]),
np.array([[80., 10., 60.]]),
np.array([[20., 10., 55.]]),
np.array([[60., 30., 70.]]),
np.array([[70., 15., 20.]])]]
为什么?为什么前两个点在一个组中,而其他所有点都是分开的?你真的想再次将多个点组合成一个二维数组吗?
在下面的评论中,您写道,表达相对于多个平面的关系是使这变得困难的部分原因。本质上,给定一个点和一个(定向的)平面列表,您可以决定该点是在这些平面中的每一个的正侧还是负侧(忽略完全在平面上的情况,由于舍入原因应该无论如何都不要依赖)。因此,对于每个点和平面,您会获得一些相关信息,对于此类平面的列表,您会获得这些比较结果的列表。您可以将它们用作键来对未被任何平面相互分离的点进行分组。选择每个平面的哪一侧是正面的,哪一侧是负面的并不重要,只要它始终如一地完成,即每个ortho
只计算一次或至少总是以相同的方式计算。
https://ideone.com/oo5GFg有一个将所有内容组合在一起的工作示例。
推荐阅读
- c - C检测弹出子进程中的错误
- google-apps-script - 是否可以使用谷歌应用脚本在谷歌文档用户界面上创建一个“按钮”?
- android - ViewPager : setPageTransformer 错误的视图翻译
- view - 从一个视图转换到另一个 SwiftUI
- database - 如何编写一个scala程序来查找两个表中属性之间的语义匹配
- ruby-on-rails - 为 Rails 模型创建 Elasticsearch 索引时如何修复“非法参数异常”?
- ios - 无效的凭据谷歌日历 API
- gradle - 如何在另一个子项目的 gradle 任务中调用一个子项目的代码?
- javascript - 获取 v-model 值并使用 v-for 创建循环
- python - 如何使用 pytorch 将系列 numpy 数组转换为张量