【C++】判断两条“线段”是否相交

23 篇文章 4 订阅

作者:非妃是公主
专栏:《笔记》《C++》
个性签:顺境不惰,逆境不馁,以心制境,万事可成。——曾国藩

在这里插入图片描述

判断两条直线是否相交,通过快速排斥实验和跨立实验进行判断。
快速排斥实验,主要原理:

如果l1.x的最小值比l2.x的最大值还要大,肯定没有交点
如果l1.y的最小值比l2.y的最大值还要大,肯定没有交点
反之如下:交换l1和l2的位置
如果l2.x的最小值比l1.x的最大值还要大,肯定没有交点
如果l2.y的最小值比l1.y的最大值还要大,肯定没有交点
在这里插入图片描述
在这里插入图片描述

跨立实验原理,主要原理:

进行叉积运算,向量AC×向量AB,向量AD×向量AB,如果两个向量(AC,AD)都排在两边,那么两个结果则分别指向纸内和纸外,这样,将上面叉积的结果进行点积运算,就可以得到一个负值。
当最终点积等于0的时候,说明两条重合,这时也符合条件(由于通过了第一步的快速排斥实验)
交换两条直线,同理。
综上,最终点积大于0的情况为两条直线不相交的情况
在这里插入图片描述

// An highlighted block
#include<iostream>
using namespace std;

struct Line {
	double x1;
	double y1;
	double x2;
	double y2;
};

// 快速排斥实验  Rapid rejection experiments
bool RapidRejExper(Line& l1, Line& l2) {
	if ((l1.x1 > l1.x2 ? l1.x1 : l1.x2) < (l2.x1 < l2.x2 ? l2.x1 : l2.x2) ||
		(l1.y1 > l1.y2 ? l1.y1 : l1.y2) < (l2.y1 < l2.y2 ? l2.y1 : l2.y2) ||
		(l2.x1 > l2.x2 ? l2.x1 : l2.x2) < (l1.x1 < l1.x2 ? l1.x1 : l1.x2) ||
		(l2.y1 > l2.y2 ? l2.y1 : l2.y2) < (l1.y1 < l1.y2 ? l1.y1 : l1.y2)) {
		return false;
	}
	return true;
}

// 跨立实验
bool Cross(Line& l1, Line& l2) {
	if ((((l1.x1 - l2.x1) * (l2.y2 - l2.y1) - (l1.y1 - l2.y1) * (l2.x2 - l2.x1)) *
		((l1.x2 - l2.x1) * (l2.y2 - l2.y1) - (l1.y2 - l2.y1) * (l2.x2 - l2.x1))) > 0 ||
		(((l2.x1 - l1.x1) * (l1.y2 - l1.y1) - (l2.y1 - l1.y1) * (l1.x2 - l1.x1)) *
			((l2.x2 - l1.x1) * (l1.y2 - l1.y1) - (l2.y2 - l1.y1) * (l1.x2 - l1.x1))) > 0)
	{
		return false;
	}
	return true;
}


int main() {
	Line l1, l2;
	cin >> l1.x1 >> l1.y1 >> l1.x2 >> l1.y2;
	cin >> l2.x1 >> l2.y1 >> l2.x2 >> l2.y2;
	if (RapidRejExper(l1, l2) && Cross(l1, l2)) {
		cout << "Yes";
	}
	else {
		cout << "No";
	}
}

针对评论区老哥"时光3"问题的解答

这个了解了,不过还是得到的结果和你列的不一样,能把你一步一步叉乘乘以叉乘展开得到这个结果的过程列一下吗?
另外,感觉判断两个点在一个边的两边,把四个点的坐标都用到了,算一次就可以了,再算这个边是不是在另一个边的两边是重复计算呀。

在这里插入图片描述
主要解答为什么要对称计算两条直线的问题。推理过程很简单,大概就是我上面列的式子的坐标形式了。

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cherries Man

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值