poj2986A Triangle and a Circle&&poj3675Telescope(三角形剖分)
2986是3675的简化版,只有一个三角形。
这题主要在于求剖分后三角形与圆的相交面积,需要分情况讨论。
具体可以看此博客 http://hi.baidu.com/billdu/item/703ad4e15d819db52f140b0b
在分析第3、4两种情况时,我是用角度来进行判断的,如果<obc||<ocb大于90度就为他所说的第四种情况,不然就是第三种情况。
还有对于sig的解释貌似网上都没写,可能都觉得太简单了。。。自己手画了一下,大体是这个样子的
红色标记那块三角形是需要减掉对于当前多边形,可以看出以最下角进行剖分三角形时,cross(b,c)算的那块小三角形的确是负的,所以需要判断一下当前的面积是要加上的还是要减掉的。
讨论的东西比较多,细节比较多,WA了好多遍,对着数据查了好久终于过了。。
附上一些数据
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 100
#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];
struct tri
{
point a,b,c;
} tr[N];
typedef point pointt;
point operator -(point a,point b)
{
return point(a.x-b.x,a.y-b.y);
}
point operator *(point a,double r)
{
return point(a.x*r,a.y*r);
}
point operator +(point a,point b)
{
return point(a.x+b.x,a.y+b.y);
}
struct line
{
point u,v;
point ppoint(double t)
{
return point(u+v*t);
}
};
struct circle
{
point c;
double r;
circle(point c,double r):c(c),r(r) {}
point ppoint(double a)
{
return point(c.x+cos(a)*r,c.y+sin(a)*r);
}
};
double r;
point ip;
double dcmp(double x)
{
if(fabs(x)<eps) return ;
return x<?-:;
}
double dis(point a)
{
return sqrt(a.x*a.x+a.y*a.y);
}
double dot(point a,point b)
{
return a.x*b.x+a.y*b.y;
}
double cross(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
double area(point a,point b,point c)
{
return fabs(cross(a-c,b-c))/;
} int getlinecircle(line ll,circle cc,point &p1,point &p2)
{
double a = ll.v.x,b = ll.u.x-cc.c.x,c = ll.v.y,d = ll.u.y-cc.c.y;
double e = a*a+c*c,f = *(a*b+c*d),g = b*b+d*d-cc.r*cc.r;
double delta = f*f-*e*g;
double t1,t2;
if(dcmp(delta)<)return ;//ÏàÀë
if(dcmp(delta)==)
{
t1 = t2 = -f/(*e);//cout<<t1<<" -"<<e<<" "<<f<<endl;
p1 = ll.ppoint(t1);
return ;//ÏàÇÐ
}
//Ïཻ
t1 = (-f-sqrt(delta))/(*e);
p1 = ll.ppoint(t1);
t2 = (-f+sqrt(delta))/(*e);
p2 = ll.ppoint(t2);
// cout<<p1.x<<" "<<p1.y<<" "<<p2.x<<" "<<p2.y<<endl;
return ;
}
double mul(point a,point b,point c)
{
return cross(b-a,c-a);
}
bool cmp(point a,point b)
{
if(dcmp(mul(ip,a,b))==)
return dis(a-ip)<dis(b-ip);
else
return dcmp(mul(ip,a,b))>;
}
double distancetoline(point p,point a,point b)
{
point v1 = a-b,v2 = p-b;
return fabs(cross(v1,v2))/dis(v1);
}
int dot_online_in(point p,point l1,point l2)
{
return !dcmp(mul(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;
}
double angle(point a,point b)
{
return acos(dot(a,b)/dis(a)/dis(b));
}
double cal(tri tr)
{
circle cp=circle(point(,),r);
int sig = dcmp(cross(tr.b,tr.c));
if(sig==) return ;
double d1 = dis(tr.a-tr.b),d2 = dis(tr.a-tr.c);
if(dcmp(d1-r)<=&&dcmp(d2-r)<=)
{
double s = sig*area(tr.a,tr.b,tr.c);
return s;
}
double dline = distancetoline(cp.c,tr.b,tr.c);
if(dcmp(d1-r)>=&&dcmp(d2-r)>=&&dcmp(dline-r)>=)
{
return sig*angle(tr.b,tr.c)*r*r/2.0;
}
double ag = angle(tr.c-tr.b,tr.a-tr.b),bg = angle(tr.b-tr.c,tr.a-tr.c);
point p1,p2;
line l1;
l1.u = tr.b,l1.v = tr.c-tr.b;
getlinecircle(l1,cp,p1,p2); if(dcmp(d1-r)>=&&dcmp(d2-r)>=&&dcmp(dline-r)<&&(dcmp(ag-pi/)>=||dcmp(bg-pi/)>=))
{ double s = sig*angle(tr.b,tr.c)*r*r/;
return s;
}
if(dcmp(d1-r)>=&&dcmp(d2-r)>=&&dcmp(dline-r)<)
{
double s = (angle(tr.b,tr.c)-angle(p1,p2))*r*r/2.0+area(tr.a,p1,p2);
return sig*s;
} p1 = dot_online_in(p1,tr.b,tr.c)?p1:p2;
if(dcmp(d1-r)<)
{
return sig*(angle(tr.c,p1)*r*r/+area(tr.a,p1,tr.b));
}
else
{
return sig*(angle(p1,tr.b)*r*r/+area(tr.a,p1,tr.c));
}
}
int dots_inline(point p1,point p2,point p3)
{
return !dcmp(mul(p1,p2,p3));
}
int main()
{
int i,n;
while(scanf("%lf",&r)!=EOF)
{
scanf("%d",&n);
for(i = ; i < n ; i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
}
p[n] = p[];
double ans = ;
for(i = ; i < n ; i++)
{
if(dots_inline(ip,p[i],p[i+])) continue;
tr[i].a = point(,);
tr[i].b = p[i];
tr[i].c = p[i+];
ans+=cal(tr[i]);
}
printf("%.2f\n",fabs(ans)+eps);
}
return ;
}
589.00 191.00 -554.00 710.00 748.00 774.00 -888.00 -588.00 902.00
201.00 -847.00 -365.00 886.00 -557.00 -609.00 272.00 -345.00 189.00
-358.00 981.00 269.00 511.00 158.00 -304.00 468.00 463.00 834.00
969.00 514.00 -445.00 460.00 -177.00 774.00 -34.00 -125.00 162.00
-467.00 413.00 -714.00 -986.00 362.00 666.00 813.00 271.00 264.00
-497.00 908.00 -414.00 631.00 -220.00 868.00 166.00 -258.00 306.00
-107.00 -743.00 -952.00 322.00 -273.00 -214.00 -14.00 466.00 758.00
511.00 -416.00 -934.00 -745.00 -335.00 -132.00 -482.00 391.00 626.00
928.00 821.00 -293.00 -853.00 -488.00 -312.00 -27.00 94.00 361.00
-979.00 -280.00 791.00 -943.00 -300.00 -278.00 -821.00 684.00 365.00
-700.00 955.00 -315.00 154.00 -103.00 -606.00 404.00 -792.00 940.00
607.00 783.00 597.00 944.00 -672.00 -323.00 343.00 -799.00 526.00
815.00 -390.00 -291.00 37.00 422.00 687.00 672.00 613.00 848.00
-988.00 363.00 -529.00 660.00 -597.00 143.00 502.00 459.00 522.00
-206.00 484.00 109.00 -111.00 424.00 650.00 330.00 -545.00 480.00
94.00 -638.00 -59.00 -9.00 -400.00 -702.00 0.00 267.00 741.00
-859.00 522.00 109.00 -640.00 383.00 712.00 489.00 -663.00 635.00
808.00 -31.00 471.00 172.00 -374.00 21.00 120.00 -860.00 474.00
-539.00 -887.00 498.00 844.00 -453.00 -213.00 -479.00 -9.00 315.00
答案
Case 1
0.00
Case 2
0.00
Case 3
274955.27
Case 4
0.00
Case 5
0.00
Case 6
0.00
Case 7
25157.17
Case 8
9943.87
Case 9
181113.99
Case 10
0.00
Case 11
11846.16
Case 12
0.00
Case 13
404668.37
Case 14
0.00
Case 15
0.00
Case 16
74663.53
Case 17
80015.79
Case 18
0.00
Case 19
57316.85
Case 20
0.00
poj2986A Triangle and a Circle&&poj3675Telescope(三角形剖分)的更多相关文章
- POJ 2986 A Triangle and a Circle(三角形和圆形求交)
Description Given one triangle and one circle in the plane. Your task is to calculate the common are ...
- POJ 2986 A Triangle and a Circle 圆与三角形的公共面积
计算几何模板 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h& ...
- POJ 2986 A Triangle and a Circle
题意:给定一个三角形,以及一个圆的圆心坐标和半径,求圆和三角形的相交面积. 思路: 用三角剖分,三角形上每个线段都变成这个线段与圆心的三角形,然后算出每个三角形与圆的相交面积,然后根据有向面积的正负累 ...
- ACM计算几何题目推荐
//第一期 计算几何题的特点与做题要领: 1.大部分不会很难,少部分题目思路很巧妙 2.做计算几何题目,模板很重要,模板必须高度可靠. 3.要注意代码的组织,因为计算几何的题目很容易上两百行代码,里面 ...
- PHP面向对象实例(图形计算器)
效果:
- 对C++虚函数、虚函数表的简单理解
一.虚函数的作用 以一个通用的图形类来了解虚函数的定义,代码如下: #include "stdafx.h" #include <iostream> using name ...
- UVa 11524:In-Circle(解析几何)
Problem EIn-CircleInput: Standard Input Output: Standard Output In-circle of a triangle is the circl ...
- zoj 1010 (线段相交判断+多边形求面积)
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=10 Area Time Limit: 2 Seconds Mem ...
- S1:new操作符
function Shape(type){ this.type = type || "rect"; this.calc = function(){ return "cal ...
随机推荐
- Python学习总结:目录
Python 3.x总结 Python学习总结[第一篇]:Python简介及入门 Python学习总结[第二篇]:Python数据结构 Python学习总结[第三篇]:Python之函数(自定义函数. ...
- ectouch第七讲 之ECshop模板机制整理
网上的资源感觉还是有些用,可以看看,帮助理解,ECshop模板机制整理原文:http://blog.sina.com.cn/s/blog_6900af430100nkn8.html 一.模板引擎: E ...
- HDU 4635:Strongly connected(强连通)
http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给出n个点和m条边,问最多能添加几条边使得图不是一个强连通图.如果一开始强连通就-1.思路:把图分成 ...
- 《深度探索C++对象模型》2
第四章: function语意学 非静态成员函数: 名称的特殊处理: 静态成员函数由于缺乏this指针,因此差不多等于非成员函数: virtual table布局(单一继承): 单一继承下函数调用: ...
- [ios]iOS 图形编程总结
转自:http://www.cocoachina.com/ios/20141104/10124.html iOS实现图形编程可以使用三种API(UIKIT.Core Graphics.OpenGL E ...
- jQuery 禁用退格键
在只读区域按退格键会造成页面后退,禁用退格键可以这样做: $(document).bind("keydown", function(e){ if(e.keyCode == 8){/ ...
- MVC模式:实现数据库中数据的增删改查功能
*.数据库连接池c3p0,连接mysql数据库: *.Jquery使用,删除时跳出框,确定是否要删除: *.使用EL和JSTL,简化在jsp页面中插入的java语言 1.连接数据库 (1)导入连接数据 ...
- 20150602_Andriod 向窗体传递参数
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:too ...
- nylg 640 Geometric Sum
Geometric Sum 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 Compute (a + a^2 + … + a^n) mod m.(a+a2+…an)m ...
- 2016年10月28日 星期五 --出埃及记 Exodus 19:13
2016年10月28日 星期五 --出埃及记 Exodus 19:13 He shall surely be stoned or shot with arrows; not a hand is to ...