[51nod1264]线段相交

给定两个点:

typedef  struct {

double  x, y;

} Point;

Point A1,A2,B1,B2;

首先引入两个实验:

a.快速排斥实验

设以线段A1A2和线段B1B2为对角线的矩形为M,N;

若M,N 不相交,则两个线段显然不相交;

所以:满足第一个条件时:两个线段可能相交。

b.跨立实验

如果两线段相交,则两线段必然相互跨立对方.若A1A2跨立B1B2,则矢量( A1 - B1 ) 和(A2-B1)位于矢量(B2-B1)的两侧,

即(A1-B1) × (B2-B1) * (A2-B1) × (B2-B1)<0。

上式可改写成(A1-B1) × (B2-B1) * (B2-B1) × (A2-A1)>0。

应该判断两次,即两条线段都要为直线,判断另一直线的两端点是否在它两边,若是则两线段相交。

若积极满跨立实验是不行的,如下面的情况:

即两条线段在同一条直线上。所以我们要同时满足两次跨立和快速排斥实验。

总体分析:

当(A1-B1) × (B2-B1)=0时,说明(A1-B1)和(B2-B1)共线,但是因为已经通过快速排斥试验,所以 A1一定在线段 B1B2上;同理,(B2-B1)×(A2-B1)=0 说明A2一定在线段B1B2上。所以判断A1A2跨立B1B2的依据是:(A1-B1) × (B2-B1) * (B2-B1) × (A2-B1) >= 0。

同理判断B1B2跨立A1A2的依据是:(B1-A1) × (A2-A1) * (A2-A1) × (B2-A1) >= 0。

如图:

应用:

1.       判断两个线段相交

2.       判断线段与直线相交

3.       判断点在矩形内

模板题

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 struct line{
 5     double x1,y1,x2,y2;
 6 }p,q;
 7 double cross1(line &a,line &b){
 8     return (a.x1-b.x1)*(b.y2-b.y1)-(a.y1-b.y1)*(b.x2-b.x1);
 9 }
10 double cross2(line &a,line &b){
11     return (a.x2-b.x1)*(b.y2-b.y1)-(a.y2-b.y1)*(b.x2-b.x1);
12 }
13 bool judge(line &a,line &b){
14     if(max(a.x1,a.x2)>=min(b.x1,b.x2)&&
15         max(a.y1,a.y2)>=min(a.y1,a.y2)&&
16         max(b.x1,b.x2)>=min(a.x1,a.x2)&&
17         max(b.y1,b.y2)>=min(a.y1,a.y2)&&
18         cross1(a,b)*cross2(a,b)<=0&&
19         cross1(b,a)*cross2(b,a)<=0)
20     return true;
21     return false;
22 }
23 int main(){
24     int t;
25     cin>>t;
26     while(t--){
27         cin>>p.x1>>p.y1>>p.x2>>p.y2>>q.x1>>q.y1>>q.x2>>q.y2;
28         if(judge(p,q)) cout<<"Yes\n";
29         else cout<<"No\n";
30     }
31 }
时间: 2024-11-23 07:10:10

[51nod1264]线段相交的相关文章

(计算几何 线段判交) 51nod1264 线段相交

1264 线段相交 给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交). 如果相交,输出"Yes",否则输出"No". 输入 第1行:一个数T,表示输入的测试数量(1 <= T <= 1000) 第2 - T + 1行:每行8个数,x1,y1,x2,y2,x3,y3,x4,y4.(-10^8 <= xi, yi <= 10^8) (直线1的两个端点为x1,y1 | x2, y2,直线2的两个端点为x3,y

HDOJ1086-You can Solve a Geometry Problem too(线段相交)

Problem Description Many geometry(几何)problems were designed in the ACM/ICPC. And now, I also prepare a geometry problem for this final exam. According to the experience of many ACMers, geometry problems are always much trouble, but this problem is ve

POJ 2653 Pick-up sticks [线段相交 迷之暴力]

Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12861   Accepted: 4847 Description Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to fin

poj 3304 直线与线段相交

Segments Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12161   Accepted: 3847 Description Given n segments in the two dimensional space, write a program, which determines if there exists a line such that after projecting these segments

poj 2653 线段与线段相交

Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 11884   Accepted: 4499 Description Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to fin

poj2826(线段相交)

传送门:An Easy Problem?! 题意:用两条线段接雨水,雨水是垂直落下的,问我们用给定的两条线段能接到多少水. 分析:看起来很简单,写起来略麻烦,先排除不能接到水的情况: 1. 两条线段不相交: 2. 其中任意一条线段水平: 3. 两条线段重合: 4. 相交的情况下,最高的端点遮住了次高的端点 最后求线段交点确定三角形并用叉积求面积. #include <iostream> #include <stdio.h> #include <string.h> #in

hdu 1086(判断线段相交)

传送门:You can Solve a Geometry Problem too 题意:给n条线段,判断相交的点数. 分析:判断线段相交模板题,快速排斥实验原理就是每条线段代表的向量和该线段的一个端点与 另一条线段的两个端点构成的两个向量求叉积,如果线段相交那么另一条线段两个端点必定在该线段的两边,则该线段代表的向量必定会顺时针转一遍逆时针转一遍,叉积必定会小于等于0,同样对另一条线段这样判断一次即可. #include <algorithm> #include <cstdio>

hdu1086(线段相交)

题目意思: 给出n个线段,判断这n条线段中,线段相交的对数. http://acm.hdu.edu.cn/showproblem.php?pid=1086 题目分析: 此题主要写出判断线段相交的函数,然后判断每一对线段即可,时间复杂度O(n*n).详细解释见代码. AC代码: /** *判断AB和CD两线段是否有交点: *同时满足两个条件:('x'表示叉积) * 1.C点D点分别在AB的两侧.(向量(ABxAC)*(ABxAD)<=0) * 2.A点和B点分别在CD两侧.(向量(CDxCA)*(

HDU 1086 You can Solve a Geometry Problem too(判断线段相交)

题目地址:HDU 1086 就这么一道仅仅判断线段相交的题目写了2k多B的代码..是不是有点浪费...但是我觉得似乎哪里也优化不了了.... 判断线段相交就是利用的叉积.假如现在两条线段分别是L1和L2,先求L1和L2两个端点与L1的某个端点的向量的叉积,如果这两个的叉积的乘积小于0的话,说明L1在是在L2两个端点之间的,但此时并不保证一定相交.此时需要用同样的方法去判断L2是否在L1的两个端点之间,如果L2也在L1的两个端点之间的话,那就足以说明L1与L2相交.但是这题还需要判断是否端点也相交