hdu 4404 Worms(多边形与圆的交)
求出爆炸点的坐标,就成了多边形与圆相交面积的模板题了。。。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<fstream>
#include<sstream>
#include<vector>
#include<string>
#include<cstdio>
#include<bitset>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#include<set>
#define FF(i, a, b) for(int i=a; i<b; i++)
#define FD(i, a, b) for(int i=a; i>=b; i--)
#define REP(i, n) for(int i=0; i<n; i++)
#define CLR(a, b) memset(a, b, sizeof(a))
#define LL long long
#define PB push_back
#define eps 1e-10
#define debug puts("**debug**")
using namespace std; const int maxn = 110;
const double PI = acos(-1);
struct Point
{
double x, y;
Point (double x=0, double y=0):x(x), y(y) {}
};
typedef Point Vector;
struct Circle
{
Point c;
double r;
Circle() {}
Circle(Point c, double r) : c(c), r(r) {}
Point point(double a) { return Point(c.x+cos(a)*r, c.y+sin(a)*r); }
};
struct Line
{
Point p;
Vector v;
double ang;
Line(){}
Line(Point p, Vector v) : p(p), v(v) {ang = atan2(v.y, v.x); }
Point point(double t)
{
return Point(p.x + t*v.x, p.y + t*v.y);
}
bool operator < (const Line& L) const
{
return ang < L.ang;
}
}; template <class T> T sqr(T x) { return x * x;}
Vector operator + (Vector A, Vector 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); }
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); }
bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
int dcmp(double x)
{
if(fabs(x) < eps) return 0;
return x < 0 ? -1 : 1;
}
bool operator == (const Point& a, const Point& b){ return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;} 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 Angel(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; }
double torad(double d) { return (d/180)*PI; }
Vector vecunit(Vector x){ return x / Length(x);} //单位向量
Vector normal(Vector x) { return Point(-x.y, x.x) / Length(x);} //垂直法向量
Point GetIntersection(Line a, Line b) //线段交点
{
Vector u = a.p-b.p;
double t = Cross(b.v, u) / Cross(a.v, b.v);
return a.p + a.v*t;
}
bool OnSegment(Point p, Point a1, Point a2)
{
return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
} bool InCircle(Point x, Circle c) { return dcmp(sqr(c.r) - sqr(Length(c.c - x))) >= 0;}
bool OnCircle(Point x, Circle c) { return dcmp(sqr(c.r) - sqr(Length(c.c - x))) == 0;}
double angle(Vector x) { return atan2(x.y, x.x);} //直线与圆交点
int getLineCircleIntersection(Line L, Circle C, double& t1, double& t2, vector<Point>& sol)
{
double a=L.v.x, b=L.p.x-C.c.x, c=L.v.y, d=L.p.y-C.c.y;
double e=a*a+c*c, f=2*(a*b+c*d), g=b*b+d*d-C.r*C.r;
double delta=f*f-4*e*g;
if(dcmp(delta) < 0) return 0;
if(dcmp(delta) == 0)
{
t1 = t2 = -f/(2*e); sol.PB(L.point(t1));
return 1;
}
t1 = (-f-sqrt(delta))/(2*e); sol.PB(L.point(t1));
t2 = (-f+sqrt(delta))/(2*e); sol.PB(L.point(t2));
return 2;
} //线段与圆的焦点
int getSegCircleIntersection(Line L, Circle C, Point* sol)
{
Vector nor = normal(L.v);
Line pl = Line(C.c, nor);
Point ip = GetIntersection(pl, L);
double dis = Length(ip - C.c);
if (dcmp(dis - C.r) > 0) return 0;
Point dxy = vecunit(L.v) * sqrt(sqr(C.r) - sqr(dis));
int ret = 0;
sol[ret] = ip + dxy;
if (OnSegment(sol[ret], L.p, L.point(1))) ret++;
sol[ret] = ip - dxy;
if (OnSegment(sol[ret], L.p, L.point(1))) ret++;
return ret;
} double SegCircleArea(Circle C, Point a, Point b) //线段切割圆
{
double a1 = angle(a - C.c);
double a2 = angle(b - C.c);
double da = fabs(a1 - a2);
if (da > PI) da = PI * 2.0 - da;
return dcmp(Cross(b - C.c, a - C.c)) * da * sqr(C.r) / 2.0;
} double PolyCiclrArea(Circle C, Point *p, int n)//多边形与圆相交面积
{
double ret = 0.0;
Point sol[2];
p[n] = p[0];
REP(i, n)
{
double t1, t2;
int cnt = getSegCircleIntersection(Line(p[i], p[i+1]-p[i]), C, sol);
if (cnt == 0)
{
if (!InCircle(p[i], C) || !InCircle(p[i+1], C)) ret += SegCircleArea(C, p[i], p[i+1]);
else ret += Cross(p[i+1] - C.c, p[i] - C.c) / 2.0;
}
if (cnt == 1)
{
if (InCircle(p[i], C) && !InCircle(p[i+1], C)) ret += Cross(sol[0] - C.c, p[i] - C.c) / 2.0, ret += SegCircleArea(C, sol[0], p[i+1]);
else ret += SegCircleArea(C, p[i], sol[0]), ret += Cross(p[i+1] - C.c, sol[0] - C.c) / 2.0;
}
if (cnt == 2)
{
if ((p[i] < p[i + 1]) ^ (sol[0] < sol[1])) swap(sol[0], sol[1]);
ret += SegCircleArea(C, p[i], sol[0]);
ret += Cross(sol[1] - C.c, sol[0] - C.c) / 2.0;
ret += SegCircleArea(C, sol[1], p[i+1]);
}
}
return fabs(ret);
} int n;
double x, y, v, ang, t, g, r;
Circle C;
Point p[maxn]; int main()
{
while (scanf("%lf%lf%lf%lf%lf%lf%lf", &x, &y, &v, &ang, &t, &g, &r))
{
if(x == 0 && y == 0 && v == 0 && ang == 0 && t == 0 && g == 0 && r == 0) break;
ang = torad(ang);
C = Circle(Point(x + v*cos(ang)*t, y + v*sin(ang)*t - 0.5*g*t*t), r); scanf("%d", &n);
REP(i, n) scanf("%lf%lf", &p[i].x, &p[i].y);
printf("%.2f\n", PolyCiclrArea(C, p, n));
}
return 0;
}
hdu 4404 Worms(多边形与圆的交)的更多相关文章
- HDU 5130 Signal Interference --计算几何,多边形与圆的交面积
题意: 求所有满足PB <= k*PA 的P所在区域与多边形的交面积. 解法: 2014广州赛区的银牌题,当时竟然没发现是圆,然后就没做出来,然后就gg了. 圆的一般式方程: 设A(x1,y1) ...
- HDU - 5130 :Signal Interference (多边形与圆的交)
pro:A的监视区域是一个多边形. 如果A的监视区的内满足到A的距离到不超过到B的距离的K倍的面积大小.K<1 sol:高中几何体经验告诉我们满足题意的区域是个圆,那么就是求圆与多边形的交. # ...
- poj3675 求多边形与圆的面积交
题意:给出多边形的顶点坐标.圆的圆心坐标和半径,求面积交 sol:又是模板题啦= = 注意poj的C++好像认不出hypot函数,要稍微改写一下. hypot(double x,double y):即 ...
- hdu 3264 圆的交+二分
Open-air shopping malls Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- 牛客网暑期ACM多校训练营(第三场)J 多边形与圆相交的面积
链接:https://www.nowcoder.com/acm/contest/141/J 题目描述 Eddy has graduated from college. Currently, he is ...
- AMap编辑折线、多边形、圆
<!doctype html> <html> <head> <meta charset="utf-8"> <meta http ...
- C++实现glut绘制点、直线、多边形、圆
C++实现glut绘制点.直线.多边形.圆 必备环境 glut.h 头文件 glut32.lib 对象文件库 glut32.dll 动态连接库 程序说明 C++实现了用glut画点.画直线.画多边形和 ...
- HDU 3467 (求五个圆相交面积) Song of the Siren
还没开始写题解我就已经内牛满面了,从晚饭搞到现在,WA得我都快哭了呢 题意: 在DotA中,你现在1V5,但是你的英雄有一个半径为r的眩晕技能,已知敌方五个英雄的坐标,问能否将该技能投放到一个合适的位 ...
- Quartz2D常见图形的绘制:线条、多边形、圆
UI高级 Quartz2D http://ios.itcast.cn iOS学院 掌握 drawRect:方法的使用 常见图形的绘制:线条.多边形.圆 绘图状态的设置:文字颜色.线宽等 图形上下文状 ...
随机推荐
- Swift初体验 (一)
// 声明一个常量 let maxNumberOfStudents: Int = 47 // 声明一个变量,假设没有在声明的时候初始化,须要显示的标注其类型 var currentNumberOfSt ...
- hdu 3874 Necklace(线段树)
这道题目和我之前做过的一道3xian大牛出的题目很像,不过总的来说还是要简单一点儿. 计算区间内的值的时候如果两个值相等,只能计算其中一个. 这道题需要将所有的问题输入之后再计算,首先,对所有问题的右 ...
- EasyUI - NumberBox组件
效果: html代码: <input type ="text" id ="box"/> JS代码: $(function () { $('#box' ...
- uva 10692 - Huge Mods(数论)
题目链接:uva 10692 - Huge Mods 题目大意:给出一个数的次方形式,就它模掉M的值. 解题思路:依据剩余系的性质,最后一定是行成周期的,所以就有ab=abmod(phi[M])+ph ...
- oracle表连接------>排序合并连接(Merge Sort Join)
排序合并连接 (Sort Merge Join)是一种两个表在做连接时用排序操作(Sort)和合并操作(Merge)来得到连接结果集的连接方法. 对于排序合并连接的优缺点及适用场景例如以下: a,通常 ...
- Oracle Tablespace Transportation
前提:进行表空间传输需要用户有SYSDBA的系统权限,被移动的表空间是自包含的表空间,不应有依赖于表空间外部对象的对象存在.确定是否自包含可使用系统包DBMS_TTS中的TRANSPORT_SET_C ...
- dwz框架---(2)表单回调函数
dwz中的表单回调函数大概有下面几种: /** * 普通ajax表单提交 * @param {Object} form * @param {Object} callback * @param {Str ...
- mysql高可用架构方案之二(keepalived+lvs+读写分离+负载均衡)
mysql主从复制与lvs+keepalived实现负载高可用 文件夹 1.前言 4 2.原理 4 2.1.概要介绍 4 2.2.工作原理 4 2.3.实际作用 4 3方 ...
- 【Unity3D自学记录】Unity3D网络之Socket聊天室初探
首先创建一个服务端程序,这个程序就用VS的控制台程序做即可了. 代码例如以下: using System; using System.Collections.Generic; using System ...
- 关于ListCtrol自绘的技巧
一.给控件添加排序功能report风格的list控件很多情况下都需要支持排序功能,而且最好支持按不同列进行排序.CListCtrl的类方法SortItems支持排序功能,但是在排序过程中,两个数据真正 ...