hdu 1086(判断线段相交)

View Code
/*
*  题目要求:求一组线段的总的交点数
*  判断两线段相交:1快速排斥,2跨立实验  
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

const int N = 100;

struct point {//点结构 
    double x;
    double y;
};

struct segment {//线段结构 
    point s;
    point e;
}seg[N];

double crossProd(point A, point B, point C) {
    return (B.x-A.x)*(C.y-A.y) - (B.y-A.y)*(C.x-A.x);
}

int segIntersect(segment seg1, segment seg2) {//判断线段是否相交 
    if (max(seg1.s.x, seg1.e.x) >= min(seg2.s.x, seg2.e.x) &&//快速排斥实验 
        max(seg2.s.x, seg2.e.x) >= min(seg1.s.x, seg1.e.x) &&
        max(seg1.s.y, seg1.e.y) >= min(seg2.s.y, seg2.e.y) &&
        max(seg2.s.y, seg2.e.y) >= min(seg1.s.y, seg1.e.y) &&
        crossProd(seg2.s, seg2.e, seg1.s) * crossProd(seg2.s, seg1.e, seg2.e) >= 0 &&//跨立实验 
        crossProd(seg1.s, seg1.e, seg2.s) * crossProd(seg1.s, seg2.e, seg1.e) >= 0)
        return 1;//相交 
    return 0;
}

int solve(int n) {
    int c = 0;
    for (int i=0; i<n; ++i) {
        for (int j=i+1; j<n; ++j) c += segIntersect(seg[i], seg[j]);
    }
    return c;
}

int main() {
    int n;
    while (scanf("%d", &n), n) {
        for (int i=0; i<n; ++i) scanf ("%lf%lf%lf%lf", &seg[i].s.x, &seg[i].s.y, &seg[i].e.x, &seg[i].e.y);
        int c = solve(n);
        printf ("%d\n", c);
    }
    return 0;
}

 

posted on 2012-04-22 08:36  Try86  阅读(192)  评论(0)    收藏  举报