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的模板载入
模板 载入模板 {% include ‘sidebar.html’ %} 当前模板的变量也会传递到 被include的模板里,在那里面可以直接访问你这个模板的变量. {% for comment in ...
- Mongodb 和Redis 的相同点和不同点
MongoDB和Redis都是NoSQL,采用结构型数据存储.二者在使用场景中,存在一定的区别,这也主要由于二者在内存映射的处理过程,持久化的处理方法不同.MongoDB建议集群部署,更多的考虑到集群 ...
- Android网络通信之WiFi Direct
使用Wi-Fi Direct技术可以让具备硬件支持的设备在没有中间接入点的情况下进行直接互联.Android 4.0(API版本14)及以后的系统都提供了对Wi-Fi Direct的API支持.通过对 ...
- Pipe(点积叉积的应用POJ1039)
Pipe Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9723 Accepted: 2964 Description ...
- Pearls
Pearls Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7980 Accepted: 3966 Description In ...
- Black Box 分类: POJ 栈和队列 2015-08-05 14:07 2人阅读 评论(0) 收藏
Black Box Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8754 Accepted: 3599 Description ...
- 一些常用的SQL查询语句
学习网站:http://www.w3cschool.cc/sql/sql-tutorial.html 一:查询所有表的属性 SELECT 'ALTER TABLE '+ CASE WHEN O.sch ...
- httpclient4.3.6/httpcore-4.4自己封装的工具类
引入jar包 httpclient4.3.6/httpcore-4.4 package com.develop.util; import java.io.IOException; import jav ...
- Android中直播视频技术探究之---视频直播服务端环境搭建(Nginx+RTMP)
一.前言 前面介绍了Android中视频直播中的一个重要类ByteBuffer,不了解的同学可以 点击查看 到这里开始,我们开始动手开发了,因为我们后续肯定是需要直播视频功能,然后把视频推流到服务端, ...
- 编译android源码官方教程(4)开始编译
Preparing to Build IN THIS DOCUMENT Obtain proprietary binaries Download proprietary binaries Extrac ...