`
阿尔萨斯
  • 浏览: 4472057 次
社区版块
存档分类
最新评论

UVA 10652 Board Wrapping(凸包求面积)

 
阅读更多

UVA 10652 Board Wrapping(凸包求面积)

题意:

有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们包起来,并计算木板占整个包装面积的百分比.

分析: 刘汝佳<<训练指南>> P272例题6

给出了每个木板的中心和长,宽以及旋转角度,通过先旋转向量然后把中心点平移对应的向量可以求出矩形的4个顶点坐标.

然后我们根据矩形的所有顶点求出凸包,并求出凸包的面积.(即总面积)

最后用所有矩形的面积和/总面积就是百分比了.

AC代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-10;
const double PI=acos(-1);
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    return x<0?-1:1;
}
struct Point
{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
    bool operator<(const Point &B)const
    {
        return dcmp(x-B.x)<0 || (dcmp(x-B.x)==0 && dcmp(y-B.y)<0 );
    }
    bool operator==(const Point &B)const
    {
        return dcmp(x-B.x)==0 && dcmp(y-B.y)==0;
    }
};
typedef Point Vector;

Vector operator-(Point A,Point 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);
}
double Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}
Vector Rotate(Vector A,double rad)
{
    return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
}
double PolygonArea(Point *p,int n)
{
    double area=0;
    for(int i=1;i<n-1;++i)
        area += Cross(p[i]-p[0],p[i+1]-p[0]);
    return fabs(area)/2;
}
int ConvexHull(Point *p,int n,Point *ch)
{
    sort(p,p+n);
    n=unique(p,p+n)-p;
    int m=0;
    for(int i=0;i<n;++i)
    {
        while(m>1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-1])<=0 ) --m;
        ch[m++]=p[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--)
    {
        while(m>k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-1])<=0) --m;
        ch[m++]=p[i];
    }
    if(n>1) m--;
    return m;
}

const int maxn=600*4+10;
Point p[maxn];
int cnt;//点数目

int main()
{
    int T; scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        cnt=0;          //当前点数目
        double area1=0;//矩形面积和
        while(n--)
        {
            double x,y,w,h,j;
            scanf("%lf%lf%lf%lf%lf",&x,&y,&w,&h,&j);
            area1 += w*h;
            Point o(x,y);           //矩形中心点
            double rad=-(j/180*PI); //角度转弧度
            p[cnt++]=o+Rotate(Vector(w/2,h/2), rad);
            p[cnt++]=o+Rotate(Vector(-w/2,h/2), rad);
            p[cnt++]=o+Rotate(Vector(w/2,-h/2), rad);
            p[cnt++]=o+Rotate(Vector(-w/2,-h/2), rad);
        }
        Point q[maxn];
        cnt=ConvexHull(p,cnt,q);
        double area2=PolygonArea(q,cnt);//凸包总面积
        printf("%.1lf %%\n",area1*100/area2);
    }
    return 0;
}

分享到:
评论

相关推荐

    求凸包及其直径

    对于给定的点集,求解凸包的方法有很多种,其中最著名的两种是格拉姆-舒尔茨(Graham's Scan)算法和 Jarvis March(也称为gift wrapping 或刺探法)。Graham's Scan首先找到一个最低点作为起点,然后按照角度排序...

    计算几何求凸包

    对于更复杂的点集,我们可以使用上述算法来找出其凸包,并进行各种几何分析,例如判断点是否在多边形内、计算面积、求最近点对等。 在实际应用中,凸包算法在计算机图形学、机器学习、图像处理等领域有着广泛的应用...

    凸包求取运行调试成功

    在VB(Visual Basic)环境下,实现“凸包求取”是一项关键的几何计算任务,尤其在处理二维点集时。凸包是包含所有点的最小凸多边形,它的概念在计算机图形学、地理信息系统、机器学习等领域都有广泛应用。本项目通过...

    qhull求二维凸包的程序

    QHull采用的是Jarvis步进法(Gift Wrapping Algorithm)或Graham扫描法等经典算法来求解凸包。这些算法的基本思想是通过一系列迭代找到边界上的关键点,从而构建出凸包的顺序。QHull库在这些基础算法上进行了优化,...

    计算几何求凸包算法的java实现

    在给定的Java程序中,“计算几何求凸包算法的java实现”是解决这个问题的关键。 这个Java代码实现了对离散点集进行求解凸包的过程。在图形用户界面中,用户可以通过鼠标点击生成点,程序会实时地计算这些点的凸包并...

    凸包的可视化程序,即使画出凸包

    对于给定的一组点集,求解凸包可以采用多种算法,如 Graham's Scan、Jarvis March( gift wrapping algorithm)或 Andrew's Monotone Chain Algorithm。 Graham's Scan算法首先找到点集中最低的点作为起点,然后按...

    凸包-卡壳算法求最远距离

    卡壳算法,又称为Jarvis March或Gift Wrapping Algorithm,是一种常用的求解凸包的方法。它的基本思想是从点集中选取一个初始点,然后依次将其他点与当前凸包上的点进行比较,选择离当前凸包最远的点加入到凸包上,...

    根据已知顶点求构成凸包的顶点集合(C#)

    在计算机图形学中,凸包(Convex Hull)是包含一组点的最大凸多边形,它在二维空间中是由这些点形成的一个最小面积的封闭多边形。本篇将详细讲解如何利用C#语言来实现根据已知顶点集合求解凸包的方法,特别是采用扫描...

    给定点求取凸包并进行三角剖分

    常见的求取凸包的算法有 Gift Wrapping(也称为 Jarvis March)算法、 Graham's Scan 算法和 QuickHull 算法。这些算法各有优缺点,例如Gift Wrapping适合小规模数据,Graham's Scan对初始排序敏感,而QuickHull则在...

    生成凸包代码

    在C#中实现生成凸包的算法,我们通常会利用已有的数据结构和算法,如 Gift Wrapping(也称为 Jarvis March)算法 或者 Graham's Scan 算法。这里我们将主要关注Gift Wrapping算法,因为它相对简单且易于理解。 **...

    Graham Jarvis两种算法求散点集凸包

    在计算机科学中,凸包(Convex Hull)是包含在一个给定集合内的所有点的最小凸多边形。它在图形学、机器学习、几何计算等领域有着广泛的应用。本篇文章将详细探讨两种用于求解平面散点集凸包的算法:Graham Jarvis...

    游戏中凸包算法

    1. Gift Wrapping算法( Jarvis March):这是一种简单的遍历算法,从一个初始点开始,依次选择与当前凸包最远的点加入到凸包中,直到所有点都被考虑过。这种方法效率较低,但易于理解。 2. Graham's Scan:首先...

    根据已知顶点求构成凸包的顶点集合

    在计算机图形学和算法设计中,"根据已知顶点求构成凸包的顶点集合" 是一个...虽然存在其他更复杂的算法(如 Gift Wrapping 或 Jarvis March),但 Graham 扫描法由于其简洁性和效率,通常被视为求二维凸包的首选方法。

    凸包问题 蛮力法-C语言

    在计算机科学中,凸包问题是一项基础且重要的算法问题,特别是在几何计算和图形学领域。简单来说,给定一组在二维平面上的点,凸包问题是找到这些点构成的最小凸多边形,使得所有点都在这个多边形内或者在其边界上。...

    凸包顶点逆时针排序

    在计算机图形学和算法设计中,"凸包顶点逆时针排序"是一个常见的问题,尤其是在处理二维几何形状时。凸包(Convex Hull)是指包含所有点且仅包含这些点的最小凸多边形。逆时针排序则是指按照顺时针或逆时针方向对...

    平面点的凸包点的求取

    在三维数据的网格化处理中,平面点的凸包求取有重要的应用。比如,当我们有一组散乱的三维点云,可能代表一个物体的表面,通过将其投影到二维平面上并找出这些投影点的凸包,我们可以得到物体在该视图下的边界轮廓。...

    探求二维凸包及其应用

    Gift-Wrapping算法是一种直观的方法,它从一个边界点开始,以一个假设的“礼物包装纸”围绕点集缠绕直到回到起始点,每次移动都是沿着当前凸包的边界进行,直到形成整个凸包。算法步骤如下: - Step1:找出所有点中...

    做Delaunay过程中用到的凸包算法

    2. ** Jarvis March(Gift Wrapping)算法**:也称为“回转扫描”算法,从一个极点开始,依次将点加入凸包,直到所有点都考虑过且无新的点在当前凸包的外面。 3. **Kirkpatrick-Seidel算法**:这是一种更高效的算法...

    用C#编写的凸包算法

    凸包算法的常见类型有 Gift Wrapping( Jarvis March)算法、 Graham's Scan 和 QuickHull 等。其中,Gift Wrapping算法是相对简单且易于理解的一种,它通过遍历点集,找到离原点最近的点作为起点,然后逐步添加下一...

    利用栈在MFC上画凸包

    接下来,我们要讨论的算法是“Jarvis步进法”或“ gift wrapping算法”,这是一种常用的生成凸包的方法。该算法的基本思想是从点集中选择一个最左边的点作为起点,然后遍历其余点,每次选择与当前点连线与x轴夹角...

Global site tag (gtag.js) - Google Analytics