我有一个表面上有点的3D球体。这些点以球坐标表示,因此方位角、仰角和r
例如,我的数据集是一个矩阵,包含给定球体上的所有可用点:
azimuth elevation r
[[ 0. 90. 1.47 ]
[ 0. 85.2073787 1.47 ]
[ 0. 78.16966379 1.47 ]
[ 0. 70.30452954 1.47 ]
[ 0. 62.0367492 1.47 ]
[ 0. 53.56289304 1.47 ]
[ 0. 45. 1.47 ]
[ 0. 36.43710696 1.47 ]
[ 0. 27.9632508 1.47 ]
[ 0. 19.69547046 1.47 ]
[ 0. 11.83033621 1.47 ]
[ 0. 4.7926213 1.47 ]
[ 0. 0. 1.47 ]
[ 0. -4.7926213 1.47 ]
[ 0. -11.83033621 1.47 ]
[ 0. -19.69547046 1.47 ]
[ 0. -27.9632508 1.47 ]
[ 0. -36.43710696 1.47 ]
[ 0. -45. 1.47 ]
[ 0. -53.56289304 1.47 ]
[ 0. -62.0367492 1.47 ]
[ 0. -70.30452954 1.47 ]
[ 0. -78.16966379 1.47 ]
[ 0. -85.2073787 1.47 ]
[ 0. -90. 1.47 ]
[ 1.64008341 -1.6394119 1.47 ]
[ 1.64008341 1.6394119 1.47 ]
[ 2.37160039 8.01881788 1.47 ]
[ 2.37160039 -8.01881788 1.47 ]
[ 2.80356493 -15.58649429 1.47 ]
[ 2.80356493 15.58649429 1.47 ]
[ 3.16999007 23.70233802 1.47 ]
[ 3.16999007 -23.70233802 1.47 ]
[ 3.56208248 -32.09871039 1.47 ]
[ 3.56208248 32.09871039 1.47 ]
[ 4.04606896 40.63141594 1.47 ]
[ 4.04606896 -40.63141594 1.47 ]
[ 4.1063771 -4.09587122 1.47 ]
ecc...
注意:我故意省略了完整的数据矩阵,因为它包含了相当多的数据。如果需要/需要使问题完全可再现,我将提供完整数据
此矩阵表示类似于此图像的内容:
给定一个任意点,我想计算数据集中“包含”输入点的3个最近点
到目前为止,我的代码如下:
def compute_three_closest_positions(self, azimuth_angle, elevation):
requested_position = np.array([azimuth_angle, elevation, 0])
# computing the absolute difference between the requested angles and the available one in the dataset
result = abs(self.sourcePositions - requested_position) #subtracting between dataset and requested point
result = np.delete(result, 2, 1) # removing the r data
result = result.sum(axis=1) #summing the overall difference for each point
# returning index of the closest points
indexes = result.argsort()[:3]
closest_points = self.sourcePositions[indexes]
return closest_points
基本上,我是从矩阵数据集中的所有点(self.sourcePositions
)中减去请求的方位角和仰角,然后对每个点的这些差异求和,计算前3个最小索引,然后使用这些索引访问数据集中的点
代码运行良好,问题是有时我会得到3个不包含请求点的最近点
示例:
错的一个:
Requested point: azimut, elevation, distance
[200 0 1.47]
# As you might notice, the requested point is not inside the triangle created by the 3 closest points
Three closest points: azimut, elevation, distance
[[199.69547046 0. 1.47 ]
[199.40203659 5.61508214 1.47 ]
[199.40203659 -5.61508214 1.47 ]]
好的:
Requested position:
[190 0 1.47]
# As you can notice, in this case the requested point is inside the triangle generated by the closest 3 points
Three closest points:
[[191.83033621 0. 1.47 ]
[188.02560265 2.34839855 1.47 ]
[188.02560265 -2.34839855 1.47 ]]
我如何解决这个问题?我想得到3个最近的点,其中“三角形”(我在球面上,所以它不是真正的三角形)包含我请求的点
从一开始
azimut+elevation
听起来不适合这个,我更喜欢latitude+longitude
therms,因为您使用的是其他东西现在,如注释中所述,如果您的点形成一个规则的网格,您可以创建一个方程,将拓扑映射到点,然后再映射到由数组中的点的整数索引(或2个索引)描述拓扑的位置。但是,如果您无法推断这一点,或者网格不规则,则可以执行以下操作:
对数组重新排序,使其按纬度和长度排序
所以经度在
<0,2*PI>
中,纬度在<-PI/2,+PI/2>
中,所以我将根据这两个参数对数组进行排序,而纬度具有更大的优先级(权重)。让我们调用这个新数组pnt[]
将点
p
映射到球体的最近顶点只需进行二进制搜索
pnt[]
,直到找到比p
更大或相等纬度的点索引ix
然后从
ix
线性搜索(如果您将pnt[]
重新排序为切片或记住每个纬度有多少个点,则可以使用二进制搜索),直到找到小于或等于p
的最大纬度现在
pnt[ix]
是球面上距离p
最近的点列出与
pnt[ix]
最近的邻居所以简单地说
pnt[ix]
是从经度的左侧开始的,所以pnt[ix+1]
应该是下一个点(如果你穿过数组大小,你需要用蛮力检查这些点,但只是数组中的最后几个点)现在我们只需要在这两个点的下方或上方找到相应的点(取决于
p
在哪一侧)。因此,以与#2
相同的方式找到离p
最近的两个点,但纬度越小越大(前后各一个切片)。这将得到3*2 points
,它形成(始终使用首先找到的2个点)4个潜在三角形测试可能的三角形
所以你们有势三角形
p0,p1,p2
,它和球面平行。因此,只需将点投影到其平面上:所以
u,v
是基向量p0
是平面的原点。。。现在p'
的测试在三角形内部,所以使用2D和重心坐标或利用叉积检查CW/CCW,如:因此,如果三角形的所有三条边对
p'
的顺时针/逆时针方向的距离相同,那么您就找到了三角形相关问题 更多 >
编程相关推荐