zoukankan      html  css  js  c++  java
  • POJ 1279 Art Gallery(半平面交求多边形核的面积)

    题目链接

    题意 : 求一个多边形的核的面积。

    思路 : 半平面交求多边形的核,然后在求面积即可。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <math.h>
    
    using namespace std ;
    
    struct node
    {
        double x;
        double y ;
    } p[1510],temp[1510],newp[1510];//p是最开始的多边形的每个点,temp是中间过程中临时存的多边形的每个点,newp是切割后的多边形的每个点
    int n,newn ;//原来的点数,切割后的点数
    double a,b,c ;//直线方程的三个系数
    
    void getline(node x,node y)//求x与y两点确定的直线方程ax+by+c=0
    {
        a = y.y-x.y ;
        b = x.x-y.x ;
        c = y.x*x.y - y.y*x.x ;
    }
    node intersect(node x,node y)//求x与y点确定的直线与ax+by+c=0这条直线的交点
    {
        double u = fabs(a*x.x+b*x.y+c) ;
        double v = fabs(a*y.x+b*y.y+c) ;
        node t ;
        t.x = (x.x*v+y.x*u)/(u+v) ;//y.y-x.y=u+v;y.y-t.y=v;y.y-x.y=u;
        t.y = (x.y*v+y.y*u)/(u+v) ;
        return t ;
    }
    void cut()
    {
        int cutn = 0 ;
        for(int i = 1 ; i <= newn ; i++)
        {
            if(a*newp[i].x+b*newp[i].y+c >= 0)//所有的点都大于0,说明所有的点都在这条直线的另一边,所以不用切
                temp[ ++cutn] = newp[i] ;
            else
            {
                if(a*newp[i-1].x+b*newp[i-1].y+c > 0)
                    temp[++cutn ] = intersect(newp[i-1],newp[i]) ;//把新交点加入
                if(a*newp[i+1].x+b*newp[i+1].y+c > 0)
                    temp[ ++cutn] = intersect(newp[i+1],newp[i]) ;
            }
        }
        for(int i = 1 ; i <= cutn ; i++)
            newp[i] = temp[i] ;
        newp[cutn+1] = temp[1] ;//能够找出所有点的前驱和后继
        newp[0] = temp[cutn] ;
        newn = cutn ;
    }
    
    double solve()
    {
        for(int i = 1 ; i <= n ; i++)
        {
            newp[i] = p[i] ;
        }
        p[n+1] = p[1] ;
        newp[n+1] = newp[1] ;
        newp[0] = newp[n] ;
        newn = n ;
        for(int i = 1 ; i <= n ; i++)
        {
            getline(p[i],p[i+1]) ;//从头开始顺序遍历两个相邻点。
            cut() ;
        }
        //求多边形核的面积
        double s = 0 ;
        for(int i = 1 ; i <= newn ; i++)
            s += newp[i].x*newp[i+1].y-newp[i].y*newp[i+1].x ;
        return s = fabs(s/2.0) ;
    }
    void guizhenghua()
    {
        for(int i = 1 ; i < (n+1)/2 ; i++)//规整化方向,顺时针变逆时针,逆时针变顺时针。
            swap(p[i],p[n-i]) ;
    }
    int main()
    {
        int T ;
        scanf("%d",&T) ;
        while(T--)
        {
            scanf("%d",&n) ;
            for(int i = 1 ; i <= n ; i++)
                scanf("%lf %lf",&p[i].x,&p[i].y) ;
            double s = solve() ;
            printf("%.2lf
    ",s) ;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    cocos2dx触摸响应
    MFC注册热键
    隐式类型转换
    virtualbox导入winXP系统OVA文件重启
    virtualbox虚拟机下的cdlinux找不到无线网卡的解决方法
    批处理,修改环境变量path的方法(加环境变量)
    什么是堆和栈,它们在哪儿?
    ON_WM_TIMER() void (__cdecl xx::* )(UINT)”转换为“void (__cdecl CWnd::* )(UINT_PTR)
    读书笔记:《你的知识需要管理》
    linux系统管理-软件包管理
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3959646.html
Copyright © 2011-2022 走看看