我有一个复杂的几何问题。
我有两个系列的点,用它们的x、y和z表示为numpy数组(实际上,我在每个系列中有数千个点,但为了更好地理解,这里将其简化)。
第一个数据集(arr_1
)表示切割面。该曲面通常是垂直的,并置换水平曲面。第二组是由曲面(表示arr_1
的曲面)置换的垂直曲面的点。目前,我在这两组数据中有一些冗余数据。首先,在arr_1
中,我更喜欢只有四个角点,并使用它们自己制作曲面。其次,在{arr_1
的四个角构成
import numpy as np
arr_1= np.array ([[31.95548952, 7.5 , 12.5 ],
[31.95548952, 22.5 , 12.5 ],
[37.5 , 7.5 , 24.20636043],
[37.5 , 22.5 , 24.20636043],
[43.78154278, 7.5 , 37.5 ],
[43.78154278, 22.5 , 37.5 ],
[55.32209575, 7.5 , 62.5 ],
[55.32209575, 22.5 , 62.5 ],
[62.5 , 7.5 , 78.50696445],
[62.5 , 22.5 , 78.50696445],
[66.52446985, 7.5 , 87.5 ],
[66.52446985, 22.5 , 87.5 ]])
arr_2= np.array([[87.5 , 7.5 , 49.99997914],
[87.5 , 22.5 , 50.00001192],
[62.5 , 7.5 , 50.00004172],
[62.5 , 22.5 , 50.00007749],
[46.8747884 , 7.5 , 62.5 ],
[46.87483609, 22.5 , 62.5 ],
[37.5 , 7.5 , 69.99973059],
[37.5 , 22.5 , 69.99977231],
[12.5 , 7.5 , 70.00012398],
[12.5 , 22.5 , 70.00015974]])
然后,我使用以下代码查找这两个数组的每组之间的距离:
from scipy.spatial import distance
distances=distance.cdist(arr_1, arr_2)
当我运行它时,distances
是一个包含12行10列的数组。
现在,我想删除arr_2
的点,它比arr_1
的任何点的阈值(比如10)更接近。在第一张上传的照片中,我用黑色矩形显示了这两点。提出了一个很好的解决方案here,但它并没有解决我的问题,因为我想比较arr_1
的每一行与arr_2
的每一行的距离。我很感激任何解决办法。
事实上,arr_1
包含曲面的点,但我不需要所有点来生成曲面。我只选择这一组的角来制作我的曲面。我使用了一个非常耗时的for循环,因此我非常欣赏任何更快的方法来查找我的点的角:
corner1 = np.array(arr_1.min (axis=0)) # this gives the row containing MIN values of x,y and z
corner2 = np.array([])
corner4 = np.array([])
corner3 = np.array(arr_1.max (axis=0)) # this gives the row containing MAX values of x,y and z
# the next block will find the corner in which x and y are minimum and z is maximum
for i in arr_1[:,0]:
if i == max (arr_1[:,0]):
for j in arr_1[:,1]:
if j == min (arr_1[:,1]):
for h in arr_1[:,2]:
if h == max (arr_1[:,2]):
corner2 = np.append(corner2, np.array([i,j,h]))
corner2=corner2[0:3]
# the next block will find the corner in which x and z are minimum and y is maximum
for m in arr_1[:,0]:
if m == min (arr_1[:,0]):
for n in arr_1[:,1]:
if n == max (arr_1[:,1]):
for o in arr_1[:,2]:
if o == min (arr_1[:,2]):
corner4 = np.append(corner4, np.array([m,n,o]))
corner4=corner4[0:3]
最后,在提取四个角点之后,我想使用它们制作一个曲面,并找到arr_2上相邻点的垂直(绿色箭头)或水平(红色箭头)投影。我不知道如何找到曲面和投影。 感谢您阅读并关注我的详细问题!如果有人提出任何解决方案,我将不胜感激。
让我们把这个问题分成几个部分
arr_1
李>arr_2
所述李>arr_2
中建立关于该交叉点的一些阈值李>我在这里展示的方法是假设数据是某个真值的度量,您希望对该值的最佳猜测执行这些操作,而不是原始数据。为此目的:
第1部分:平面最小二乘拟合
有两种不同的方法来描述平面,例如法向量和点。最小二乘拟合最简单的方法可能是
假设您的数据表现良好,那么使用该方程进行简单拟合应该没有问题
由于不可能有超过四个点的单一解决方案,因此可以运行^{} 以获得根据MSE优化的值:
如果
arr_2
也是一个平面,则对它执行相同的操作以获得plane_2
第2部分:平面相交
许多平面相交的解依赖于平面的法向量。我将假设这两个平面都依赖于Y坐标(从图上看,这似乎是安全的)。在这种情况下,您可以在数学堆栈交换上遵循this answer。设置
y = t
,您可以从系统中求解该行这里,向量
[a1, b1, c1]
是plane_1
。在解决了细节之后,你会得到这是
t
的任何值的参数化第3部分:点到线的距离
要根据
m
和b
对上面计算的线的arr_2
值设置阈值,需要一个点与线之间距离的公式。这可以通过例如postshere和here中的方法来实现例如,单点
p
可以按如下方式处理:如果您只对阈值处理感兴趣,可以将
dist**2
与阈值的平方进行比较,并在平方根上保存一些循环,因为这两个函数都是单调的TL;DR
输入:
arr_1, arr_2, distance_threshold
附录1:RMSE
如前所述,这种方法的真正优点(除了它将算法限制在~O(n)之外)是它消除了数据中的噪声。您可以使用最小二乘拟合的结果来计算有关拟合的平面数据的RMSE,以了解测量值的实际平面度。
lstsq
的第二个返回值是RMSE度量附录2:点到平面的距离
如果
arr_2
中的数据确实不是平面的,您可以稍微改变它的子集。您可以直接使用单个点与平面之间的距离公式,而不是查找一对平面的交点,如here所示:然后代码变为
下面是我编写的一些代码,它涵盖了问题的第一部分,即从点集合中查找和定义“曲面”
任何平面(平面)都可以用公式定义,其中a、b、c是系数,d是常数。我们可以将其写入如下函数:
然后,在一些导入之后,我们可以使用scipy的curve_fit搜索并找到最适合每个数组的函数的参数。curve_fit接受
linear_plane
函数的输入值,并尝试调整a、b、c,以便该函数的结果与包含大量-1
的a列表匹配。这来自于重新排列方程,其中d=1其中
v1
,v2
中的每一个都是系数a、b、c,它们最接近地定义了您所讨论的两个平面err1
和err2
显示剩余的“错误”,因此如果这些错误太大,请小心现在找到了系数,您可以使用它们来可视化两个平面:
在这里,我们为每个平面的最大和最小边界内的所有x和y计算一组z值,然后将其绘制为显示交点的曲面:
我注意到Mad Physicist 刚刚发布了一个更完整的答案,所以现在就把这个留在这里。我想做的一件事是扩展曲面拟合,这样平面就不必是线性的,就像一个类似于3d多项式的函数,它应该是一个替换
curve_fit
调用中使用的函数的例子这里缺少的另一部分是如何计算描述这两个平面交叉位置的直线方程,我相信在另一个(更好的)答案中可以找到
相关问题 更多 >
编程相关推荐