• 半平面交 求多边形内核问题


     多边形的内核可以理解为:

    在多边形找到一块区域,使这块区域中的任何一个点都能够和多边形上的任意一点相连而不受到多边形上其他边的阻挡

    也可以抽象的理解为在这块区域中任意位置放一个旋转摄像头,这个摄像头可以监控多边形的整个区域

    多边形内核是否存在可以利用半平面交的思想去求解

    将多边形上的每一条边作为逆时针顺序的射线,在每一条线左侧的就是可行区域

    譬如:

    比如这个多边形

    蓝色区域便是内核

    这样利用半平面交的nlogn的算法就可以轻松判断

    这里是三道这样类型的题目:poj 3335 , poj 1474 , poj 1279

    poj 3335

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    #define N 105
    #define ll long long
    #define eps 1e-9
    
    int dcmp(double x)
    {
        if(fabs(x)<eps) return 0;
        else return x<0?-1:1;
    }
    
    struct Point{
        double x,y;
        Point(double x=0 , double y=0):x(x),y(y){}
    }p[N] , poly[N];
    
    typedef Point Vector;
    
    struct Line{
        Point p;
        Vector v;
        double ang;
        Line(){}
        Line(Point p , Vector v):p(p),v(v){ang = atan2(v.y , v.x);}
        bool operator<(const Line &m) const{
            return dcmp(ang-m.ang)<0;
        }
    }line[N];
    
    Vector operator+(Vector a , Vector b){return Vector(a.x+b.x , a.y+b.y);}
    Vector operator-(Vector a , Vector b){return Vector(a.x-b.x , a.y-b.y);}
    Vector operator*(Vector a , double b){return Vector(a.x*b , a.y*b);}
    Vector operator/(Vector a , double b){return Vector(a.x/b , a.y/b);}
    
    double Cross(Vector a , Vector b){return a.x*b.y-a.y*b.x;}
    
    bool OnLeft(Line L , Point P)
    {
        return dcmp(Cross(L.v , P-L.p))>=0;
    }
    
    Point GetIntersection(Line a , Line b)
    {
        Vector u = a.p-b.p;
        double t = Cross(b.v , u)/Cross(a.v , b.v);
        return a.p+a.v*t;
    }
    
    int HalfplaneIntersection(Line *L , int n , Point *poly)
    {
        sort(L , L+n);
        int first , last;
        Point *p = new Point[n];
        Line *q = new Line[n];
        q[first=last=0] = L[0];
        for(int i=1 ; i<n ; i++){
            while(first<last && !OnLeft(L[i] , p[last-1])) last--;
            while(first<last && !OnLeft(L[i] , p[first])) first++;
            q[++last] = L[i];
            if(fabs(Cross(q[last].v , q[last-1].v))<eps){
                last--;
                if(OnLeft(q[last] , L[i].p)) q[last]=L[i];
            }
            if(first < last) p[last-1] = GetIntersection(q[last-1] , q[last]);
        }
        while(first<last && !OnLeft(q[first] , p[last-1])) last--;
        if(last-first<=1) return 0;
        p[last] = GetIntersection(q[last] , q[first]);
        int m=0;
        for(int i=first ; i<=last ; i++) poly[m++] = p[i];
        return m;
    }
    
    int main()
    {
       // freopen("in.txt" , "r" , stdin);
        int T , n;
        scanf("%d" , &T);
        while(T--)
        {
            scanf("%d" , &n);
            for(int i=0 ; i<n ; i++) scanf("%lf%lf" , &p[i].x , &p[i].y);
            p[n] = p[0];
            for(int i=0 ; i<n ; i++) line[i] = Line(p[i] , p[i]-p[i+1]);
            if(HalfplaneIntersection(line , n , poly)) puts("YES");
            else puts("NO");
        }
    }
    View Code

    poj 1474

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 
     7 using namespace std;
     8 #define N 105
     9 #define ll long long
    10 #define eps 1e-9
    11 
    12 int dcmp(double x)
    13 {
    14     if(fabs(x)<eps) return 0;
    15     else return x<0?-1:1;
    16 }
    17 
    18 struct Point{
    19     double x,y;
    20     Point(double x=0 , double y=0):x(x),y(y){}
    21 }p[N] , poly[N];
    22 
    23 typedef Point Vector;
    24 
    25 struct Line{
    26     Point p;
    27     Vector v;
    28     double ang;
    29     Line(){}
    30     Line(Point p , Vector v):p(p),v(v){ang = atan2(v.y , v.x);}
    31     bool operator<(const Line &m) const{
    32         return dcmp(ang-m.ang)<0;
    33     }
    34 }line[N];
    35 
    36 Vector operator+(Vector a , Vector b){return Vector(a.x+b.x , a.y+b.y);}
    37 Vector operator-(Vector a , Vector b){return Vector(a.x-b.x , a.y-b.y);}
    38 Vector operator*(Vector a , double b){return Vector(a.x*b , a.y*b);}
    39 Vector operator/(Vector a , double b){return Vector(a.x/b , a.y/b);}
    40 
    41 double Cross(Vector a , Vector b){return a.x*b.y-a.y*b.x;}
    42 
    43 bool OnLeft(Line L , Point P)
    44 {
    45     return dcmp(Cross(L.v , P-L.p))>=0;
    46 }
    47 
    48 Point GetIntersection(Line a , Line b)
    49 {
    50     Vector u = a.p-b.p;
    51     double t = Cross(b.v , u)/Cross(a.v , b.v);
    52     return a.p+a.v*t;
    53 }
    54 
    55 int HalfplaneIntersection(Line *L , int n , Point *poly)
    56 {
    57     sort(L , L+n);
    58     int first , last;
    59     Point *p = new Point[n];
    60     Line *q = new Line[n];
    61     q[first=last=0] = L[0];
    62     for(int i=1 ; i<n ; i++){
    63         while(first<last && !OnLeft(L[i] , p[last-1])) last--;
    64         while(first<last && !OnLeft(L[i] , p[first])) first++;
    65         q[++last] = L[i];
    66         if(fabs(Cross(q[last].v , q[last-1].v))<eps){
    67             last--;
    68             if(OnLeft(q[last] , L[i].p)) q[last]=L[i];
    69         }
    70         if(first < last) p[last-1] = GetIntersection(q[last-1] , q[last]);
    71     }
    72     while(first<last && !OnLeft(q[first] , p[last-1])) last--;
    73     if(last-first<=1) return 0;
    74     p[last] = GetIntersection(q[last] , q[first]);
    75     int m=0;
    76     for(int i=first ; i<=last ; i++) poly[m++] = p[i];
    77     return m;
    78 }
    79 
    80 int main()
    81 {
    82    // freopen("in.txt" , "r" , stdin);
    83     int n , cas=0 , flag=0;
    84     while(scanf("%d" , &n) , n)
    85     {
    86         if(flag) puts("");
    87         flag=1;
    88         for(int i=0 ; i<n ; i++) scanf("%lf%lf" , &p[i].x , &p[i].y);
    89         p[n] = p[0];
    90         for(int i=0 ; i<n ; i++) line[i] = Line(p[i] , p[i]-p[i+1]);
    91         printf("Floor #%d
    " , ++cas);
    92         if(HalfplaneIntersection(line , n , poly)) puts("Surveillance is possible.");
    93         else puts("Surveillance is impossible.");
    94     }
    95 }
    View Code

    poj 1279

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 
      7 using namespace std;
      8 #define N 1505
      9 #define ll long long
     10 #define eps 1e-9
     11 
     12 int dcmp(double x)
     13 {
     14     if(fabs(x)<eps) return 0;
     15     else return x<0?-1:1;
     16 }
     17 
     18 struct Point{
     19     double x,y;
     20     Point(double x=0 , double y=0):x(x),y(y){}
     21 }p[N] , poly[N];
     22 
     23 typedef Point Vector;
     24 
     25 struct Line{
     26     Point p;
     27     Vector v;
     28     double ang;
     29     Line(){}
     30     Line(Point p , Vector v):p(p),v(v){ang = atan2(v.y , v.x);}
     31     bool operator<(const Line &m) const{
     32         return dcmp(ang-m.ang)<0;
     33     }
     34 }line[N];
     35 
     36 Vector operator+(Vector a , Vector b){return Vector(a.x+b.x , a.y+b.y);}
     37 Vector operator-(Vector a , Vector b){return Vector(a.x-b.x , a.y-b.y);}
     38 Vector operator*(Vector a , double b){return Vector(a.x*b , a.y*b);}
     39 Vector operator/(Vector a , double b){return Vector(a.x/b , a.y/b);}
     40 
     41 double Cross(Vector a , Vector b){return a.x*b.y-a.y*b.x;}
     42 
     43 bool OnLeft(Line L , Point P)
     44 {
     45     return dcmp(Cross(L.v , P-L.p))>=0;
     46 }
     47 
     48 Point GetIntersection(Line a , Line b)
     49 {
     50     Vector u = a.p-b.p;
     51     double t = Cross(b.v , u)/Cross(a.v , b.v);
     52     return a.p+a.v*t;
     53 }
     54 
     55 int HalfplaneIntersection(Line *L , int n , Point *poly)
     56 {
     57     sort(L , L+n);
     58     int first , last;
     59     Point *p = new Point[n];
     60     Line *q = new Line[n];
     61     q[first=last=0] = L[0];
     62     for(int i=1 ; i<n ; i++){
     63         while(first<last && !OnLeft(L[i] , p[last-1])) last--;
     64         while(first<last && !OnLeft(L[i] , p[first])) first++;
     65         q[++last] = L[i];
     66         if(fabs(Cross(q[last].v , q[last-1].v))<eps){
     67             last--;
     68             if(OnLeft(q[last] , L[i].p)) q[last]=L[i];
     69         }
     70         if(first < last) p[last-1] = GetIntersection(q[last-1] , q[last]);
     71     }
     72     while(first<last && !OnLeft(q[first] , p[last-1])) last--;
     73     if(last-first<=1) return 0;
     74     p[last] = GetIntersection(q[last] , q[first]);
     75     int m=0;
     76     for(int i=first ; i<=last ; i++) poly[m++] = p[i];
     77     return m;
     78 }
     79 
     80 double calArea(Point *p , int n)
     81 {
     82     if(!n) return 0;
     83     double ret = 0;
     84     for(int i=2 ; i<n ; i++){
     85         ret += Cross(p[i-1]-p[0],p[i]-p[0]);
     86     }
     87     return ret/2;
     88 }
     89 
     90 int main()
     91 {
     92    // freopen("in.txt" , "r" , stdin);
     93     int T , n ;
     94     scanf("%d" , &T);
     95     while(T--)
     96     {
     97         scanf("%d" , &n);
     98         for(int i=0 ; i<n ; i++) scanf("%lf%lf" , &p[i].x , &p[i].y);
     99         p[n] = p[0];
    100         for(int i=0 ; i<n ; i++) line[i] = Line(p[i] , p[i]-p[i+1]);
    101         int cnt = HalfplaneIntersection(line , n , poly);
    102         printf("%.2f
    " , calArea(poly , cnt));
    103     }
    104 }
    View Code
  • 相关阅读:
    这种人就是傻逼
    WinDBG + VMWare 双机调试
    最近我遇到了一个代码上的问题
    GITHUB,Fork别人的代码,然后更新的问题
    又半个月没写了,最近忙,真的忙,在考虑换工作的问题
    最近在弄clamav,这里把clamav的编译方法弄一下吧
    基于seay代码,加了个小功能
    CTF:第七题
    CTF:第六题
    Python str拼接bytes
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4668890.html
Copyright © 2020-2023  润新知