POJ3675 Telescope 圆和多边形的交

POJ3675

用三角剖分可以轻松搞定,数据也小 随便AC。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const double eps=1e-10,PI=acos(-1.0);

int cmp(double k)
{
 return k<-eps ? -1:k>eps ? 1:0;
}

const double pi=acos(-1.0);

inline double sqr(double x)
{
 return x*x;
}

struct point
{
 double x,y;
 point (){}
 point (double a,double b):x(a),y(b){}
 bool input()
 	{
 	 return scanf("%lf%lf",&x,&y)!=EOF;
	}
 friend point operator +(const point &a,const point &b)
 	{
 	 return point(a.x+b.x,a.y+b.y);
	}
 friend point operator -(const point &a,const point &b)
 	{
 	 return point(a.x-b.x,a.y-b.y);
	}
 friend bool operator ==(const point &a,const point &b)
 	{
 	 return cmp(a.x-b.x)==0&&cmp(a.y-b.y)==0;
	}
 friend point operator *(const point &a,const double &b)
 	{
 	 return point(a.x*b,a.y*b);
	}
 friend point operator*(const double &a,const point &b)
 	{
 	 return point(a*b.x,a*b.y);
	}
 friend point operator /(const point &a,const double &b)
 	{
 	 return point(a.x/b,a.y/b);
	}
 double norm()
 	{
 	 return sqr(x)+sqr(y);
	}
};

double mysqrt(double x)
{
 return sqrt(x);
}
double dot(const point &a,const point &b)
{
 return a.x*b.x+a.y*b.y;
}
double cross(const point &a,const point &b)
{
 return a.x*b.y-a.y*b.x;
}
double abs(const point &o)
{
 return sqrt(dot(o,o));
}
void circle_cross_line(point a,point b,point o,double r,point ret[],int &num)
{
 double x0=o.x,y0=o.y;
 double x1=a.x,y1=a.y;
 double x2=b.x,y2=b.y;
 double dx=x2-x1,dy=y2-y1;
 double A=dx*dx+dy*dy;
 double B=2*dx*(x1-x0)+2*dy*(y1-y0);
 double C=sqr(x1-x0)+sqr(y1-y0)-sqr(r);
 double delta=B*B-4*A*C;
 num=0;
 if(cmp(delta)>=0)
 	{
 	 double t1=(-B-mysqrt(delta))/(2*A);
 	 double t2=(-B+mysqrt(delta))/(2*A);
 	 if(cmp(t1-1)<=0&&cmp(t1)>=0)
 	 	{
 	 	 ret[num++]=point(x1+t1*dx,y1+t1*dy);
		}
	 if(cmp(t2-1)<=0&&cmp(t2)>=0)
 	 	{
 	 	 ret[num++]=point(x1+t2*dx,y1+t2*dy);
		}
	}
}

point crosspt(const point &a,const point &b,const point &p,const point &q)
{
 double a1=cross(b-a,p-a);
 double a2=cross(b-a,q-a);
 return (p*a2-q*a1)/(a2-a1);
}

double sector_area(const point &a,const point &b,const double r)
{
 double theta=atan2(a.y,a.x)-atan2(b.y,b.x);
 while(cmp(theta)<=0)theta+=2*PI;
 while(cmp(theta-2*PI)>0)theta-=2*PI;
 theta=min(theta,2*PI-theta);
 return r*r*theta/2.;
}

double calc_c(const point &a,const point &b,const double r)
{
 point p[2];
 int num=0;
 bool ina=cmp(abs(a)-r)<0;
 bool inb=cmp(abs(b)-r)<0;
 if(ina)
 	{
 	 if(inb)return fabs(cross(a,b))/2.;
 	 	else
 	 		{
 	 		 circle_cross_line(a,b,point(0,0),r,p,num);
 	 		 return fabs(sector_area(b,p[0],r))+fabs(cross(a,p[0]))/2.;
			}
	}
		else
			{
			 if(inb)
			 	{
			 	 circle_cross_line(a,b,point(0,0),r,p,num);
 	 		 			return fabs(sector_area(p[0],a,r))+fabs(cross(p[0],b))/2.;
				}
				else
					{
					 circle_cross_line(a,b,point(0,0),r,p,num);
					 if(num==2)
					 	{
					 	 return fabs(sector_area(a,p[0],r))+fabs(sector_area(p[1],b,r))+fabs(cross(p[0],p[1]))/2.;

						}else
							{
							 return fabs(sector_area(a,b,r));
							}
					}
			}
}

double area(int n,point res[],double r)
{
 double ret=0.;
 for(int i=0;i<n;i++)
 	{
 	 int sgn=cmp(cross(res[i],res[(i+1)%n]));
	 if(sgn!=0)
	 	{
	 	 ret+=sgn*calc_c(res[i],res[(i+1)%n],r);
		}
	}
 return ret;
}
point pp[100];
int main()
{freopen("t.txt","r",stdin);
 double r;
 int n;
 while(scanf("%lf",&r)!=EOF)
 {

 scanf("%d",&n);
 for(int i=0;i<n;i++)
 	pp[i].input();
 pp[n]=pp[0];
 printf("%.2f\n",fabs(area(n,pp,r))+eps);
}
 return 0;
}

  

时间: 2024-08-05 23:39:49

POJ3675 Telescope 圆和多边形的交的相关文章

HDU 3982 半平面交+圆与多边形面积交

Harry Potter and J.K.Rowling Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 685    Accepted Submission(s): 210 Problem Description In July 31st, last month, the author of the famous novel seri

Gym - 101208J 2013 ACM-ICPC World Finals J.Pollution Solution 圆与多边形面积交

题面 题意:给你一个半圆,和另一个多边形(可凹可凸),求面积交 题解:直接上板子,因为其实这个多边形不会穿过这个半圆,所以他和圆的交也就是和半圆的交 打的时候队友说凹的不行,不是板题,后面想想,圆与多边形面积交本来就是拆成有向三角形做的,所以无论凹凸了 1 #include<bits/stdc++.h> 2 #define inf 1000000000000 3 #define M 100009 4 #define eps 1e-12 5 #define PI acos(-1.0) 6 usi

圆和多边形面积交模板

hdu5130 //#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loop

POJ3675 Telescope(计算几何)

题意:求一个圆心在原点,半径r的圆和多边形的面积的交 思路:利用三角剖分,这题主要就是验证下模板 代码: #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<algorithm> const double eps = 1e-8; const double pi = acos(-1.0); int dcmp(double x) { if(

[NetTopologySuite](2)任意多边形求交

任意多边形求交: private void btnPolygon_Click(object sender, EventArgs e) { double[] Xs = new double[] { 30, 260, 130, 350, 250, 330, 320, 180, 250, 50, 70, 60, 30, 260 }; double[] Ys = new double[] { 140, 260, 110, 150, 230, 210, 140, 260 }; int m = Xs.Len

OpenCASCADE圆与平面求交

OpenCASCADE圆与平面求交 [email protected] 在 解析几何求交之圆与二次曲面中分析了OpenCASCADE提供的类IntAna_IntConicQuad可以用来计算圆与二次曲面之间的交点,这个算法是将平面Plane作为二次曲面的一个特例来处理,最后主要是对三角函数方程进行求解. 当直接使用圆和平面作为参数时,IntAna_IntConicQuad重载了函数Perform来对圆和平面进行求交计算,这时的算法与前面解三角函数不同,代码如下: void IntAna_IntC

A Round Peg in a Ground Hole - POJ 1584 (判断凸多边形&amp;判断点在多边形内&amp;判断圆在多边形内)

题目大意:首先给一个圆的半径和圆心,然后给一个多边形的所有点(多边形按照顺时针或者逆时针给的),求,这个多边形是否是凸多边形,如果是凸多边形在判断这个圆是否在这个凸多边形内. 分析:判断凸多边形可以使用相邻的三个点叉积判断,因为不知道顺时针还是逆时针,所以叉积如果有有整数和负数,那么一定不是凸多边形(注意允许多多点在一条线段上).判断圆在凸多边形首先要判断圆心是否在多边形内,如果在多边形内,再次判断圆心到达到变形每条边的最短距离,如果小于半径就是不合法.ps:一道好题,通过这个题学会了不少东西.

[hihoCoder1231 2015BeijingOnline]求圆与多边形公共部分的周长

题意:如题 思路:离散.如果多边形与圆交点小于2个则说明它们的关系是包含关系,然后判断是谁包含谁并得到答案,否则将所有交点求出来,相当于将多变形的边切成了很多条元边,对每条元边,有两种情况 在圆内,答案加上此边长 在圆外,答案加上此边相对于圆心的"有向转弧" #include <bits/stdc++.h> using namespace std; #ifndef ONLINE_JUDGE #include "local.h" #endif #defin

简单几何(圆与多边形公共面积) UVALive 7072 Signal Interference (14广州D)

题目传送门 题意:一个多边形,A点和B点,满足PB <= k * PA的P的范围与多边形的公共面积. 分析:这是个阿波罗尼斯圆.既然是圆,那么设圆的一般方程:(x + D/2) ^ 2 + (y + E/2) ^ 2 = (D ^ 2 + E ^ 2 - 4 * F)  / 4,通过PB == PA * k解方程来求解圆心以及半径.然后就是套模板啦,上海交大的红书. /************************************************ * Author :Runni