POJ 1279 Art Gallery 半平面交求多邊形核

來源:互聯網
上載者:User

標籤:style   blog   color   os   io   for   ar   art   

第一道半平面交,只會寫N^2。

將每條邊化作一個不等式,ax+by+c>0,所以要固定順序,方便求解。

半平面交其實就是對一系列的不等式組進行求解可行解。

如果某點在直線右側,說明那個點在地區內,否則出現在左邊,就可能會有交點,將交點求出加入。

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler#include <stdio.h>#include <iostream>#include <cstring>#include <cmath>#include <stack>#include <queue>#include <vector>#include <algorithm>#define ll long long#define Max(a,b) (((a) > (b)) ? (a) : (b))#define Min(a,b) (((a) < (b)) ? (a) : (b))#define Abs(x) (((x) > 0) ? (x) : (-(x)))using namespace std;const int MAXN = 1555;const double eps = 1e-8;struct POINT{    double x;    double y;    POINT() : x(0), y(0) {};    POINT(double _x_, double _y_) : x(_x_), y(_y_) {};};struct LINE{    POINT a;    POINT b;    LINE() {};    LINE(POINT _a_, POINT _b_) : a(_a_), b(_b_) {};};POINT point[MAXN];//記錄最開始的多邊形POINT temp[MAXN]; //臨時儲存新切割的多邊形POINT ans[MAXN]; //儲存新切割出的多邊形LINE lline;int n,m;//n的原先的點數,m是新切割出的多邊形的點數void Coefficient(const LINE & L, double & A, double & B, double & C){    A = L.b.y - L.a.y;    B = L.a.x - L.b.x;    C = L.b.x * L.a.y - L.a.x * L.b.y;}double Cross(const POINT & a, const POINT & b, const POINT &o){    return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);}POINT Intersection(const LINE & A, const LINE & B){    double A1, B1, C1;    double A2, B2, C2;    Coefficient(A, A1, B1, C1);    Coefficient(B, A2, B2, C2);    POINT temp_point(0, 0);    temp_point.x = -(B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1);    temp_point.y =  (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1);    return temp_point;}//求面積,正為順時針,和叉積寫法有關double PointArea(POINT p[],int n){    double area = 0;    for(int i = 2; i < n; ++i)        area += Cross(p[1], p[i], p[i+1]);    return -area / 2.0;}void Cut(){  //用直線ax+by+c==0切割多邊形    int cut_m = 0, i;    double a, b, c;    Coefficient(lline, a, b, c);    for(i = 1; i <= m; ++i){        if(a * ans[i].x + b*ans[i].y + c >= 0)  //題目是順時鐘給出點的,所以一個點在直線右邊的話,那麼帶入值就會大於等於0            temp[++cut_m] = ans[i];         //說明這個點還在切割後的多邊形內,將其保留        else{            if(a * ans[i - 1].x + b * ans[i - 1].y + c > 0){   //該點不在多邊形內,但是它和它相鄰的點構成直線與                LINE line1(ans[i - 1], ans[i]); //ax+by+c==0所構成的交點可能在新切割出的多邊形內,                temp[++cut_m] = Intersection(lline, line1); //所以保留交點            }            if(a * ans[i + 1].x + b * ans[i + 1].y + c > 0){                LINE line1(ans[i + 1], ans[i]);                temp[++cut_m] = Intersection(lline, line1); //所以保留交點            }        }    }    for(i = 1; i <= cut_m; ++i) ans[i] = temp[i];    ans[cut_m + 1] = temp[1];    ans[0] = temp[cut_m];    m = cut_m;}void solve(){    int i;    point[0] = point[n];    point[n+1] = point[1];    for(i = 0; i <= n + 1; ++i){        ans[i] = point[i];    }    m = n;    for(i = 1;i <= n; ++i){        lline.a = point[i];        lline.b = point[i + 1]; //根據point[i]和point[i+1]確定直線ax+by+c==0        Cut();  //用直線ax+by+c==0切割多邊形    }    printf("%.2f\n",Abs(PointArea(ans,m)));}int main(){    int caseNum,i;    scanf("%d",&caseNum);    while(caseNum--){        scanf("%d",&n);        for(i = 1; i <= n; ++i){            scanf("%lf%lf",&point[i].x,&point[i].y);        }        solve();    }    return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.