计算几何入门

艰难入门ing

感觉我这样的去写计算几何光调bug就得5小时 

参考资料(很多):

OI WIki

向量

另一个入门blog

检查线段相交

板子主要是抄的KS

POJ1127 Jack Straws

先用向量判交,然后传递闭包

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
typedef double db;

namespace Geo {
    const db eps = 1e-8;
    const db Pi = acos(-1);

    inline int sgn(db x) {
        if (x < -eps) return -1;
        else if (x > eps) return 1;
        else return 0;
    } 

    struct Vector {
        db x, y;

        Vector(db x = 0, db y = 0) : x(x), y(y) {}

        inline friend Vector operator + (Vector u, Vector v) {
            return Vector(u.x + v.x, u.y + v.y);
        } 

        inline friend Vector operator - (Vector u, Vector v) {
            return Vector(u.x - v.x, u.y - v.y);
        } 

        inline friend Vector operator * (Vector u, Vector v) {
            return Vector(u.x * v.x, u.y * v.y);
        } 

        inline friend Vector operator / (Vector u, Vector v) {
            return Vector(u.x / v.x, u.y / v.y);
        } 

        inline friend bool operator == (Vector u, Vector v) {
            return sgn(u.x - v.x) == 0 && sgn(u.y - v.y) == 0;
        } 

    };
    typedef Vector Point;
    typedef vector <Point> Polygon;

    inline db dot(Vector u, Vector v) {
        return u.x * v.x + u.y * v.y;
    }

    inline db crs(Vector u, Vector v) {
        return u.x * v.y - u.y * v.x;
    }

    inline db length(Vector u) {
        return max(0.0, sqrt(dot(u, u)));
    }

    inline db angle(Vector u, Vector v) {
        return acos(dot(u, v) / length(u) / length(v));
    }

    inline Vector rotate(Vector u, db rad) {
        return Vector(u.x * cos(rad) - u.y * sin(rad), u.x * sin(rad) + u.y * cos(rad));
    }

    struct Line {
        Point p;
        Vector v;
        Line(Point p = Point(), Vector v = Vector()) : p(p), v(v) {} 
    };

    struct Ray : public Line {
        Ray(Point p = Point(), Vector v = Vector()) : Line(p, v) {}
    };

    struct Segment {
        Point a, b;
        Segment(Point a = Point(0, 0), Point b = Point(0, 0)) : a(a), b(b) {}
    };

    inline bool isCrs(Segment u, Segment v) {
        Point p1 = u.a, p2 = u.b, q1 = v.a, q2 = v.b;
        if (min(p1.x, p2.x) <= max(q1.x, q2.x) && min(q1.x, q2.x) <= max(p1.x, p2.x) 
            && min(p1.y, p2.y) <= max(q1.y, q2.y) && min(q1.y, q2.y) <= max(p1.y, p2.y)) {
                //puts("in");
                if (sgn(crs(q1 - p1, p2 - p1) * crs(q2 - p1, p2 - p1)) > 0) return 0;
                //puts("1");
                if (sgn(crs(p1 - q1, q2 - q1) * crs(p2 - q1, q2 - q1)) > 0) return 0;
                //puts("2");
                return 1;
        } else return 0;
    }

} using namespace Geo;

const int N = 20;

int n;
Segment s[N];
bool f[N][N];

int main() {
    #ifndef ONLINE_JUDGE
        freopen("sample.in", "r", stdin);
    #endif

    for (; scanf("%d", &n); getchar()) {
        if (n == 0) break;
        for (int i = 1; i <= n; i++) {
            int x1, y1, x2, y2;
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
//          printf("%f %f %f %f\n", Point(x1, y1).x, Point(x1, y1).y, Point(x2, y2).x, Point(x2, y2).y);
            s[i] = Segment(Point(x1, y1), Point(x2, y2));
        }

        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                if (isCrs(s[i], s[j])) f[i][j] = 1;
                else f[i][j] = 0;
        
        for (int k = 1; k <= n; k++)
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= n; j++)
                    f[i][j] |= f[i][k] & f[k][j];

/*        for (int i = 1; i <= n; i++)
            printf("%f %f %f %f\n", s[i].a.x, s[i].a.y, s[i].b.x, s[i].b.y);      */

        for (int u, v; ; ) {
            scanf("%d%d", &u, &v);
            if (u == 0 && v == 0) break;
            if (f[u][v]) puts("CONNECTED");
            else puts("NOT CONNECTED");
        }
    }
    return 0;
}
View Code

 

占坑

posted @ 2020-10-08 16:12  CzxingcHen  阅读(122)  评论(0编辑  收藏  举报