多邊形的核 模板

來源:互聯網
上載者:User

謝勇大神畫了張圖,然後這個問題就解決了。。。

本質是“半平面交”問題。

直線切割多邊形,公用的部分就是多邊形的核

這裡找到一個不錯的模板:
http://blog.csdn.net/accry/article/details/6070621

http://blog.csdn.net/candy20094369/article/details/6703940 

 

 

#include <iostream>#include <cstdio>#include <cmath>#include <vector>#include <cstring>#include <algorithm>#include <string>#include <set>#include <ctime>#define CL(arr, val)    memset(arr, val, sizeof(arr))#define REP(i, n)       for((i) = 0; (i) < (n); ++(i))#define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))#define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))#define L(x)    (x) << 1#define R(x)    (x) << 1 | 1#define MID(l, r)   (l + r) >> 1#define Min(x, y)   x < y ? x : y#define Max(x, y)   x < y ? y : x#define E(x)    (1 << (x))const double eps = 1e-8;typedef long long LL;using namespace std;const int maxn = 110;struct Point {    double x;    double y;    Point(double a = 0, double b = 0): x(a), y(b) {}    void input() {        scanf("%lf%lf", &x, &y);    }};Point point[maxn], p[maxn], q[maxn];    //讀入的多邊形的頂點(順時針)、p為存放最終切割得到的多邊形頂點的數組、暫存核的頂點  int cCnt, n;    //此時cCnt為最終切割得到的多邊形的頂點數、暫存頂點個數inline int dbcmp(double x) {    //精度問題    if(x > eps) return 1;    else if(x < -eps)   return -1;    return 0;}inline void getline(Point x, Point y, double& a, double& b, double& c) {    //點X,Y確定一條直線    a = y.y - x.y;    b = x.x - y.x;    c = y.x*x.y - x.x*y.y;}inline Point intersect(Point x, Point y, double a, double b, double c) {    ////求x、y形成的直線與已知直線a、b、c、的交點      double u = fabs(a*x.x + b*x.y + c);    double v = fabs(a*y.x + b*y.y + c);    return Point((x.x*v + y.x*u)/(u + v), (x.y*v + y.y*u)/(u + v));}inline void cut(double a, double b, double c) {        //如所示,切割    int cur = 0, i;    for(i = 1; i <= cCnt; ++i) {        if(dbcmp(a*p[i].x + b*p[i].y + c) >= 0)  q[++cur] = p[i];    // c由於精度問題,可能會偏小,所以有些點本應在右側而沒在        else {            if(dbcmp(a*p[i-1].x + b*p[i-1].y + c) > 0)    //如果p[i-1]在直線的右側的話,                  //則將p[i],p[i-1]形成的直線與已知直線的交點作為核的一個頂點(這樣的話,由於精度的問題,核的面積可能會有所減少)                  q[++cur] = intersect(p[i], p[i-1], a, b, c);            if(dbcmp(a*p[i+1].x + b*p[i+1].y + c) > 0)                q[++cur] = intersect(p[i], p[i+1], a, b, c);        }    }    for(i = 1; i <= cur; ++i)   p[i] = q[i];    p[cur+1] = q[1]; p[0] = p[cur];    cCnt = cur;}void solve() {    //注意:預設點是順時針,如果題目不是順時針,規整化方向     int i;    for(i = 1; i <= n; ++i) {        double a, b, c;        getline(point[i], point[i+1], a, b, c);        cut(a, b, c);    }    if(cCnt == 0)   puts("NO");    else    puts("YES");}void init() {    int i;    FOR(i, 1, n)    point[i].input();    point[n+1] = point[1];    //初始化p[], cCnt    FOR(i, 1, n)    p[i] = point[i];    p[n+1] = p[1]; p[0] = p[n];    cCnt = n;}int main() {    //freopen("data.in", "r", stdin);    int t;    scanf("%d", &t);    while(t--) {        scanf("%d", &n);        init();        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.