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 ...
随机推荐
- symfony中twig的模板变量与注释
程序会传递给模板若干变量,你需要在模板里输出他们.例如输出$hello .1{{ hello }}.如果传递给模板的是对象或者数组,你可以使用点. 来输出对象的属性或者方法,或者数组的成员.或者你可以 ...
- awk 手册--【转载】
1. 前言 有关本手册 : 这是一本awk学习指引, 其重点着重于 : l awk 适于解决哪些问题 ? l awk 常见的解题模式为何 ? 为使读者快速掌握awk解 ...
- Houdini Krakatoa Render Plugin
HDK真实个混蛋,都懒得写个解释.凭着函数英文意思猜测.. plugin sample video: 在极其残忍的开发环境,"Particle Voxel Render" 产生了( ...
- 20145227《Java程序设计》第10周学习总结
20145227<Java程序设计>第10周学习总结 教材学习内容总结 网络编程 就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收 ...
- MySQL数据类型总结
MySQL中的数据类型大的方面来分,可以分为:日期和时间.数值,以及字符串.下面就分开来进行总结. 日期和时间数据类型 MySQL数据类型 含义 date 3字节,日期,格式:2014-09-18 t ...
- ACM题目————列变位法解密
这是在百度之星看到的. Problem Description 列变位法是古典密码算法中变位加密的一种方法,具体过程如下 将明文字符分割成个数固定的分组(如5个一组,5即为密钥),按一组一行的次序整齐 ...
- c# 遍历子控件,比如Form下的group,或者panel
方法很好用.目的是遍历所有容器的子控件... 方法1private void GetControl(Control.ControlCollection ctc, ref int checkNull) ...
- PHP之验证码类
<?php /** * Created by PhpStorm. * User: Administrator * Date: 2016/6/20 * Time: 14:29 */ Class c ...
- WebForm 发送邮箱
首先在设置发件邮箱的SMTP服务,以新浪邮箱为例:设置区----客户端pop/imap/smtp----"POP3/SMTP服务"和"IMAP4服务/SMTP服务&quo ...
- flash视频器播放器代码
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...