You can Solve a Geometry Problem too HDU - 1086

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 very easy, after all we are now attending an exam, not a contest :) 
Give you N (1<=N<=100) segments(线段), please output the number of all intersections(交点). You should count repeatedly if M (M>2) segments intersect at the same point. 

Note: 
You can assume that two segments would not intersect at more than one point. 

Input

Input contains multiple test cases. Each test case contains a integer N (1=N<=100) in a line first, and then N lines follow. Each line describes one segment with four float values x1, y1, x2, y2 which are coordinates of the segment’s ending. 
A test case starting with 0 terminates the input and this test case is not to be processed. 

Output

For each case, print the number of intersections, and one line one case. 

Sample Input

2
0.00 0.00 1.00 1.00
0.00 1.00 1.00 0.00
3
0.00 0.00 1.00 1.00
0.00 1.00 1.00 0.000
0.00 0.00 1.00 0.00
0

Sample Output

1
3

 如何判断两条线段是否香蕉???

首先,你得知道:

炒鸡完备的解释!!!https://www.cnblogs.com/tuyang1129/p/9390376.html

以下均为叉乘----------->

(向量)a x(向量)b<0------>a顺时针旋转得到b

(向量)a x(向量)b=0------>a和b平行!!!

(向量)a x(向量)b>0------>a逆时针旋转得到b

其次,可以这样想:

http://blog.sina.com.cn/s/blog_b2ad877f0102witj.html

                           ææ ·å¤æ­çº¿æ®µç¸äº¤

 首先,需要判断两条直线所在的矩形框是不是有重合部分,如果没有重合部分,那就不要费劲了。如上面左图的情况。只要检验出两个矩形区域不重合,就能直接判断出两线段没有交点。而矩形框有重合部分,只是有交点的必要条件,不是充分条件,也就是说,两线段可能有交点,也可能没有交点,比如上面中图和右图。我们的主要工作,也就是区分这两种情况。

对于中图,我们发现,P1和P2两点(蓝点)在直线Q1Q2的两侧,而Q1和Q2(红点)两点在直线P1P2的同一侧。而对右图,和P2两点在直线Q1Q2的两侧,而Q1和Q2两点也在直线P1P2的两侧。

综上所述,两线段香蕉的充要条件为:任意一条线段的两点都在另一条线段两点的两侧!!!!!(对于向量的意义就是其中一个连线向量相对于另一条方向相反,两向量交换位置叉乘结果异号!!!!)

#include<iostream>
using namespace std;
struct point
{
    double x,y;
}p[101];
double mult_cross(point a, point b, point c)
{
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
bool ifcross(point a,point b,point c,point d)
{
    if(mult_cross(c, b, a)*mult_cross(b, d, a)<0)return false;
    if(mult_cross(a, d, c)*mult_cross(d, b, c)<0)return false;
    if(max(a.x,b.x)<min(c.x,d.x))return false;
    if(max(a.y,b.y)<min(c.y,d.y))return false;
    if(max(c.x,d.x)<min(a.x,b.x))return false;
    if(max(c.y,d.y)<min(a.y,b.y))return false;
    return true;
}
int main()
{
    int n;
    while(cin>>n&&n)
    {
        int sd=1;
        for(int i=1; i<=n; i++)
        {
            cin>>p[sd].x>>p[sd].y>>p[sd+1].x>>p[sd+1].y;
            sd+=2;
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                if(ifcross(p[2*i-1],p[2*i],p[2*j-1],p[2*j]))
                ans++;
            }
        }
       cout <<ans<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43813697/article/details/90519863