如何根据 python 中的某些平面拆分 3D 中的某些点
How to split some points in 3D based on some planes in python
在 3D 中 space 我有一些点(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
中的每一个除以其长度的标准化步骤,因此您可以省略它。这会影响结果的大小,但不会影响符号。
与其在 for 乘积前减去 corners[0]
,还不如从结果中减去 for 与 p
(即 np.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 有一个将所有内容放在一起的工作示例。
在 3D 中 space 我有一些点(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
中的每一个除以其长度的标准化步骤,因此您可以省略它。这会影响结果的大小,但不会影响符号。与其在 for 乘积前减去
corners[0]
,还不如从结果中减去 for 与p
(即np.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 有一个将所有内容放在一起的工作示例。