判断两条线段是否相交

    题目:给定两条线段,判断这两条线段是否相交,线段AB的表示形式是A(x1,y1)B(x2,y2),线段CD的表示形式为C(x3,y3)D(x4,y4)。那么我们如何判断线段AB与线段CD是否相交。
    解析:在介绍如何解决线段相交问题之前,我们先介绍向量的叉积。如下图所示:

    下面的图(1)表示p1向量在p2向量的顺时针方向,图(2)表示p1向量在p2向量逆时针方向,图(3)表示p1向量与p2向量共线,我们只画出了同向共线的情况,反向共线的情况同理可得。

    有了上面的叉积运算,很容易判断两条线段是否相交,比如说我们要判断线段p1p2与线段p3p4是否相交。(1)计算p1p3向量与p1p2向量的叉积值。(2)计算p1p4向量与p1p2向量的叉积值。(3)判断这两个叉积值是否为异号。(4)计算p3p1向量与p3p4向量的叉积值。(5)计算p3p2向量与p3p4向量的叉积值。(6)判断这两个叉积值是否为异号。(7)如果这两对叉积值都为异号,则说明两条线段相交,否则则不想交。如下图所示:

    有一种特殊情况:比如说下图中的左图中线段p1p2与线段p3p4相交。向量p1p3与向量p1p2的叉积值为零。右图中线段p1p2与线段p3p4不相交。但是向量p1p3与向量p1p2的叉积值也为零。那么我们如何处理这种情况:我们只需要判断p3点在p1点与p2点之间即可,也就是说x1<=x3<=x2且y1<=y3<=y2。

#include<iostream>
#include<vector>
using namespace std;

struct Point
{
	int x;
	int y;
	Point(int myX, int myY) :x(myX), y(myY)
	{}
	Point(){}
};

bool isIntersect(vector<Point> &line1, vector<Point> &line2)
{
	int x1 = line1[0].x;
	int y1 = line1[0].y;
	int x2 = line1[1].x;
	int y2 = line1[1].y;
	int x3 = line2[0].x;
	int y3 = line2[0].y;
	int x4 = line2[1].x;
	int y4 = line2[1].y;
	int num1 = (x4 - x1)*(y2 - y1) - (y4 - y1)*(x2 - x1);
	int num2 = (x3 - x1)*(y2 - y1) - (y3 - y1)*(x2 - x1);
	int num3 = (x1 - x3)*(y4 - y3) - (y1 - y3)*(x4 - x3);
	int num4 = (x2 - x3)*(y4 - y3) - (y2 - y3)*(x4 - x3);
	if (num1*num2 < 0 && num3*num4 < 0)
	{
		return true;
	}
	if (num1 == 0)
	{
		if ((x4 > x1 && x4 > x2) || (x4 < x1 && x4 < x2))
		{
			return false;
		}
	}
	if (num2 == 0)
	{
		if ((x3 > x1 && x3 > x2) || (x3 < x1 && x3 < x2))
		{
			return false;
		}
	}
	if (num3 == 0)
	{
		if ((x2 > x3 && x2 > x4) || (x2 < x3 && x2 < x4))
		{
			return false;
		}
	}
	if (num4 == 0)
	{
		if ((x1 > x3 && x1 > x4) || (x1 < x3 && x1 < x4))
		{
			return false;
		}
	}
	return true;
}

int main(void)
{
	system("pause");
	return 0;
}
 
 

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值