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 ...
随机推荐
- springMVC配置freemarker
这里呢,我首先来说明一下写该篇的目的. 我最近要用到freemarker因此研究了一下这个东西. 先来说说如何配置吧. 1.jar包.地址见下链接. http://pan.baidu.com/s/1j ...
- javaWEB小练习:在数据库中查找相同的username和password
/*练习题: * 在Mysql数据库中创建一个person数据表,添加三个字段,id,user,password,并录入几条记录 * *练习题:定义一个login.html,里面定义了两个请求字段:u ...
- hdu4727 The Number Off of FFF
理解错题意,wa了几次. 我一开始的理解忽略了实际背景,认为错报是绝对的,不依赖于其左边的人. 而实际上某士兵报数的对错取决且仅取决于他所报的数与其左邻所报的数. 所以假设第一个人没有报错,则其后必有 ...
- Unity-Animator深入系列---状态机面板深入
回到 Animator深入系列总目录 本篇不讲解所有的面板功能,只是针对一些非常用功能进行介绍. 1.状态 1.1状态简介 简单的不做介绍了,需要特别注意: 1.Paramter勾选后可以指定参数控制 ...
- Apache Common-pool2对象池分析和应用
Apache Common-pool2包提供了一个通用的对象池技术的实现.可以很方便的基于它来实现自己的对象池,比如DBCP和Jedis他们的内部对象池的实现就是依赖于Common-pool2. 对象 ...
- AIM Tech Round 3 (Div. 2) A
Description Kolya is going to make fresh orange juice. He has n oranges of sizes a1, a2, ..., an. Ko ...
- c++のdll两种调用方式
调用DLL有两种方法:静态调用和动态调用. (一).静态调用其步骤如下: 1.把你的youApp.DLL拷到你目标工程(需调用youApp.DLL的工程)的Debug目录下; 2.把你的youApp. ...
- WebForm分页浏览
1.封装类 //封装类 using System; using System.Collections.Generic; using System.Web; /// <summary> // ...
- xcode下编译.a文件的路径
http://www.it165.net/pro/html/201503/36842.html 每当我们编译之后, 实际上系统就给我编译好了一个可以运行的.app文件,在某个路径下 如果我们建立的是静 ...
- web打印
实现方法 引用jquery和,jqprint到您的页面 <script language="javascript" src="jquery-1.4.4.min.js ...