前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HDU 6354--Everything Has Changed(判断两圆关系+弧长计算)

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

作者头像
Enterprise_
发布2019-03-01 09:33:44
3690
发布2019-03-01 09:33:44
举报
文章被收录于专栏:小L的魔法馆小L的魔法馆
  • 题目
  • 题意:首先给定一个以原点为圆心,R为半径的圆,之后在给m个圆,这些圆可能会和原来的圆有所交集,计算开始的圆剩余区域的周长,不包括内部周长。
  • 首先判定两圆关系,如果内含,直接加上圆的周长,如果相交,在计算对应弧长,其他情况都不用计算。在计算圆心角的时候,有个精度问题,只用本身半径算出来的弧度会不够,所有用上两个圆的半径。
代码语言:javascript
复制
#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\n",ans);
    }
    return 0;
}
本文参与?腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年08月06日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体同步曝光计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com