【发布时间】:2019-10-03 05:59:01
【问题描述】:
问题是:如何在同一个语句中使用两个np.where,像这样(过于简单化):
np.where((ndarr1==ndarr2),np.where((ndarr1+ndarr2==ndarr3),True,False),False)
如果没有达到第一个条件语句,则避免计算第二个条件语句。
我的第一个目标是在三角形中找到一条射线的交点,如果有的话。这个问题可以通过这个算法解决(在stackoverflow上找到):
def intersect_line_triangle(q1,q2,p1,p2,p3):
def signed_tetra_volume(a,b,c,d):
return np.sign(np.dot(np.cross(b-a,c-a),d-a)/6.0)
s1 = signed_tetra_volume(q1,p1,p2,p3)
s2 = signed_tetra_volume(q2,p1,p2,p3)
if s1 != s2:
s3 = signed_tetra_volume(q1,q2,p1,p2)
s4 = signed_tetra_volume(q1,q2,p2,p3)
s5 = signed_tetra_volume(q1,q2,p3,p1)
if s3 == s4 and s4 == s5:
n = np.cross(p2-p1,p3-p1)
t = np.dot(p1-q1,n) / np.dot(q2-q1,n)
return q1 + t * (q2-q1)
return None
这里有两个条件语句:
- s1!=s2
- s3==s4 & s4==s5
现在因为我有 >20k 的三角形要检查,我想同时在所有三角形上应用这个函数。
第一个解决方案是:
s1 = vol(r0,tri[:,0,:],tri[:,1,:],tri[:,2,:])
s2 = vol(r1,tri[:,0,:],tri[:,1,:],tri[:,2,:])
s3 = vol(r1,r2,tri[:,0,:],tri[:,1,:])
s4 = vol(r1,r2,tri[:,1,:],tri[:,2,:])
s5 = vol(r1,r2,tri[:,2,:],tri[:,0,:])
np.where((s1!=s2) & (s3+s4==s4+s5),intersect(),False)
其中 s1,s2,s3,s4,s5 是包含每个三角形的值 S 的数组。问题是,这意味着我必须为所有三角形计算 s3、s4 和 s5。
现在理想的是仅当语句 1 为真时才计算语句 2(和 s3、s4、s5),如下所示:
check= np.where((s1!=s2),np.where((compute(s3)==compute(s4)) & (compute(s4)==compute(s5), compute(intersection),False),False)
(为了简化解释,我只是说“计算”而不是整个计算过程。这里,“计算”只对适当的三角形进行)。
现在这个选项当然不起作用(并且计算 s4 两次),但我很乐意就类似的过程提出一些建议
【问题讨论】:
-
使用掩码数组。它们允许您计算条件,然后仅在条件适用的情况下计算其他内容
-
条件 1 very 不是不太可能失败吗?这意味着即使您能够短路电路,您也只能保存对条件 2 的一小部分评估?
-
您好,感谢您的快速解答!我会尝试第一个选项,然后再找你。关于第二条评论,它实际上在“简化”网格中发生了很多。在检查条件一之前和之后的长度时,我从 15k 到 9k 个三角形。
-
@RolandSireyjol 啊,我明白了,我被你的函数名
signed_tetra_volume愚弄了,我相信这不是有符号四面体体积,而是有符号四面体体积的符号,也就是方向。 -
是的,这是另一个帖子的功能,很抱歉造成混淆。顺便说一句,因为我们只使用符号,除以 6 是没有用的。在另一点上,请注意,此函数会为某些特定三角形返回 0(可能当所有 3 个点都在同一条线上时,我正在调查它)。因此,像 s3=s4 或 s4=s5 这样的条件不成立,尽管光线穿过三角形)。如果您想了解有关此的更多详细信息,我可以提供一些信息并在找到后更新修复程序。
标签: python-3.x numpy optimization geometry