ecnu1624求交集多边形面积
本来在刷hdu的一道题。。一直没过,看到谈论区发现有凹的,我这种方法只能过凸多边形的相交面积。。
就找来这道题试下水。
两个凸多边形相交的部分要么没有 要么也是凸多边形,那就可以把这部分单独拿出来极角排序、叉积求面积。这部分的顶点要么p在q内的顶点,要么是q在p内的顶点,要么是两凸多边形的交点。
用到了点在多边形内的判定模板。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 10000
#define LL long long
#define INF 0xfffffff
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
struct point
{
double x,y;
point(double x=,double y = ):x(x),y(y) {}
} p[N],q[N],ch[N],chh[N];
typedef point pointt;
point operator -(point a,point b)
{
return point(a.x-b.x,a.y-b.y);
}
int dcmp(double x)
{
if(fabs(x)<eps) return ;
return x<?-:;
}
double cross(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
double dis(point a)
{
return sqrt(a.x*a.x+a.y*a.y);
}
double getarea(point p[],int n)
{
int i;
double area = ;
for(i = ; i < n-; i++)
area+=cross(p[i]-p[],p[i+]-p[]);
area = fabs(area)/;
return area;
}
bool PtInPolygon (point p, point ptPolygon[], int nCount)
{
int i,nCross = ;
for(i = ; i< nCount ; i++)
{
point p1 = ptPolygon[i];
point p2 = ptPolygon[(i+)%nCount];
if(dcmp(p1.y-p2.y)==) continue;
if(dcmp(p.y-min(p1.y,p2.y))<) continue;
if(dcmp(p.y-max(p1.y,p2.y))>=) continue;
double x = (double)(p.y-p1.y)*(double)(p2.x-p1.x)/(double)(p2.y-p1.y)+p1.x;
if(x>p.x) nCross++;
}
return (nCross % == );
}
bool segprointer(point a1,point a2,point b1,point b2)
{
double c1 = cross(a2-a1,b1-a1),c2 = cross(a2-a1,b2-a1);
double c3 = cross(b2-b1,a1-b1),c4 = cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<&&dcmp(c3)*dcmp(c4)<;
}
bool intersection1(point p1, point p2, point p3, point p4, point& p) // 直线相交
{
double a1, b1, c1, a2, b2, c2, d;
a1 = p1.y - p2.y;
b1 = p2.x - p1.x;
c1 = p1.x*p2.y - p2.x*p1.y;
a2 = p3.y - p4.y;
b2 = p4.x - p3.x;
c2 = p3.x*p4.y - p4.x*p3.y;
d = a1*b2 - a2*b1;
if (!dcmp(d)) return false;
p.x = (-c1*b2 + c2*b1) / d;
p.y = (-a1*c2 + a2*c1) / d;
return true;
}
double mul(point p0,point p1,point p2)
{
return cross(p1-p0,p2-p0);
} bool cmp(point a,point b)
{
if(dcmp(mul(ch[],a,b))==)
return dis(a-ch[])<dis(b-p[]);
else
return dcmp(mul(ch[],a,b))>;
}
bool cmpp(point a,point b)
{
if(dcmp(a.x-b.x)==) return a.y<b.y;
return a.x<b.x;
}
int main()
{
int n,m,i,j;
while(scanf("%d",&n)!=EOF)
{ for(i = ; i < n ; i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
p[n] = p[];
scanf("%d",&m);
for(i = ; i < m; i++)
scanf("%lf%lf",&q[i].x,&q[i].y);
q[m] = q[];
int g = ;
for(i = ; i < n ; i ++)
{
if(PtInPolygon(p[i],q,m))
ch[g++] = p[i];
}
for(i = ; i < m ; i ++)
{
if(PtInPolygon(q[i],p,n))
ch[g++] = q[i];
}
for(i = ; i < n; i++)
{
for(j = ; j < m ; j++)
{
if(segprointer(p[i],p[i+],q[j],q[j+])==) continue;
point pp;
if(!intersection1(p[i],p[i+],q[j],q[j+],pp))continue;
ch[g++] = pp;
}
}
double ans = ;//getarea(p,n)+getarea(q,m);
if(g==)
ans = ;
else
{
int k = ,o=;
sort(ch,ch+g,cmpp);
chh[o++] = ch[];
for(i = ; i < g; i++)
if(dcmp(ch[i].x-ch[i-].x)==&&dcmp(ch[i].y-ch[i-].y)==)
continue;
else chh[o++] = ch[i];
g = o;
for(i = ; i < g ; i ++)
{
if(dcmp(chh[i].y-chh[k].y)<||(dcmp(chh[i].y-chh[k].y)==&&dcmp(chh[i].x-chh[k].x)<))
k = i;
}
if(k!=) swap(chh[k],chh[]);
sort(chh+,chh+g,cmp);
ans = getarea(chh,g);
}
printf("%.2f\n",ans);
}
return ;
}
ecnu1624求交集多边形面积的更多相关文章
- [ECNU 1624] 求交集多边形面积
求交集多边形面积 Time Limit:1000MS Memory Limit:30000KB Total Submit:98 Accepted:42 Description 在平面上有两给定的凸多边 ...
- hdu-2036求任意多边形面积
改革春风吹满地 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- 求任意多边形面积 python实现
数学解决方法: 多边形外选取一点,连接各点构成三角形,计算求和...... 详细链接 http://blog.csdn.net/hemmingway/article/details/7814494 ...
- HDU 2036 求任意多边形面积向量叉乘
三角形的面积可以使用向量的叉积来求: 对于 三角形的面积 等于: [(x2 - x1)*(y3 - y1)- ( y2 - y1 ) * ( x3 - x1 ) ] / 2.0 但是面积是有方向的, ...
- poj 1654 Area(计算几何--叉积求多边形面积)
一个简单的用叉积求任意多边形面积的题,并不难,但我却错了很多次,double的数据应该是要转化为long long,我转成了int...这里为了节省内存尽量不开数组,直接计算,我MLE了一发...,最 ...
- EOJ 1058. 挤模具 (多边形面积)
题目链接:1058. 挤模具 题意 给出模具的底和体积,求模具的高. 思路 模具的底为多边形,因此求出多边形面积,用体积除以底的面积就是答案. 多边形的面积求解见 EOJ 1127. 多边形面积(计算 ...
- 三角剖分求多边形面积的交 HDU3060
//三角剖分求多边形面积的交 HDU3060 #include <iostream> #include <cstdio> #include <cstring> #i ...
- Area - POJ 1654(求多边形面积)
题目大意:从原点开始,1-4分别代表,向右下走,向右走,向右上走,向下走,5代表回到原点,6-9代表,向上走,向左下走,向左走,向左上走.求出最后的多边形面积. 分析:这个多边形面积很明显是不规则的, ...
- hdu 2036 求多边形面积 (凸、凹多边形)
<题目链接> Problem Description “ 改革春风吹满地,不会AC没关系;实在不行回老家,还有一亩三分地.谢谢!(乐队奏乐)” 话说部分学生心态极好,每天就知道游戏,这次考 ...
随机推荐
- php开启openssl的方法
windows下开启方法: 1: 首先检查php.ini中:extension=php_openssl.dll是否存在, 如果存在的话去掉前面的注释符‘:’, 如果不存在这行,那么添加extensio ...
- 周赛-Integration of Polynomial 分类: 比赛 2015-08-02 08:40 10人阅读 评论(0) 收藏
Integration of Polynomial Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/O ...
- Apache Common-pool2对象池分析和应用
Apache Common-pool2包提供了一个通用的对象池技术的实现.可以很方便的基于它来实现自己的对象池,比如DBCP和Jedis他们的内部对象池的实现就是依赖于Common-pool2. 对象 ...
- Android 内存分析工具 - LogCat GC
一.GC_Reason 触发垃圾回收的回收的集中原因: 类型 描述 GC_CONCURRENT 内存使用将满时,并发的进行垃圾回收. GC_FOR_MALLOC 当内存已满应用尝试分配内存时会出触发垃 ...
- Android:onNewIntent()触发机制及注意事项
一.onNewIntent() 在IntentActivity中重写下列方法:onCreate onStart onRestart onResume onPause onStop onDestro ...
- Flume-NG + HDFS + HIVE日志收集分析
摘自:http://blog.csdn.net/cnbird2008/article/details/18967449
- 【MySQL】MySQL的group_concat使用例子
> 参考的优秀文章 GROUP_CONCAT(expr) > 简单的例子 此函数的功能,是拼接group分组多行的数据为一行,并可以指定去重.排序.分隔符. 例子: select t.na ...
- 【Linux】CentOS设置静态IP(非动态获取IP)
在VMware上安装好Linux后,默认设置的动态IP,每次启动的IP都不同,远程连接挺费劲的. 于是,需要设置静态的IP,至少我从远程工具连接上去方便多了.另外,为了安装一些软件,也需要访问互联网. ...
- ActiveMQ点对点的消息发送案例
公司最近会用MQ对某些业务进行处理,所以,这次我下载了apache-activemq-5.12.0-bin把玩下. 基于练习方便需要,使用Windows的版本. 参考的优秀文章: activemq的几 ...
- 使用js实现移动设备访问跳转到指定目录
最近最项目的时候总会同时做pc站点跟手机站点,当手机访问的时候默认是看到pc站点的,需要在url上加上/mobile才能正常访问,这段代码是我同事分享给我的,还是蛮实用的. CODE function ...