首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【UVALive 4642】Malfatti Circles(圆,二分)

【UVALive 4642】Malfatti Circles(圆,二分)

作者头像
饶文津
发布2020-06-02 15:48:38
发布2020-06-02 15:48:38
3480
举报
文章被收录于专栏:饶文津的专栏饶文津的专栏

给定三角形,求三个两两相切且与三角形的一条边相切的圆的半径。

二分一个半径,可以得出另外两个半径,需要推一推公式(太久了,我忘记了)

代码语言:javascript
复制
#include<cstdio>
#include<cmath>
#define eps (1e-8)
#define sqr(a) (a)*(a)
#define min(a,b) (a)>(b)?(b):(a)
#define dd double
struct point{
    dd x,y,v,a;//点x,y,v为角度,a为边长
}q[10];
dd r0,r1,r2,r3;
int read(){
    int f=0;
    for(int i=0;i<3;i++){
        scanf("%lf%lf",&q[i].x,&q[i].y);
        if(q[i].x||q[i].y) f=1;
    }
    return f;
}
dd make(dd r,dd a,dd h,dd n){
    dd t=r-r/tan(h)/tan(n)+a/tan(n);
    if(t<=eps)return -1;
    return sqr((sqrt(t)-sqrt(r))*tan(n));
}
void solve(){
    dd l=0,r=min(q[0].a*tan(q[0].v),q[2].a*tan(q[2].v));
    while(r-l>eps){
        r0=(l+r)/2;
        r1=make(r0,q[0].a,q[0].v,q[1].v);
        r2=make(r0,q[2].a,q[0].v,q[2].v);
        if(r1<=eps||r2<=eps||r2/tan(q[2].v)+r1/tan(q[1].v)+2*sqrt(r2*r1)-q[1].a<eps)
            r=r0;
        else
            l=r0;
    }
}
int main(){
    while(read())
    {
        for(int i=0;i<3;i++)
            q[i].a=sqrt(sqr(q[(i+1)%3].x-q[i].x)+sqr(q[(i+1)%3].y-q[i].y));//计算边长
        for(int i=0;i<3;i++)
            q[i].v=acos((sqr(q[i].a)+sqr(q[(i+2)%3].a)-sqr(q[(i+1)%3].a))/2/q[i].a/q[(i+2)%3].a)/2;
        solve();
        printf("%lf %lf %lf\n",r0,r1,r2);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-07-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

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