两条线段的交点

    • 解题思路
    • 下面分别讨论三种情况
  • 四点组成四边形
  • 四点组成三角形
  • 四点共线
    • 代码

题目: 面试题 16.03. 交点

解题思路

思路:

  • 两条直线相交:叉乘,向量叉乘 符号为逆时针旋转共线为正,顺时针旋转为负。值为向量组成的三角形面积的2倍。
  • (X, Y)在线段上 (X1,Y1) (X2,Y2): X>=min(X1,X2)&&X<=max(X1,X2)&&Y>=min(Y1,Y2)&&Y<=min(X2,Y2)
  • 判断两条线段是否相交:

如果四个点组成一个四边形,则必然存在交点
如果四个点组成三角形,则一端端点必为交点
如果四个点共线,如果有交点,答案必然是两条线段中X较小的点,然后判断该点是否在另一条直线上即可,否则两条共线的线段不相交。

  • 定比分点:点(x,y)在线段内部时,求(x,y)的坐标

x=(x1+ax2)/(1+a);y=(y1+ay2)/(1+a);

下面分别讨论三种情况

用线段 L1 = (X1, Y1) (X2, Y2)表示第一条线段
L2 = (A1, B1) (A2, B2)表示第二条线段

四点组成四边形

线段L1的端点必然存在线段L2的两侧
线段L2的端点必然存在线段L1的两侧
且交点在必然存在线段的内部,根据定比分点公式计算即可
判断两个点是否处于线段两侧
根据叉乘的性质,如果在其线段两侧,叉乘符号必然相反,相乘符号为负;如在同侧,乘积必然大于0;如一端端点在线段上,其叉乘必然为0。
判断(X1,Y1)(X2,Y2)是否处于线段L2的两侧 为例

  • 构造向量L=(A2-A1,B2-B1),L1=(X1-A1,Y1-B1),L2=(X2-A1,X2-B1)
  • 判断(L x L1) * (L x L2)的符号即可
  • 此处需要注意同时需要判断另一条线段是否能把两个端点放在两侧,否则不能保证四点组成四边形。
// 判断(X1,Y1)(X2,Y2)是否处于线段L2的两侧
int crossA1X1 = cross(A2 - A1, B2 - B1, X1 - A1, Y1 - B1), crossA1X2 = cross(A2 - A1, B2 - B1, X2 - A1, Y2 - B1);

四点组成三角形

如一端端点在线段上,其叉乘必然为0,利用叉乘判断哪个点在线段上,即为答案

四点共线

  • 分别找出L1 L2线段中x较小的点(X,Y),(A,B)
  • 判断(X,Y)是否在线段L2上,判断(A,B)是否在L1上
  • 若存在一个点在另一条线段上即为答案,否则两条线段相离,无交点

代码

class Solution {public:vector<double> intersection(vector<int>& start1, vector<int>& end1, vector<int>& start2, vector<int>& end2) {vector<double> ans;int X1 = start1[0], X2 = end1[0], A1 = start2[0], A2 = end2[0];int Y1 = start1[1], Y2 = end1[1], B1 = start2[1], B2 = end2[1];int V1 = X2 - X1, P1 = Y2 - Y1;int L1 = A1 - X1, M1 = B1 - Y1;int L2 = A2 - X1, M2 = B2 - Y1;int crossX1A1 = cross(V1, P1, L1, M1), crossX1A2 = cross(V1, P1, L2, M2);//需要注意同时需要判断另一条线段是否能把两个端点放在两侧int crossA1X1 = cross(A2 - A1, B2 - B1, X1 - A1, Y1 - B1), crossA1X2 = cross(A2 - A1, B2 - B1, X2 - A1, Y2 - B1);int crossSign =  crossX1A1 * crossX1A2;int crossSign2 = crossA1X1 * crossA1X2;if (crossSign < 0 && crossSign2 < 0) {// 有交点 且端点不在线上double s1 = abs(crossX1A1), s2 = abs(crossX1A2);// 此时 ans1 ans2必不为0double x1 = (A1 + (s1/s2)*A2) / (1 + (s1/s2));double y1 = (B1 + (s1/s2)*B2) / (1 + (s1/s2));ans.push_back(x1);ans.push_back(y1);return ans;} else if (crossSign == 0 || crossSign2 == 0) {// 不共线一端端点在线上if (crossX1A1 == 0 && crossX1A2 != 0) {// (A1, B1)交点ans.push_back((double)A1);ans.push_back((double)B1);return ans;}if (crossX1A1 != 0 && crossX1A2 == 0) {// (A1, B1)交点ans.push_back((double)A2);ans.push_back((double)B2);return ans;}if (crossA1X1 == 0 && crossA1X2 != 0) {ans.push_back((double)X1);ans.push_back((double)Y1);return ans;}if (crossA1X1 != 0 && crossA1X2 == 0) {ans.push_back((double)X2);ans.push_back((double)Y2);return ans;}// 共线// 四个点(X1, Y1) (X2, Y2) (A1, B1) (A2, B2)int X = 0, Y = 0, A = 0, B = 0;getMiniCoor(X, Y, X1, Y1, X2, Y2);getMiniCoor(A, B, A1, B1, A2, B2);// 最小交点必在(X, Y) 或者 (A, B)int ANSX = 0, ANSY = 0;// 相交bool b1 = inside(X, Y, A1, B1, A2, B2), b2 = inside(A, B, X1, Y1, X2, Y2);if (b1 || b2) {if (b1 && b2) getMiniCoor(ANSX, ANSY, X, Y, A, B);else if (b1) {ANSX = X;ANSY = Y;} else {ANSX = A;ANSY = B;}ans.push_back((double)ANSX);ans.push_back((double)ANSY);return ans;}// 相离return ans;} else{// 不相交return ans;}}// (X1, Y1) x (X2, Y2)int cross(int X1, int Y1, int X2, int Y2) {return X1*Y2 - X2*Y1; // 叉乘为0则共线 (X1,Y1)逆时针旋转共线为正 顺时针旋转共线为负}// 判断点(ux, uy)是否在(X1, Y1) (X2, Y2) 线段上bool inside(int ux, int uy, int X1, int Y1, int X2, int Y2) {return ux >= min(X1, X2) && ux <= max(X1, X2) && uy >= min(Y1, Y2) && uy <= max(Y1, Y2);}void getMiniCoor(int &X, int &Y, int X1, int Y1, int X2, int Y2) {if (X1 == X2 && Y1 <= Y2 || X1 < X2) {X = X1;Y = Y1;} else {X = X2;Y = Y2;}return;}
};

两条线段的交点 交点相关推荐

  1. 两条线段求交点+叉积求面积 poj 1408

    题目链接:https://vjudge.net/problem/POJ-1408 题目是叫我们求出所有四边形里最大的那个的面积. 思路:因为这里只给了我们正方形四条边上的点,所以我们要先计算横竖线段两 ...

  2. 平面内两条线段的位置关系(相交)判定与交点求解

    http://www.cnblogs.com/devymex/archive/2010/08/19/1803885.html 概念 平面内两条线段位置关系的判定在很多领域都有着广泛的应用,比如游戏.C ...

  3. Java黑皮书课后题第9章:**9.12(几何:交点)假设两条线段相交。第一条线段的两个端点是(x1, y1)和(x2, y2),第二条线段的两个端点是(x3, y3)和(x4, y4)

    Java黑皮书课后题第9章:**9.12(几何:交点)假设两条线段相交.第一条线段的两个端点是(x1, y1)和(x2, y2),第二条线段的两个端点是(x3, y3)和(x4, y4) 题目 破题 ...

  4. 【数学计算】判断两条线段是否相交+计算两条线段的交点和夹角

    序言 还是那句话,学习是为了应用.书到用时方恨"用得少" 1. 计算两条直线的交点 直线一般式方程 A x + B y + C = 0 Ax+By+C = 0 Ax+By+C=0 ...

  5. 二维空间内,如何判断两条线段是否相交,相离,平行,重合,并求交点

    首先,假设有两条线段p,q,求这两条线段的空间关系. 我们把两条线段的四个顶点看为向量,用坐标表示:p1(p1x,p1y), p2(p2x,p2y), q1(q1x,q1y), q2(q2x, q2y ...

  6. 判断两条线段/直线相交,并求交点

      一.矢量基本知识     因为后面的计算需要一些矢量的基本知识,这里只是简单的列举如下,如果需要更加详细的信息,可以自行搜索wikipedia或google. 1.矢量的概念:如果一条线段的端点是 ...

  7. Unity3D C#数学系列之判断两条线段是否相交并求交点

    1 引言 问题:已知三维空间中四点A.B.C.D,如何判断线段AB与CD是否相交,若相交则求出交点. 分析: AB.CD要相交,则AB.CD必须要在同一平面内 快速排斥和跨立实验判断是否相交 几何法分 ...

  8. python求两条线段的交点

    本来想找一段求线段交点的代码,但是网上很多的代码都没有考虑除0的特殊情况,所以自己写了一份.具体原理: 一般方程法: 直线的一般方程为F(x) = ax + by + c = 0.既然我们已经知道直线 ...

  9. 用Python求两条线段的交点,包括延长线的交点

    用Python求两条线段的交点,包括延长线的交点 代码 结果如图 代码 import numpy as np import matplotlib.pyplot as pltdef line_inter ...

最新文章

  1. 掌握这 7 个编程设计原则,想做菜鸟都难
  2. 使用Sublime Text 3作为Python编辑器有关中文问题
  3. boostrap-table export 导出监听
  4. 循环冗余校验码CRC,求解步骤
  5. 计算机视觉与深度学习 | 复杂环境下的视觉同时定位与地图构建(SLAM)
  6. Polygonal-Light Shading with LTC
  7. L1-004.计算摄氏温度
  8. 第一天 学习前的准备
  9. linux ntfs 3g6,CentOS6挂载读写NTFS分区(ntfs-3g)
  10. Oracle11g新特性:在线操作功能增强-表增加包含默认值的字段(转载)
  11. 10)-MySQL数据库基础练习(答案版)
  12. 【T+】T+和天联高级版软件结合使用的时候,运行T+提示网页崩溃了。
  13. PE启动盘制作,电脑PE工具制作教程(可能是最详细的制作方法)小白推荐
  14. photoshop cc版下载
  15. springboot注解方式实现aop及常规方式
  16. 第二类曲面积分、场论、高斯公式和斯托克斯公式
  17. 掌握动效设计!让你的设计富有未来科技感(上)
  18. ICLR 2021 NAS 相关论文(包含Workshop)
  19. ppt密码忘记了怎样能打开文档,ppt权限密码如何解开?
  20. Intellij Idea创建maven项目,App.java代码编辑区没有run选项

热门文章

  1. 澳元兑美元预测:美元可能因美国经济衰退担忧而进一步下跌(MogaFX)
  2. C语言——二进制转为十进制
  3. python strip什么意思_python中strip什么意思
  4. python交易是什么意思_py交易是什么意思?
  5. jira -workflow之父级任务关注人copy到子任务
  6. 人脸活体检测、红外人脸数据集下载
  7. Unity-Graphic绘制菱形Rhombus
  8. 果汁机器人传销_独家调查|“洋果汁治百病”?然健环球涉嫌传销大起底
  9. 轻办公之Windows下的可道云
  10. 3D打印人体骨骼?这家哈佛大学孵化的公司要为中国医生开发自己的软件平台...