三维几何-点和直线

xiaoxiao2025-07-16  11

直线的表示。

直线仍然可以用参数方程(点和向量)来表示,并且射线和线段仍然可以看成参数有取值范围限制的直线,并且点到直线的投影和二维情形一样。

点到直线/线段的距离。仍然可以用面积法(注意三维叉积是向量,要用Length函数而不是fabs)。

点P到直线AB的距离:

double DistanceToLine(const Point3 &P, const Point3 &A, const Point3 &B) { Vector3 v1, v2; v1 = B - A; v2 = P - A; return Length(Cross(v1, v2)) / Length(v1); }

点P到线段AB的距离。

double DistanceToSegment(const Point3 &P, const Point3 &A, const Point3 &B) { if(A == B) return Length(P-A); Vector3 v1, v2, v3; v1 = B - A; v2 = P - A; v3 = P - B; if(dcmp(Dot(v1, v2)) < 0) return Length(v2); else if(dcmp(Dot(v1, v3)) > 0) return Length(v3); else return Length(Cross(v1, v2)) / Length(v1); }

异面直线的最短距离:

假设两条直线分别为l1=(p1,v1)和l2=(p2,v2),那么最短距离会在某个q1=p1 + sv1 和 q2 = p2 + tv2 上取到,其中q1和q2分别在l1和l2上

且q1q2是这两条异面直线的公垂线。向量q1q2=q2-q1 = p2-p1 + tv2-sv1垂直于v1, 因此Dot(p2-p1+tv2-sv1)=0.分配率:

Dot(p2-p1,v1) + t*Dot(v2,v1)-s*Dot(v1,v1)=0. 根据q1q2垂直于v2还可以得到一个一次方程,联立。

求异面直线p1+su和p2+tv的公垂线对应的s.如果平行/重合,则返回false。 两条直线相交的情况下算出的距离为0,并且返回true。

bool LineDistance3D(const Point3 &P1,const Vector3 &u,const Point3 &P2,const Vector3 &v, double &s) { double a, b; b = Dot(u, u)*Dot(v, v) - Dot(u, v)*Dot(u, v); if(dcmp(b) == 0) return false; a = Dot(u, v)*Dot(v, P1-P2) - Dot(v, v)*Dot(u, P1-P2); s = a / b; return true; }

用N条直线来划分空间,最多可以划分为 (N^3 + 5N + 6) / 6 部分。

转载请注明原文地址: https://www.6miu.com/read-5033189.html

最新回复(0)