分享

判断同一平面内任意两线段是否相交的方法

 jason zhai 2010-09-19

原创  判断同一平面内任意两线段是否相交的方法 收藏

本文给出一种判断同一平面内两线段相交的判定方法。如下图:

  如果两线段相交,则两线段必然相互跨立对方。  
  若P1P2跨立Q1Q2   ,则矢量(P1 - Q1)和( P2 - Q1)位于矢量(Q2 - Q1)的两侧,  
  即(( P1 - Q1) × ( Q2 - Q1 )) *(( P2 - Q1) × ( Q2 - Q1 )) <   0。  
  上式可改写成((P1 - Q1) × ( Q2 - Q1 ))  * (( Q2 - Q1) × (P2 - Q1 ))  >   0。  
  当(P1 - Q1) × (Q2 - Q1) = 0 时,说明 (P1 - Q1 ) 和(Q2 - Q1)共线, 但是因为已经通过快速排斥试验,所以P1 一定在线段   Q1Q2上;  
  同理,(Q2 - Q1 ) ×(P2 - Q1 ) =  0 说明P2 一定在线段Q1Q2上。  
  所以判断P1P2跨立Q1Q2的依据是:  
  (( P1 - Q1 )  ×  (Q2 - Q1))* *((Q2 - Q1 ) × (P2 - Q1)) >= 0。  
  同理判断Q1Q2跨立P1P2的依据是:  
  ( Q1 - P1 ) × ( P2 - P1 ) * ( P2 - P1) × ( Q2  - P1) >= 0。  

代码实现:

 

  1. #include <iostream>  
  2. #include <math.h>  
  3. using namespace std;  
  4.   
  5. #define ABS_FLOAT_0 0.0001  
  6.   
  7. struct pointf   
  8. {  
  9.     float x;  
  10.     float y;  
  11. };  
  12. struct Vectorf3D  
  13. {  
  14.     float x;  
  15.     float y;  
  16.     float z;  
  17. };  
  18.   
  19. bool IsIntersectLine(  
  20.                      const pointf p1, // 线段1起点   
  21.                      const pointf p2, // 线段1终点  
  22.                      const pointf q1, // 线段2起点  
  23.                      const pointf q2  // 线段2终点  
  24.                      )  
  25. {  
  26.     Vectorf3D v1, v2, v3, v4;  
  27.     v1.x = (p1.x - q1.x);  
  28.     v1.y = (p1.y - q1.y);  
  29.     v1.z = 0.0;  
  30.   
  31.     v2.x = (q2.x - q1.x);  
  32.     v2.y = (q2.y - q1.y);  
  33.     v2.z = 0.0;  
  34.   
  35.     //计算v1,v2的叉乘  
  36.     v3.x = v1.y * v2.z - v1.z * v2.y;  
  37.     v3.y = v1.z * v2.x - v1.x * v2.z;  
  38.     v3.z = v1.x * v2.y - v1.y * v2.x;  
  39.   
  40.     v1.x = (p2.x - q1.x);  
  41.     v1.y = (p2.y - q1.y);  
  42.     v1.z = 0.0;  
  43.   
  44.     //计算v2,v1的叉乘  
  45.     v4.x = v2.y * v1.z - v2.z * v1.y;  
  46.     v4.y = v2.z * v1.x - v2.x * v1.z;  
  47.     v4.z = v2.x * v1.y - v2.y * v1.x;  
  48.   
  49.     // 计算v3,v4的点积  
  50.     float fTemp1 = v3.x * v4.x + v3.y * v4.y + v3.z * v4.z;  
  51.   
  52.     v1.x = (q1.x - p1.x);  
  53.     v1.y = (q1.y - p1.y);  
  54.     v1.z = 0.0;  
  55.   
  56.     v2.x = (p2.x - p1.x);  
  57.     v2.y = (p2.y - p1.y);  
  58.     v2.z = 0.0;  
  59.   
  60.     //计算v1,v2的叉乘  
  61.     v3.x = v1.y * v2.z - v1.z * v2.y;  
  62.     v3.y = v1.z * v2.x - v1.x * v2.z;  
  63.     v3.z = v1.x * v2.y - v1.y * v2.x;  
  64.   
  65.     v1.x = (q2.x - p1.x);  
  66.     v1.y = (q2.y - p1.y);  
  67.     v1.z = 0.0;  
  68.   
  69.     //计算v2,v1的叉乘  
  70.     v4.x = v2.y * v1.z - v2.z * v1.y;  
  71.     v4.y = v2.z * v1.x - v2.x * v1.z;  
  72.     v4.z = v2.x * v1.y - v2.y * v1.x;  
  73.   
  74.     // 计算v3,v4的点积  
  75.     float fTemp2 = v3.x * v4.x + v3.y * v4.y + v3.z * v4.z;  
  76.   
  77.     if ((fTemp1 >= ABS_FLOAT_0) && (fTemp2 >= ABS_FLOAT_0))  
  78.     {  
  79.         return true;  
  80.     }  
  81.     else  
  82.     {  
  83.         return false;  
  84.     }  
  85. }  
  86.   
  87. void main(void)  
  88. {  
  89.     pointf p1, p2, q1, q2;  
  90.     p1.x = 0.0;  
  91.     p1.y = 0.0;  
  92.     p2.x = 30.0;  
  93.     p2.y = 30.0;  
  94.   
  95.     q1.x = 0.0;  
  96.     q1.y = 20.0;  
  97.     q2.x = 20.0;  
  98.     q2.y = 0.0;  
  99.   
  100.     if (IsIntersectLine(p1, p2, q1, q2))  
  101.     {  
  102.         cout<<"线段相交!"<<endl;  
  103.     }  
  104.     else  
  105.     {  
  106.         cout<<"线段不相交!"<<endl;  
  107.     }  
  108. }  

 

发表于 @ 2009年07月09日 22:04:00 | 评论( 1 ) | 编辑| 举报| 收藏

旧一篇:向量几何在游戏编程中的使用6 | 新一篇:近期读书计划

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约