HDU 6354--Everything Has Changed(判断两圆关系+弧长计算)

  • 题目
  • 题意:首先给定一个以原点为圆心,R为半径的圆,之后在给m个圆,这些圆可能会和原来的圆有所交集,计算开始的圆剩余区域的周长,不包括内部周长。
  • 首先判定两圆关系,如果内含,直接加上圆的周长,如果相交,在计算对应弧长,其他情况都不用计算。在计算圆心角的时候,有个精度问题,只用本身半径算出来的弧度会不够,所有用上两个圆的半径。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const double PI = acos(-1.0);
typedef struct point {
	double x;
	double y;
	point() {

	}
	point(double a, double b) {
		x = a;
		y = b;
	}
	point operator -(const point &b)const {		//返回减去后的新点
		return point(x - b.x, y - b.y);
	}
	point operator +(const point &b)const {		//返回加上后的新点
		return point(x + b.x, y + b.y);
	}
	//数乘计算
	point operator *(const double &k)const {	//返回相乘后的新点
		return point(x * k, y * k);
	}
	point operator /(const double &k)const {	//返回相除后的新点
		return point(x / k, y / k);
	}
	double operator ^(const point &b)const {	//叉乘
		return x*b.y - y*b.x;
	}
	double operator *(const point &b)const {	//点乘
		return x*b.x + y*b.y;
	}
	double len() {		//返回直角三角形的斜边长
		return hypot(x, y);
	}
}point;
typedef struct circle {//圆
	double r;
	point centre;
	circle() {

	}
	circle(point a,double b) {
		centre = a;
		r = b;
	}
	double len() {
		return 2 * PI*r;
	}
	double area() {
		return PI*r*r;
	}
}circle;
circle	org;
double ans, r;
int t, m;
double dist(point p1, point p2) {		//返回平面上两点距离
	return sqrt((p1 - p2)*(p1 - p2));
}
int CircleInterNum(circle a, circle b) {
	double fh = fabs(a.r + b.r), fc = fabs(a.r - b.r), d = dist(a.centre, b.centre);
	if (d>fh)
		return -2;	//外离,没有交点
	if (d==fh)
		return -1;	//外切,一个交点
	if (d > fc&&d < fh)
		return 0;	//相交,两个交点
	if (d == fc)
		return 1;	//内切,一个交点
	if (d < fc&&d>=0)
		return 2;	//内含,没有交点
}

void CircleIntteLen(circle a, circle b) {
	double d = dist(a.centre, b.centre);
	double t = (d*d + a.r*a.r - b.r*b.r) / (2.0 * d);
	double h = sqrt((a.r*a.r) - (t*t))*2;
	double angle_a = 2*acos((a.r*a.r +d*d-b.r*b.r) / (2.0 * a.r*d));	//余弦公式计算圆心角,反三角计算出的是弧度
	double angle_b = 2*acos((b.r*b.r +d*d-a.r*a.r) / (2.0 * b.r*d));
	double la = angle_a*a.r;
	double lb = angle_b*b.r;
	ans += (lb-la);
}
int main(void) {
	cin >> t;
	while (t-- > 0) {
		org.centre = point(0, 0);
		cin >> m >> r;
		org.r = r;
		ans = org.len();
		double x, y, rt;
		for (int i = 0; i < m; i++) {
			cin >> x >> y >> rt;
			circle tmp = circle(point(x, y), rt);
			if (CircleInterNum(org, tmp) == 0)
				CircleIntteLen(org, tmp);
			if (CircleInterNum(org, tmp) == 1)
				ans += tmp.len();
		}
		printf("%.15f
",ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/FlyerBird/p/9431703.html