您的位置:首页 > 编程语言 > C语言/C++

判断两线段是否相交-考研真题

2015-12-06 14:56 295 查看
之前在网上看到一篇利用向量内积来判断线段是否相交的例子,自己也曾尝试过去书写这样的算法,但是在书写过程中发现,由于该算法涉及的知识包括向量叉乘和点乘公式以及行列式计算等,导致算法的可读性不强,有些地方难于理解。故利用中学的几何知识重新书写判断线段相交的算法,新的算法运算快捷且简单易懂。下面便是详细介绍:

如题:书写算法判断线段p1p2与线段p3p4是否相交。



核心思想其实非常的简单:这里将判断两线段p1p2与线段p3p4相交分解为判断线段p1p2与直线p3p4是否相交和线段p3p4与直线p1p2是否相交。

如果是直线的话,就好办了。

1、先根据直线上的两点算出直线p1p2和直线p3p4的代数方程;

2、判断点p3和点p4是否分别在直线p1p2的两侧;

3、判断点p1和点p2是否分别在直线p3p4的两侧;

4、如果条件2和3均满足,则两线段相交,否则不想交,最后输出结果。

这里还需要指出的一点是判断点在直线的哪一侧,可以将该点的x坐标代入直线方程计算得到y1,如果点的y坐标大于y1则点在直线上方,否则点在直线的下方。

同理判断两点是否在直线的两侧时,只需判断两点是否一个在上侧,一个在下侧即可。

好了,下面就是完整的代码了。

// 判断两条线段是否相交.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

struct Point
{
double x,y;
Point(double x =0,double y=0):x(x),y(y){}
};

class StraightLine
{
public:
Point begin,end;
double k;//斜率
double b;//截距

public:
StraightLine(const Point begin,const Point end):begin(begin),end(end)
{
k = (begin.y-end.y)/(begin.x-end.x);
b = begin.y-k*begin.x;
}
public:
bool isUpper(Point p);//点在是否在直线上方,如果在直线上或上方均返回true,否则返回false
bool isCross(Point p1,Point p2);//点p1,p2组成的线段是否穿过直线
};

bool StraightLine::isUpper(Point p)
{
double y1 = k * p.x + b;
if(p.y>=y1)
return true;
else
return false;
}

bool StraightLine::isCross(Point p1,Point p2)
{
if(p1.x==p2.x&&p1.y==p2.y)return false;//若p1与p2坐标相同则返回false
if(isUpper(p1))
{
//如果p1在直线上方,p2在直线下方则满足条件返回True,否则返回false
if(!isUpper(p2))
return true;
else
return false;
}
else
{
//如果p1在直线下方,p2在直线上方则满足条件返回True,否则返回false
if(isUpper(p2))
return true;
else
return false;
}
return false;
}

void isCross(Point p1,Point p2,Point p3,Point p4)
{
StraightLine Line1(p1,p2);
StraightLine Line2(p3,p4);
//若点p3,p4分别在直线p1p2的两侧,且点p3,p4分别在直线p1p2的两侧,则线段p1p2与线段p3p4相交
if(Line1.isCross(p3,p4)&&Line2.isCross(p1,p2))
{
printf("Cross!\n");
}
else
{
printf("Don't Cross!\n");
}
}

int _tmain(int argc, _TCHAR* argv[])
{

Point p1(1,2),p2(5,3),p3(1,5),p4(5,1);
isCross(p1,p2,p3,p4);

Point a1(1,3),a2(5,2),a3(2,4),a4(4,9);
isCross(a1,a2,a3,a4);

getchar();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  考研 算法 C++