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采用的是Jarvis步进法(Gift Wrapping Algorithm)或Graham扫描法等经典算法来求解凸包。这些算法的基本思想是通过一系列迭代找到边界上的关键点,从而构建出凸包的顺序。QHull库在这些基础算法上进行了优化,...
在给定的Java程序中,“计算几何求凸包算法的java实现”是解决这个问题的关键。 这个Java代码实现了对离散点集进行求解凸包的过程。在图形用户界面中,用户可以通过鼠标点击生成点,程序会实时地计算这些点的凸包并...
对于给定的一组点集,求解凸包可以采用多种算法,如 Graham's Scan、Jarvis March( gift wrapping algorithm)或 Andrew's Monotone Chain Algorithm。 Graham's Scan算法首先找到点集中最低的点作为起点,然后按...
卡壳算法,又称为Jarvis March或Gift Wrapping Algorithm,是一种常用的求解凸包的方法。它的基本思想是从点集中选取一个初始点,然后依次将其他点与当前凸包上的点进行比较,选择离当前凸包最远的点加入到凸包上,...
在计算机图形学中,凸包(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算法,因为它相对简单且易于理解。 **...
在计算机科学中,凸包(Convex Hull)是包含在一个给定集合内的所有点的最小凸多边形。它在图形学、机器学习、几何计算等领域有着广泛的应用。本篇文章将详细探讨两种用于求解平面散点集凸包的算法:Graham Jarvis...
1. Gift Wrapping算法( Jarvis March):这是一种简单的遍历算法,从一个初始点开始,依次选择与当前凸包最远的点加入到凸包中,直到所有点都被考虑过。这种方法效率较低,但易于理解。 2. Graham's Scan:首先...
在计算机图形学和算法设计中,"根据已知顶点求构成凸包的顶点集合" 是一个...虽然存在其他更复杂的算法(如 Gift Wrapping 或 Jarvis March),但 Graham 扫描法由于其简洁性和效率,通常被视为求二维凸包的首选方法。
在计算机科学中,凸包问题是一项基础且重要的算法问题,特别是在几何计算和图形学领域。简单来说,给定一组在二维平面上的点,凸包问题是找到这些点构成的最小凸多边形,使得所有点都在这个多边形内或者在其边界上。...
在计算机图形学和算法设计中,"凸包顶点逆时针排序"是一个常见的问题,尤其是在处理二维几何形状时。凸包(Convex Hull)是指包含所有点且仅包含这些点的最小凸多边形。逆时针排序则是指按照顺时针或逆时针方向对...
在三维数据的网格化处理中,平面点的凸包求取有重要的应用。比如,当我们有一组散乱的三维点云,可能代表一个物体的表面,通过将其投影到二维平面上并找出这些投影点的凸包,我们可以得到物体在该视图下的边界轮廓。...
Gift-Wrapping算法是一种直观的方法,它从一个边界点开始,以一个假设的“礼物包装纸”围绕点集缠绕直到回到起始点,每次移动都是沿着当前凸包的边界进行,直到形成整个凸包。算法步骤如下: - Step1:找出所有点中...
2. ** Jarvis March(Gift Wrapping)算法**:也称为“回转扫描”算法,从一个极点开始,依次将点加入凸包,直到所有点都考虑过且无新的点在当前凸包的外面。 3. **Kirkpatrick-Seidel算法**:这是一种更高效的算法...
凸包算法的常见类型有 Gift Wrapping( Jarvis March)算法、 Graham's Scan 和 QuickHull 等。其中,Gift Wrapping算法是相对简单且易于理解的一种,它通过遍历点集,找到离原点最近的点作为起点,然后逐步添加下一...
接下来,我们要讨论的算法是“Jarvis步进法”或“ gift wrapping算法”,这是一种常用的生成凸包的方法。该算法的基本思想是从点集中选择一个最左边的点作为起点,然后遍历其余点,每次选择与当前点连线与x轴夹角...