原文地址
https://segmentfault.com/a/1190000004070478
向量:u=(u1,u2,u3) v=(v1,v2,v3)
叉积公式:u x v = { u2v3-v2u3 , u3v1-v3u1 , u1v2-u2v1 }
点积公式:u * v = u1v1+u2v2+u3v3
快速排斥
min(p1.x,p2.x) <= max(q1.x,q2.x) &&
min(q1.x,q2.x) <= max(p1.x,p2.x) &&
min(p1.y,p2.y) <= max(q1.y,q2.y) &&
min(q1.y,q2.y) <= max(p1.y,p2.y);
//跨立判断
bool isLineSegmentCross(const Point &P1,const Point &P2,const Point &Q1,const Point &Q2)
{
if(
((Q1.x-P1.x)*(Q1.y-Q2.y)-(Q1.y-P1.y)*( Q1.x-Q2.x)) * ((Q1.x-P2.x)*(Q1.y-Q2.y)-(Q1.y-P2.y)*(Q1.x-Q2.x)) < 0 &&
((P1.x-Q1.x)*(P1.y-P2.y)-(P1.y-Q1.y)*(P1.x-P2.x)) * ((P1.x-Q2.x)*(P1.y-P2.y)-(P1.y-Q2.y)*( P1.x-P2.x)) < 0
)
return true;
else
return false;
}
#include
#define N 10002
/**
算法适用于整形点,不适用于浮点型
**/
typedef struct Point
{
int x;
int y;
}Point;
double min(int x, int y)
{
return x<y?x:y;
}
double max(int x, int y)
{
return x>y?x:y;
}
//排斥实验
bool IsRectCross(const Point &p1,const Point &p2,const Point &q1,const Point &q2)
{
bool ret = min(p1.x,p2.x) <= max(q1.x,q2.x) &&
min(q1.x,q2.x) <= max(p1.x,p2.x) &&
min(p1.y,p2.y) <= max(q1.y,q2.y) &&
min(q1.y,q2.y) <= max(p1.y,p2.y);
return ret;
}
//跨立判断
bool IsLineSegmentCross(const Point &P1,const Point &P2,const Point &Q1,const Point &Q2)
{
if(
((Q1.x-P1.x)*(Q1.y-Q2.y)-(Q1.y-P1.y)*( Q1.x-Q2.x)) * ((Q1.x-P2.x)*(Q1.y-Q2.y)-(Q1.y-P2.y)*(Q1.x-Q2.x)) < 0 ||
((P1.x-Q1.x)*(P1.y-P2.y)-(P1.y-Q1.y)*(P1.x-P2.x)) * ((P1.x-Q2.x)*(P1.y-P2.y)-(P1.y-Q2.y)*( P1.x-P2.x)) < 0
)
return true;
else
return false;
}
/**
求线段P1P2与Q1Q2的交点。
先进行快速排斥实验和跨立实验确定有交点再进行计算。
交点(x,y)使用引用返回。
没有验证过
**/
bool GetCrossPoint(const Point &p1,const Point &p2,const Point &q1,const Point &q2,long &x,long &y)
{
if(IsRectCross(p1,p2,q1,q2))
{
if (IsLineSegmentCross(p1,p2,q1,q2))
{
//求交点
long tmpLeft,tmpRight;
tmpLeft = (q2.x - q1.x) * (p1.y - p2.y) - (p2.x - p1.x) * (q1.y - q2.y);
tmpRight = (p1.y - q1.y) * (p2.x - p1.x) * (q2.x - q1.x) + q1.x * (q2.y - q1.y) * (p2.x - p1.x) - p1.x * (p2.y - p1.y) * (q2.x - q1.x);
x = (int)((double)tmpRight/(double)tmpLeft);
tmpLeft = (p1.x - p2.x) * (q2.y - q1.y) - (p2.y - p1.y) * (q1.x - q2.x);
tmpRight = p2.y * (p1.x - p2.x) * (q2.y - q1.y) + (q2.x- p2.x) * (q2.y - q1.y) * (p1.y - p2.y) - q2.y * (q1.x - q2.x) * (p2.y - p1.y);
y = (int)((double)tmpRight/(double)tmpLeft);
return true;
}
}
return false;
}