Python 如何检测两段(在三维空间中)是否相交?
只检查,不需要找到重点 坐标z不是0。 堆栈溢出中的旧问题都是针对2d的。Python 如何检测两段(在三维空间中)是否相交?,python,3d,intersect,segment,Python,3d,Intersect,Segment,只检查,不需要找到重点 坐标z不是0。 堆栈溢出中的旧问题都是针对2d的。 提前谢谢我可以告诉你你可以使用的数学,尽管它有点复杂。 以参数形式为每一行编写方程式。然后找到每行的参数。 见下例: (a1,a2,a3)________________(b1,b2,b3) A B and second line (c1,c2,c3)________________(d1,d2,d3) C
提前谢谢我可以告诉你你可以使用的数学,尽管它有点复杂。 以参数形式为每一行编写方程式。然后找到每行的参数。 见下例:
(a1,a2,a3)________________(b1,b2,b3)
A B
and second line
(c1,c2,c3)________________(d1,d2,d3)
C D
所以这个等式是
A+tB-A表示第一条直线这实际上表示t在0和1之间的线段上的一个点
和
第二条线路的C+sD-C
其中t和s是参数
其值应介于0和1之间,以使点位于线段上。0是A,1是B
这里A的意思是a1,a2,a3
因此,你可以将交点的两个方程(如果有)相等,并找到满足三个方程的t和s:
a1+t(b1-a1)=c1+s(d1-c1)
a2+t(b2-a2)=c2+s(d2-c2)
a3+t(b3-a3)=c3+s(d3-c3)
t和s应介于0和1之间,以使点真正位于线段上。所以我希望你能明白:
代码:
这是代码段。希望您最终得到它:有几种方法可以进行直线相交测试。经典的方法是使用线性代数,即求解线性矩阵系统,但从软件开发的角度来看,我更喜欢几何代数方法,以Pucker坐标的形式,它只需要实现向量代数运算,即。,在求解线性系统时,叉积和点积比矩阵运算更易于编码 向量代数解 给定线段p受点P1和P2限制,线段Q受点Q1和Q2限制 线的参数化形式如下所示: Pt=P1+tp2-P1 Qt=Q1+tq2-Q1 其中t是区间[0 1]中的实数 如果两条线相交,则以下等式成立: Pt0=Qt1 假设存在两个未知数字t0和t1。将上述方程展开,我们得到: t0 P2-P1-t1 Q2-Q1=Q1-P1 为了避免处理矩阵代数,我们可以尝试使用向量代数和替换法求解系统: t0 P2-P1-t1 Q2-Q1=Q1-P1 t0=a+t1+b t1=C•Q1-1-AP1-AP2/|C^2 其中: a=P2-P1•Q1-P1/| P2-P1 | ^2 b=P2-P1•Q2-Q1/| P2-P1 | ^2 C=b P2-P1-Q2-Q1 其中•是点积。如果t0和t1都在区间[01]内,则交点Pt0或Qt1存在 采摘机坐标方式 给定线段p受点P1和P2限制,线段Q受点Q1和Q2限制 线p的拾取器坐标由一对3d向量Pd,Pm给出: Pd=P2-P1 Pm=P1×P2 式中,Pm是P1和P2的叉积。可以用完全相同的方法计算线Q的采摘器坐标Qd,Qm 线p和Q只有在共面时才能相交。线P和Q是共面iif: Pd•Qm+Qd•Pm=0 其中•是点积。由于机器的精度有限,稳健测试不应检查零,而应检查少量。如果Pd×Qd=0,则直线平行,此处0为零矢量。同样,应针对instamce进行稳健测试,以确保Pd×Qd的平方长度较小 如果两条线不平行,那么它们是共面的,它们的相交点在普莱克的行话中称为相交点: x=Pm•N Qd-Qm•N Pd-Pm•Qd N/Pd×Qd•N 其中N是任意坐标轴向量,即1,0,0或0,1,0或0,0,1,使得Pd×Qd•N为非零 如果p和Q均未通过原点,则其采摘器坐标Pm和Qm将分别为非零,且以下sinpler公式将起作用 x=Pm×Qm/Pd•Qm 有关采摘器坐标的介绍,请参见: 关于一般的交点公式,请参见推论6: 线性代数方法 给定线段p受点P1和P2限制,线段Q受点Q1和Q2限制 线的参数化形式如下所示: Pt=P1+tp2-P1 Qt=Q1+tq2-Q1 其中t是区间[0 1]中的实数 如果两条线相交,则以下等式成立: Pt0=Qt1 假设存在两个未知数字t0和t1。将上述方程展开,我们得到: t0 P2-P1-t1 Q2-Q1=Q1-P1 我们可以通过在矩阵代数中表示上述方程来求解t0和t1: A x=B 其中,A是3x2矩阵,向量P2-P1的坐标在第一列,向量Q2-Q1的坐标在第二列;x是未知量t0和t1的2x1列向量,B是坐标为矢量Q1-P1的3x1列向量 经典地,系统可以通过计算矩阵A的伪逆来求解,表示为A^+: A^+=A^T A^-1 A^T 见: 幸运的是,Python中的任何矩阵包都应该能够计算上述计算 这很容易,也许也很有效 如果将A与其伪逆A^+相乘等于单位矩阵I,即A^+==I,则存在唯一答案交点,您可以通过计算以下乘积得到它: x=A^+B 当然,如果你首先不能计算伪逆,例如,因为A^ta是奇异的,即行列式为零,那么就不存在交集
因为我们处理的是线段,交点在点Px0或Qx1,如果x0和x1都在区间[01]。thx很多!但是除了使用Symphy库之外,我不知道如何解决它。起初,我使用Symphy 3dsegment处理它,但是当我导入Symphy时,然后我将无法通过pyinstaller/py2exe将.py文件编译为.exe文件。然后我希望任何人都能给出一种只使用标准库的方法。我不知道sympy3d。。。如果您正在使用此方法,则不需要使用它。可以使用numpy来求解方程。否则,不需要任何特殊模块。您可以使用numpy搜索解联立方程组。也不能使用numpy,可能会导致编译到exe文件失败或文件非常大。如果您不能使用任何库,则必须使用纯数学解联立方程组!这是我的愿望,但我不知道怎么做,你能给我一些建议吗?Pm•N和Pm•N Qd中的Qd之间的操作是什么?这是标量乘法吗?@VictorSg是的,这是标量乘法,也称为标量积。
#input a1,a2,a3 and all the other components here.
#define all constants required for solving t and s
A=b1-a1
B=c1-d1
C=c1-a1
D=b2-a2
E=c2-d2
F=c2-a2
#find t and s using formula
t=(C*E-F*B)/(E*A-B*D)
s=(D*C-A*F)/(D*B-A*E)
#check if third equation is also satisfied(we have 3 equations and 2 variable
if ((t*(b3-a3)+s*(c3-d3))==c3-a3):
if(0<=t<=1 and 0<=s<=1):
print('line segments intersect')
else:
print ('line segments intersect on being produced')