二维平面上线段与直线位置关系的判定

和点与线段的位置关系的判定类似,在讨论线段与直线的位置关系的时候,也是采用向量的叉积的方法来做的。具体方法是在直线上取两点AB,如下图所示,对于给定的线段CD和CE,不难发现当点C与点E同在直线L(即线段AB)的顺时针方向上(同在逆时针方向上也是成立的);点C与点D分别在L的不同方向上(一个位于顺时针一个位于逆时针方向上),此时直线与线段相交;对与线段点落在直线L上的情况在此不做说明,很简单,动手画画就知道了。

Problem:Segments (http://poj.org/problem?id=3304)

给定平面上n条线段,判断是否存在一条直线,使得这n条线段在L上的投影至少有一个公共点。

可能现在你觉得这个问题和线段与直线关系的判定没有什么联系。下面给出具体的分析:先考虑一个特殊的情况,即n=1的时候,如下图,线段AB在直线L上的投影为线段A'B',则过任意介于A'B'之间的点C'做直线L的垂线必交线段AB与一点C;反之,过线段AB之间任意一点C做直线L的垂线,垂足必定落在A'B'之间。

不难将此结论推广到n条线段的情况,假设存在一满足题意的直线L,则设点A为各个线段在L上投影的公共点,那么过A做一条直线L的垂线L',则L'必定与n条线段都相交;反之,过所有线段做一个直线L1使其与n条线段均相交,做直线L1的垂线L2,容易发现垂足即为所有n条线段投影的公共点。

这样一来就清晰了,问题转化成了判定是否存在一条直线L,L与n条线段均相交。我们只需枚举n条线段,判定是否均与直线L相交。但是,直线L该如何枚举呢?这里采用的方法也是计算几何中常用到得离散化思想。我们知道计算机只能处理离散的数据,我们没有办法来通过连续的旋转直线L来分别判定是否满足题意。但是我们可以采用离散化的思想:假设任意直线L分别于n条线段相交,我们可以采用将直线L分别向顺时针和逆时针的方向旋转,旋转的时候必须满足于n条线段均相交的限制,直到无法旋转为止。那么,最后直线会和n条线段中的某两条的端点重合。这样,我们就可以通过枚举任意两线段端点确定的直线,从而对问题进行求解。

下面说明一下该问题的两个细节:

<1>、n=1时要特判;

<2>、精度问题,当枚举两线段中的端点距离很接近(<1e-8)的时候,不能作为待选直线判定,原因见下图:

#include<iostream> #include<cstdio> #include<math.h> #define N 110 #define EPS 1e-10 using namespace std; typedef struct Node1 { double x,y; }Point; typedef struct Node2 { Point s,t; }Segment; Segment s[N]; int n; double cross(Point o,Point a,Point b)//求叉积 { return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y); } double dis(Point a,Point b) //求两点距离 { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int judge(Point a,Point b)//判定是否与n条线段均相交 { if(dis(a,b)<EPS) return 0;//细节2 for(int i=0;i<n;i++) if(cross(a,b,s[i].s)*cross(a,b,s[i].t)>EPS)// 精度控制 return 0; return 1; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lf%lf%lf%lf",&s[i].s.x,&s[i].s.y,&s[i].t.x,&s[i].t.y); int yes=0; if(n==1) yes=1;//特判 for(int i=0;yes==0&&i<n;i++)//枚举线段定点确定的待选直线 for(int j=i+1;yes==0&&j<n;j++) if(judge(s[i].s,s[j].s)||judge(s[i].s,s[j].t) ||judge(s[i].t,s[j].s)||judge(s[i].t,s[j].t)) yes=1; if(yes) printf("Yes!/n"); else printf("No!/n"); } return 0; }

二维平面上线段与直线位置关系的判定相关推荐

  1. 二维平面上点与线段关系的判定

    二维平面上点与线段关系的判定 问题的基本模型是:已知平面上一线段AB,判定平面上一点C相对于AB的位置(C不和AB共线). 通过向量叉积来判定线段与点的的位置关系. 例题:Toys (http://p ...

  2. 给定两个数组arrx和arry,长度都为N。代表二维平面上有N个点,第i个点的x 坐标和y坐标分别为arrx[i]和arry[i],返回求一条直线最多能穿过多少个点?

    问题描述: 给定两个数组arrx和arry,长度都为N.代表二维平面上有N个点,第i个点的x 坐标和y坐标分别为arrx[i]和arry[i],返回求一条直线最多能穿过多少个点? 思想 坐标系中两个点 ...

  3. 现在,我们用大炮来打蚊子:蚊子分布在一个M×N格的二维平面上,每只蚊子占据一格。向该平面的任意位置发射炮弹,炮弹的杀伤范围如下示意:

    目录 输入格式: 输出格式: 输入样例: 输出样例: 正确答案: 现在,我们用大炮来打蚊子:蚊子分布在一个M×N格的二维平面上,每只蚊子占据一格.向该平面的任意位置发射炮弹,炮弹的杀伤范围如下示意: ...

  4. 计算几何(二):线段与直线,点与线,线与线的关系

    写在前面 本文基于fxj巨佬的计算几何全家桶,并基于原文进行了自己的一些整理了经验补充,阅读本文前请前往支持巨佬fxj. 直线/线段的表示: 直线与线段的表示采用两点+方向向量的表示方法. 此外,一般 ...

  5. Java黑皮书课后题第10章:*10.15(几何:边框)边框是指包围一个二维平面上点集的最小矩形,编写一个方法,为二维平面上一系列点返回一个边框

    *10.15编写一个方法,为二维平面上一系列点返回一个边框 题目 程序 代码 Test15.java Test13_MyRectangle2D.java 运行结果 题目 点击这里跳转编程练习题10.1 ...

  6. 可视化 —— 二维平面上的散列点在坐标轴方向上的移动

    二维平面可以通过平面直角坐标系表示: 二维平面上不同的散列点,也就是平面直角坐标系上的不同的点, 其在坐标轴方向上的移动,分别在以下两个方向上的移动: 在 xx 轴方向上,(x1,y1)(x_1, y ...

  7. JavaScript:实现计算二维平面上两点之间的距离算法(附完整源码)

    JavaScript:实现计算二维平面上两点之间的距离算法 /*Calculate the mathematical properties involving coordinatesCalculate ...

  8. 点与直线位置关系,叉乘

    叉乘原理 它可以用来判断点在直线的某侧.进而可以解决点是否在三角形内,两个矩形是否重叠等问题.向量的叉积的模表示这两个向量围成的平行四边形的面积. 设矢量P = ( x1, y1 ),Q = ( x2 ...

  9. 在二维平面上,有一个机器人从原点 (0, 0) 开始。给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束。

    在二维平面上,有一个机器人从原点 (0, 0) 开始.给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束. 移动顺序由字符串表示.字符 move[i] 表示其第 i 次移动.机器 ...

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

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

最新文章

  1. jmeter获取时间_time 函数
  2. JavaScript容易犯错的九个陷阱
  3. bzoj2959 长跑
  4. 如何对接oracle 建立pdb
  5. 推荐系统中传统模型——LightGBM + FFM融合
  6. 计算机应用基础试题及答案数据库,数据库原理试题及答案.doc
  7. 长期趋势的测定方法-时距扩大法和移动平均法
  8. 使用nslookup查看邮箱信息
  9. 简要介绍无刷电机的基础知识
  10. 钉钉发起审批流程分析
  11. mysql 字段值分布很少的字段要不要加索引
  12. 解决BMap is not defined?
  13. 【CTF】记录一次CTF比赛的Writeup(附题目下载地址)
  14. 萝卜怎么吃最治病:白菜萝卜汤养胃暖身
  15. Unity引擎中的C#语言学习的笔记(1)
  16. vue3 vue-seamless-scroll
  17. Android高德地图自定义地图指南针
  18. 微信怎么制作小程序?制作微信小程序流程
  19. Segment Anything CV界的GPT—prompt-based里程碑式研究成果
  20. java date只保存年月日_java date 只保留年月日

热门文章

  1. Excel去除含有重复数据所在行
  2. 免费在线绘制CircRNA吸附miRNA圈图
  3. 安卓工具类集合—— 1 时间、时间戳转换工具
  4. 基于JavaEE的医院网上预约挂号系统
  5. CASIA-B步态数据集的一些粗糙理解
  6. 测试三极管的口诀[转]
  7. CENTOS6 安装和使用PHP全链路追踪 Molten
  8. 免费调用快递鸟物流跟踪轨迹订阅接口技术文档
  9. 注册微信公众平台测试账号
  10. go语言-channel使用(二十一)