线段交点算法

原文地址
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;
}

你可能感兴趣的:(算法)