Random intersection

来源:互联网 发布:国外注册域名要备案吗 编辑:程序博客网 时间:2024/05/29 15:00

Description

There are N segments on the plane. You are to find out how many pairs of segments intersect with each other. A pair of segments intersect with each other if and only if they have at least one common point.

Input

the first line contains a single integer T -- the number of the testcases then T testcases are followed each testcase contains an integer N( N <= 100000), the number of segments then N lines are followed, each line contains 4 floating point numbers: x1 y1 x2 y2 which means the coordinates of the two ends of a segment for more details, see the sample input (the input data is generated randomly, and the probability of a pair of segments intersecting is about 0.001)

Output

for each testcase, print 1 line with the number of the pairs of segments intersect with each other.

Sample Input

330.0000 0.0000 1.0000 2.00000.0000 1.0000 1.0000 0.00000.0000 2.0000 1.0000 1.000040.0000 0.0000 0.0000 -1.00000.0000 0.0000 1.0000 0.00000.0000 0.0000 0.0000 1.00000.0000 0.0000 -1.0000 0.000020.0000 0.0000 1.0000 1.00000.0000 0.0000 2.0000 2.0000

Sample Output

261


题意很简单,就是给你线段判断几个交点 

两步确定两条线段是否相交:

  (1)快速排斥试验

    设以线段 P1P2 为对角线的矩形为R, 设以线段 Q1Q2 为对角线的矩形为T,如果R和T不相交,显然两线段不会相交。

  (2)跨立试验

    如果两线段相交,则两线段必然相互跨立对方。若P1P2跨立Q1Q2 ,则矢量 ( P1 - Q1 ) 和( P2 - Q1 )位于矢量( Q2 - Q1 ) 的两侧,即( P1 - Q1 ) × ( Q2 - Q1 ) * ( P2 - Q1 ) × ( Q2 - Q1 ) < 0。上式可改写成( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) > 0。当 ( P1 - Q1 ) × ( Q2 - Q1 ) = 0 时,说明 ( P1 - Q1 ) 和 ( Q2 - Q1 )共线,但是因为已经通过快速排斥试验,所以 P1 一定在线段 Q1Q2上;同理,( Q2 - Q1 ) ×(P2 - Q1 ) = 0 说明 P2 一定在线段 Q1Q2上。所以判断P1P2跨立Q1Q2的依据是:( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0。同理判断Q1Q2跨立P1P2的依据是:( Q1 - P1 ) × ( P2 - P1 ) * ( P2 - P1 ) × ( Q2 - P1 ) >= 0。具体情况如下图所示:

    

顺便介绍一个网站http://dev.gameres.com/Program/Abstract/Geometry.htm   关于几何的;

知道这些就是模板套一下了;

#include <iostream>#include<stdio.h>using namespace std;struct line{    double x1,x2,y1,y2;}st[100002];int jd(int i,int j){    int f1=0,f2=0;    double acd=(st[i].x1-st[j].x1)*(st[i].y1-st[i].y2)-(st[i].x1-st[i].x2)*(st[i].y1-st[j].y1);    double bcd=(st[i].x1-st[j].x2)*(st[i].y1-st[i].y2)-(st[i].x1-st[i].x2)*(st[i].y1-st[j].y2);    if(acd*bcd<=0)     f1=1;     double cab=(st[j].x1-st[i].x1)*(st[j].y1-st[j].y2)-(st[j].x1-st[j].x2)*(st[j].y1-st[i].y1);    double dab=(st[j].x1-st[i].x2)*(st[j].y1-st[j].y2)-(st[j].x1-st[j].x2)*(st[j].y1-st[i].y2);    if(cab*dab<=0)     f2=1;     if((f1+f2)==2)     return 1;     else     return 0;}int main(){    int n,t;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        int i,num=0,j;        for(i=0;i<n;i++)        scanf("%lf%lf%lf%lf",&st[i].x1,&st[i].y1,&st[i].x2,&st[i].y2);        for(i=0;i<n-1;i++)        for(j=i+1;j<n;j++)        {            if(jd(i,j))            num++;        }        printf("%d\n",num);    }    return 0;}



0 0
原创粉丝点击