hdu 2892 Area
http://acm.hdu.edu.cn/showproblem.php?pid=2892
解题思路:
求多边形与圆的相交的面积是多少。
以圆心为顶点,将多边形划分为n个三角形。
接下来就求出每个三角形与圆相交的面积。
因为三角形的一个点是圆心,所以三角形的另外两个点与圆的情况有以下几种:
(1)两点都在圆里,三角形与圆相交的面积=三角形的面积。
(2)一个点在圆外,一个点在圆里,三角形与圆相交的面积=小三角形的面积+扇形面积
(3)两点都在圆外,又分为几种情况:
1、两点构成的线段与圆相交的点数0或1个时,三角形与圆相交的面积=扇形的面积
2.两点构成的线段与圆相交的点数2个时,三角形与圆相交的面积=大扇形面积+小三角形面积-小扇形的面积
#include<cmath>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std; #define MAXN 100000+10
#define PI acos(-1.0)
#define EPS 0.00000001 int dcmp(double x){
if(fabs(x) < EPS)
return ;
return x < ? - : ;
} struct Point{
double x, y;
Point(double x = , double y = ): x(x), y(y) {}
}; struct Circle{
Point c;
double r;
Circle(Point c = Point(, ), double r = ): c(c), r(r) {}
}; typedef Point Vector; Vector operator + (Vector A, Vector B){
return Vector(A.x + B.x, A.y + B.y);
}
Vector operator - (Point A, Point B){
return Vector(A.x - B.x, A.y - B.y);
}
Vector operator * (Vector A, double p){
return Vector(A.x * p, A.y * p);
}
Vector operator / (Vector A, double p){
return Vector(A.x / p, A.y / p);
} double dot(Vector A, Vector B){
return A.x * B.x + A.y * B.y;
} double length(Vector A){
return sqrt(dot(A, A));
} double angle(Vector A, Vector B){
return acos(dot(A, B) / length(A) / length(B));
} double cross(Vector A, Vector B){
return A.x * B.y - A.y * B.x;
} Circle bomb;//炸弹爆炸的坐标及半径
Point p[MAXN];//岛屿的点
int n;//岛屿点数 double point_line_distance(Point P, Point A, Point B){//点到直线的距离
Vector AP = P - A, AB = B - A;
return fabs(cross(AP, AB) / length(AB));
} Point point_line_projection(Point P, Point A, Point B){//点在直线上的映射
Vector v = B - A;
return A + v * (dot(v, P - A) / dot(v, v));
} int circle_line_intersect(Circle C, Point A, Point B, vector<Point> &v){
double dist = point_line_distance(C.c, A, B);
int d = dcmp(dist - C.r);
if(d > ){
return ;
}
Point pro = point_line_projection(C.c, A, B);
if(d == ){
v.push_back(pro);
return ;
}
double len = sqrt(C.r * C.r - dist * dist);//勾股定理
Vector AB = B - A;
Vector l = AB / length(AB) * len;
v.push_back(pro + l);
v.push_back(pro - l);
return ;
} bool point_on_segment(Point P, Point A, Point B){//判断点在线段上
Vector PA = A - P, PB = B - P;
return dcmp(cross(PA, PB)) == && dcmp(dot(PA, PB)) <= ;
} double circle_delta_intersect_area(Circle C, Point A, Point B){
Vector CA = A - C.c, CB = B - C.c;
double da = length(CA), db = length(CB); da = dcmp(da - C.r), db = dcmp(db - C.r); if(da <= && db <= ){//三角形在圆里面
return fabs(cross(CA, CB)) * 0.5;
} vector<Point> v;
int num = circle_line_intersect(C, A, B, v);//圆和直线的关系
double carea = C.r * C.r * PI;
Point t;
if(da <= && db > ){//左边的点在圆里 右边的点在圆外
t = point_on_segment(v[], A, B) ? v[] : v[]; double area = fabs(cross(CA, t - C.c)) * 0.5, an = angle(CB, t - C.c);
return area + carea * an / PI / ;
}
if(da > && db <= ){//左边点在圆外 右边点在圆里
t = point_on_segment(v[], A, B) ? v[] : v[]; double area = fabs(cross(CB, t - C.c)) * 0.5, an = angle(CA, t - C.c);
return area + carea * an / PI / ;
}
//两个点都在圆外
if(num == ){
double bigarea = carea * angle(CA, CB) / PI / ,
smallarea = carea * angle(v[] - C.c, v[] - C.c) / PI / ,
deltaarea = fabs(cross(v[] - C.c, v[] - C.c)) * 0.5;
return bigarea + deltaarea - smallarea;
}
return carea * angle(CA, CB) / PI / ;//两点都在圆外 直线AB与圆交点1个或两个
} double circle_polygon_intersect_area(){//源于多边形相交面积
p[n] = p[];
double ans = ;
for(int i = ; i < n; i++ ){
double area = circle_delta_intersect_area( bomb, p[i], p[i + ] );
if(cross(p[i] - bomb.c, p[i + ] - bomb.c) < ){
area = -area;
}
ans += area;
}
return ans > ? ans : -ans;
} void solve(){
scanf("%d", &n );
for(int i = ; i < n; i++ ){
scanf("%lf%lf", &p[i].x, &p[i].y );
}
printf("%.2lf\n", circle_polygon_intersect_area() );
} int main(){
//freopen("data.in", "r", stdin );
double x, y, h, x1, y1, r;
while(~scanf("%lf%lf%lf", &x, &y, &h )){
scanf("%lf%lf%lf", &x1, &y1, &r ); double t = sqrt(0.2 * h);//h = 0.5 * G * t^2 重力加速度公式 bomb = Circle( Point(x1 * t + x, y1 * t + y), r ); solve();
}
return ;
}
hdu 2892 Area的更多相关文章
- hdu 2892 area (圆与多边形交面积)
Problem - 2892 这道题的做法是以圆心为原点,对多边形进行三角剖分.题目描述中,多边形的可能是顺时针或者是逆时针给出,不过在我的做法里,是用有向面积来计算的,和常见的多边形面积的求法类似, ...
- HDU - 2892:area (圆与多边形交 求面积)
pro:飞行员去轰炸一个小岛,给出炸弹落地点的位置信息,以及轰炸半径:按顺时针或者逆时针给出小岛的边界点. 求被轰炸的小岛面积. sol:即是求圆和多边形的面积交. (只会套板子的我改头换面,先理解然 ...
- hdu 2528 Area
2014-07-30 http://acm.hdu.edu.cn/showproblem.php?pid=2528解题思路: 求多边形被一条直线分成两部分的面积分别是多少.因为题目给的直线一定能把多边 ...
- hdu 4946 Area of Mushroom(凸包)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946 Area of Mushroom Time Limit: 2000/1000 MS (Java/Ot ...
- HDU 4946 Area of Mushroom(构造凸包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946 题目大意:在一个平面上有n个点p1,p2,p3,p4....pn,每个点可以以v的速度在平面上移 ...
- HDU 4946 Area of Mushroom 凸包
链接:pid=4946">http://acm.hdu.edu.cn/showproblem.php?pid=4946 题意:有n个人.在位置(xi,yi),速度是vi,假设对于某个点 ...
- HDU 4946 Area of Mushroom 凸包 第八次多校
题目链接:hdu 4946 题意:一大神有N个学生,各个都是小神,大神有个二次元空间,每一个小神都有一个初始坐标,如今大神把这些空间分给徒弟们,规则是假设这个地方有一个人比谁都先到这,那么这个地方就是 ...
- hdu 2528:Area(计算几何,求线段与直线交点 + 求多边形面积)
Area Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- hdu 1451 Area in Triangle(计算几何 三角形)
Given a triangle field and a rope of a certain length (Figure-1), you are required to use the rope t ...
随机推荐
- 用c++builder读取一个一行有多行变量的文件
文件内容如下: C DXDY.INP FILE, IN FREE FORMAT ACROSS COLUMNS for 83658 Active CellsC 2013-5-25 上午 10:43 ...
- from xml
/** * 将xml转为array * @param string $xml * @throws WxPayException */ public function FromXml($xml) { i ...
- 【Java 基础篇】【第二课】基本数组类型
就像第一章所说一样,这次学习为了快,因此说明性的文字就不想写太多了,直接帖代码吧,代码当中尽量加一些注释: package a.b; public class test { static void B ...
- 自动换行的矢量文字(android demo)
由于矢量字体的宽度不同,自测android字体,发现当中文字体大小为100像素时,字母s等 宽度大概在52,字母l等 宽度大概在26,这样自动换行就不可以按字符的个数计算截取每行显示的字串. 直接上代 ...
- Codeforce727B --- Bill Total Value(字符串处理 正则表达式)
先说一下正则表达式 %*[a-z]表示忽略前面的小写字符,%[0-9]表示把紧接着非字符的连续数字存入t字符串中去; 从"abc123de4f"中得到"123" ...
- 折腾Centos6.4记
背景: 闲置了一台Thinkpad,之前装的是Kali Linux,但无线网卡挂掉了,加之硬盘分区不当,平时几乎没怎么用,重新使用kali的livecd进行分区,然后安装,总是出错,尝试了七八次,仍然 ...
- Selenium2学习-022-WebUI自动化实战实例-020-JavaScript 在 Selenium 自动化中的应用实例之二(获取浏览器显示区域大小)
前几篇文章中简略概述了,如何获取.设置浏览器窗口大小,那么我们该如何获取浏览器显示区域的大小呢?此文讲对此进行简略概述,敬请各位小主参阅.若有不足之处,敬请各位大神指正,不胜感激! 获取浏览器显示区域 ...
- imx6 启动 init进程
之前不知道imx6内核是怎么启动文件系统的init进程,查了下资料,记录于此,以后再来补充. kernel/init/main.c static noinline int init_post(void ...
- mouseenter(fn)和mouseleave、mouseover和mouseout的的区别
$('.box1').mouseenter(function(){//穿入事件mouseenter $(this).css('background','red'); }).mouseleave(fun ...
- docker:从 tomcat 容器连接到 mysql 容器
docker 中的容器互联是一个较为复杂的话题,详细内容将在后续章节中介绍. 续前 2 个章节的内容,我们创建了一个 mysql 容器和一个 tomcat 容器,可以使用 「docker ps」来查看 ...