【几何数学】【Python】【C++】判断两条线段是否相交,若相交则求出交点坐标

news/2024/11/2 13:26:48/

判断线段是否相交的办法(使用了向量叉积的方法):

首先,通过给定的线段端点坐标p1、p2、p3和p4构建了四个向量v1、v2、v3和v4:
v1表示从p1指向p2的向量,其分量为[p2[0] - p1[0], p2[1] - p1[1]]。
v2表示从p3指向p4的向量,其分量为[p4[0] - p3[0], p4[1] - p3[1]]。
v3表示从p1指向p3的向量,其分量为[p3[0] - p1[0], p3[1] - p1[1]]。
v4表示从p1指向p4的向量,其分量为[p4[0] - p1[0], p4[1] - p1[1]]。
接下来,计算了两个叉积cross1和cross2:
cross1表示v1和v3的叉积,计算公式为v1[0] * v3[1] - v1[1] * v3[0]。
cross2表示v1和v4的叉积,计算公式为v1[0] * v4[1] - v1[1] * v4[0]。
最后,根据两个叉积的乘积进行判断:
如果cross1和cross2的乘积小于等于0,意味着v1和v3位于不同的半平面或者其中一个线段的某个端点在另一个线段上,这时可以判断两条线段相交。
如果cross1和cross2的乘积大于0,意味着v1和v3位于同一侧或者两个线段没有交点,这时可以判断两条线段不相交。
根据以上逻辑,如果条件满足,则返回True表示线段相交,否则返回False表示线段不相交。

Python代码实现:

def are_lines_intersect(p1, p2, p3, p4):v1 = [p2[0] - p1[0], p2[1] - p1[1]]v2 = [p4[0] - p3[0], p4[1] - p3[1]]v3 = [p3[0] - p1[0], p3[1] - p1[1]]v4 = [p4[0] - p1[0], p4[1] - p1[1]]cross1 = v1[0] * v3[1] - v1[1] * v3[0]cross2 = v1[0] * v4[1] - v1[1] * v4[0]if cross1 * cross2 <= 0:return Trueelse:return Falsedef compute_intersection(p1, p2, p3, p4):if p1[0] == p2[0]:  # p1p2为垂直线x = p1[0]slope2 = (p4[1] - p3[1]) / (p4[0] - p3[0])intercept2 = p3[1] - slope2 * p3[0]y = slope2 * x + intercept2elif p3[0] == p4[0]:  # p3p4为垂直线x = p3[0]slope1 = (p2[1] - p1[1]) / (p2[0] - p1[0])intercept1 = p1[1] - slope1 * p1[0]y = slope1 * x + intercept1else:slope1 = (p2[1] - p1[1]) / (p2[0] - p1[0])slope2 = (p4[1] - p3[1]) / (p4[0] - p3[0])intercept1 = p1[1] - slope1 * p1[0]intercept2 = p3[1] - slope2 * p3[0]x = (intercept2 - intercept1) / (slope1 - slope2)y = slope1 * x + intercept1return [x, y]if __name__ == '__main__':p1 = [10, 20]p2 = [0, 100]p3 = [100, 50]p4 = [200, 30]# p1 p2 是一条线段# p3 p4 是另一条线段# 判断是否相交,相交且求交点if are_lines_intersect(p1, p2, p3, p4):print(compute_intersection(p1, p2, p3, p4))x, y = compute_intersection(p1, p2, p3, p4)else:print("No intersection")# 画图import matplotlib.pyplot as pltplt.plot([p1[0], p2[0]], [p1[1], p2[1]], color='r')plt.plot([p3[0], p4[0]], [p3[1], p4[1]], color='b')# 加注释plt.annotate('p1', xy=(p1[0], p1[1]), xytext=(p1[0] + 10, p1[1] + 10))plt.annotate('p2', xy=(p2[0], p2[1]), xytext=(p2[0] + 10, p2[1] + 10))plt.annotate('p3', xy=(p3[0], p3[1]), xytext=(p3[0] + 10, p3[1] + 10))plt.annotate('p4', xy=(p4[0], p4[1]), xytext=(p4[0] + 10, p4[1] + 10))try:# 绘制交点plt.scatter(x, y, color='g')# 给交点加注释plt.annotate('intersection', xy=(x, y), xytext=(x + 10, y + 10),arrowprops=dict(facecolor='g', shrink=0.05))except:pass# 坐标轴等距plt.axis('equal')plt.show()

绘制的图:
在这里插入图片描述
在这里插入图片描述
不相交:
在这里插入图片描述

C++ 借助opencv的数据结构

// are_lines_intersect: 判断两条线段是否相交
// 原理:判断两条线段的端点是否在另一条线段的两侧
bool are_lines_intersect(cv::Point2f p1, cv::Point2f p2, cv::Point2f p3, cv::Point2f p4) {cv::Point2f v1 = p2 - p1;cv::Point2f v2 = p4 - p3;cv::Point2f v3 = p3 - p1;cv::Point2f v4 = p4 - p1;float cross1 = v1.x * v3.y - v1.y * v3.x;float cross2 = v1.x * v4.y - v1.y * v4.x;if (cross1 * cross2 <= 0) {return true;} else {return false;}
}
// compute_intersection: 计算两条线段的交点
// 原理:计算两条线段的斜率和截距,然后解方程
cv::Point2f compute_intersection(cv::Point2f p1, cv::Point2f p2, cv::Point2f p3, cv::Point2f p4) {cv::Point2f intersection;if (p1.x == p2.x) {intersection.x = p1.x;float slope2 = (p4.y - p3.y) / (p4.x - p3.x);float intercept2 = p3.y - slope2 * p3.x;intersection.y = slope2 * intersection.x + intercept2;} else if (p3.x == p4.x) {intersection.x = p3.x;float slope1 = (p2.y - p1.y) / (p2.x - p1.x);float intercept1 = p1.y - slope1 * p1.x;intersection.y = slope1 * intersection.x + intercept1;} else {float slope1 = (p2.y - p1.y) / (p2.x - p1.x);float slope2 = (p4.y - p3.y) / (p4.x - p3.x);float intercept1 = p1.y - slope1 * p1.x;float intercept2 = p3.y - slope2 * p3.x;intersection.x = (intercept2 - intercept1) / (slope1 - slope2);intersection.y = slope1 * intersection.x + intercept1;}return intersection;
}

http://www.ppmy.cn/news/691151.html

相关文章

BUUCTF变异凯撒

根据题目可以得知&#xff0c;这道题使用的是凯撒密码 凯撒密码&#xff0c;是一种位移加密方式&#xff0c;只对26个字母进行位移替换加密&#xff0c;规则简单&#xff0c;容易破解。 但是根据题目下发的文件看来&#xff0c;出现了关于除字母以外的字符&#xff0c;结合题目…

掌握网络架构核心!了解为什么要分层

1 网络是七层、五层还是四层&#xff1f; 常听到三层交换机、七层规则等。网络为什么要分层呢&#xff1f;非分不可&#xff1f; 网络诞生前夜&#xff0c;IP协议、TCP协议都不存在&#xff0c;而你是网络缔造者&#xff0c;你会选择做怎样设计&#xff1f; 大体有两种 1.1…

春考计算机组装与维护,山东春考计算机组装与维修模拟试题.docx

山东春考计算机组装与维修模拟试题 班级 姓名 考号 信息技术类专业知识试题本试卷分卷一(选择题)和卷二(非选择题)两部分。满分200分&#xff0c;考试时间120分钟&#xff0c;考试结束后&#xff0c;请将答题卡交回。卷一(选择题&#xff0c;共100分)选择题(本大题50小题&#…

Dreamweaver安装99卡死_原装耗材99元了解一下?兄弟DCP-B7535DW低成本也能“印”对自如...

[PConline 导购]随着社会经济的发展&#xff0c;当前企业的工作节奏愈来愈紧凑&#xff0c;文件扫描、打印作为工作中重要的一环&#xff0c;必然成为企业办公的刚需。一台适合企业的打印机不仅考虑到成本、耗能、功能性&#xff0c;还要考虑它本身带来的便利性和持久性&#x…

mfc9140cdn硒鼓型号_兄弟MFC-9140CDN驱动

软件标签&#xff1a; 兄弟MFC-9140CDN一体机驱动是兄弟官方针对该型号一体机推出的驱动程序&#xff0c;安装驱动后&#xff0c;一体机就可以正常工作了&#xff0c;并且能够快速地解决一体机与电脑连接异常或者无法工作等问题&#xff0c;兄弟MFC-9140CDN是一款彩色激光多功能…

乙苯脱氢制苯乙烯实验装置

一、 装置功能 1.掌握乙苯脱氢实验的反应过程和反应机理、 特点&#xff0c; 了解 反应的反正和生成副产物的过程。 2.学习气固相管式催化反应器的构造、 原理和使用方法&#xff0c; 学习反应器正常操作和安装&#xff0c; 掌握催化剂评价的一般方法和 获得适宜工艺条件的研究…

柯尼卡美能达bizhub C458评测:可靠彩印利器

在现代办公生活中&#xff0c;彩色文印越来越收到企业办公人员的重视&#xff0c;一份彩色文件的表现力是普通的黑白文件所不能比拟的。尤其在一些商务和公关部门的业务流转中&#xff0c;彩色文印的重要性则更加凸显。 从市场宏观上来看&#xff0c;彩色复合机设备目前已经十分…

扶持初创企业成长 佳能再度携手优客工场升级轻松办公新体验

【行业报道】前不久&#xff0c;佳能宣布与国内知名共享办公空间优客工场再度携手&#xff0c;联合在优客工场推出佳能专属会议及佳能打印站&#xff0c;共同探索共享办公升级的新模式&#xff0c;共同关怀中小型初创企业助力其快速发展。此次再度携手&#xff0c;佳能将最新采…