三维空间碰撞问题;空间中两直线的最短距离及最近点

三维空间碰撞问题;空间中两直线的最短距离及最近点

  (2013-02-28 16:26:39)
  分类: 计算机图形学

容易理解的常规方法:

已知空间中两线段,如果它们无限变粗,判断是否相交。(主要讨论不在同一平面的情况)

线段AB 线段CD

问题的关键是求出这两条任意直线之间的最短距离,以及在这个距离上的两线最接近点坐标,判断该点是否在线段AB线段CD上。

首先将直线方程化为对称式,得到其方向向量n1=(a1,b1,c1),n2=(a2,b2,c2).

再将两向量叉乘得到其公垂向量N=(x,y,z),在两直线上分别选取点A,B(任意),得到向量AB,

求向量AB在向量N方向的投影即为两异面直线间的距离了(就是最短距离啦)。

最短距离的求法:d=|向量N*向量AB|/|向量N|(上面是两向量的数量积,下面是取模)。

设交点为C,D,带入公垂线N的对称式中,又因为C,D两点分别满足一开始的直线方程,所以得到关于C(或D)的两个连等方程,分别解出来就好了!

没有理解的简单方法:

三维空间碰撞问题;空间中两直线的最短距离及最近点_第1张图片

三维空间碰撞问题;空间中两直线的最短距离及最近点_第2张图片

三维空间碰撞问题;空间中两直线的最短距离及最近点_第3张图片

 

hdu 4741 Save Labman No.004(2013杭州网络赛)

分类: 计算几何   280人阅读  评论(3)  收藏  举报

http://blog.sina.com.cn/s/blog_a401a1ea0101ij9z.html

 空间两直线上最近点对。

这个博客上给出了很好的点法式公式了。。。其实没有那么多的tricky。。。不知到别人怎么错的。。。

[cpp]  view plain copy
  1. //#pragma comment(linker, "/STACK:1024000000,1024000000")  
  2. #include<algorithm>  
  3. #include<iostream>  
  4. #include<cstring>  
  5. #include<fstream>  
  6. #include<sstream>  
  7. #include<vector>  
  8. #include<string>  
  9. #include<cstdio>  
  10. #include<bitset>  
  11. #include<queue>  
  12. #include<stack>  
  13. #include<cmath>  
  14. #include<map>  
  15. #include<set>  
  16. #define FF(i, a, b) for(int i=a; i<b; i++)  
  17. #define FD(i, a, b) for(int i=a; i>=b; i--)  
  18. #define REP(i, n) for(int i=0; i<n; i++)  
  19. #define CLR(a, b) memset(a, b, sizeof(a))  
  20. #define debug puts("**debug**")  
  21. #define LL long long  
  22. #define PB push_back  
  23. #define MP make_pair  
  24. #define eps 1e-10  
  25. using namespace std;  
  26.   
  27. struct Point  
  28. {  
  29.     double x, y, z;  
  30.     Point(double x=0, double y=0, double z=0) : x(x), y(y),z(z){}  
  31. };  
  32. typedef Point Vector;  
  33.   
  34. Vector operator + (Vector a, Vector b) { return Vector(a.x+b.x, a.y+b.y, a.z+b.z); };  
  35. Vector operator - (Vector a, Vector b) { return Vector(a.x-b.x, a.y-b.y, a.z-b.z); };  
  36. Vector operator * (Vector a, double p) { return Vector(a.x*p, a.y*p, a.z*p); }  
  37. Vector operator / (Vector a, double p) { return Vector(a.x/p, a.y/p, a.z/p); }  
  38.   
  39. double Dot(Vector a, Vector b) { return a.x*b.x + a.y*b.y + a.z*b.z; }  
  40. double Length(Vector a) { return sqrt(Dot(a, a)); }  
  41. Vector Cross(Point a, Point b)  
  42. {  
  43.     return Vector(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x);  
  44. }  
  45.   
  46. Point a1, b1, a2, b2;  
  47. int main()  
  48. {  
  49.     int n;  
  50.     scanf("%d", &n);  
  51.     while(n--)  
  52.     {  
  53.         scanf("%lf%lf%lf", &a1.x, &a1.y, &a1.z);  
  54.         scanf("%lf%lf%lf", &b1.x, &b1.y, &b1.z);  
  55.         scanf("%lf%lf%lf", &a2.x, &a2.y, &a2.z);  
  56.         scanf("%lf%lf%lf", &b2.x, &b2.y, &b2.z);  
  57.         Vector v1 = (a1-b1), v2 = (a2-b2);  
  58.         Vector N = Cross(v1, v2);  
  59.         Vector ab = (a1-a2);  
  60.         double ans = Dot(N, ab) / Length(N);  
  61.         Point p1 = a1, p2 = a2;  
  62.         Vector d1 = b1-a1, d2 = b2-a2;  
  63.         Point ans1, ans2;  
  64.         double t1, t2;  
  65.         t1 = Dot((Cross(p2-p1, d2)), Cross(d1, d2));  
  66.         t2 = Dot((Cross(p2-p1, d1)), Cross(d1, d2));  
  67.         double dd = Length((Cross(d1, d2)));  
  68.         t1 /= dd*dd;  
  69.         t2 /= dd*dd;  
  70.         ans1 = (a1 + (b1-a1)*t1);  
  71.         ans2 = (a2 + (b2-a2)*t2);  
  72.         printf("%.6f\n", fabs(ans));  
  73.         printf("%.6f %.6f %.6f ", ans1.x, ans1.y, ans1.z);  
  74.         printf("%.6f %.6f %.6f\n", ans2.x, ans2.y, ans2.z);  
  75.     }  
  76.     return 0;  
  77. }  

你可能感兴趣的:(计算几何)