【UVALive 4642】Malfatti Circles(圆,二分)
给定三角形,求三个两两相切且与三角形的一条边相切的圆的半径。
二分一个半径,可以得出另外两个半径,需要推一推公式(太久了,我忘记了)
#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); } }
┆凉┆暖┆降┆等┆幸┆我┆我┆里┆将┆ ┆可┆有┆谦┆戮┆那┆ ┆大┆始┆ ┆然┆
┆薄┆一┆临┆你┆的┆还┆没┆ ┆来┆ ┆是┆来┆逊┆没┆些┆ ┆雁┆终┆ ┆而┆
┆ ┆暖┆ ┆如┆地┆站┆有┆ ┆也┆ ┆我┆ ┆的┆有┆精┆ ┆也┆没┆ ┆你┆
┆ ┆这┆ ┆试┆方┆在┆逃┆ ┆会┆ ┆在┆ ┆清┆来┆准┆ ┆没┆有┆ ┆没┆
┆ ┆生┆ ┆探┆ ┆最┆避┆ ┆在┆ ┆这┆ ┆晨┆ ┆的┆ ┆有┆来┆ ┆有┆
┆ ┆之┆ ┆般┆ ┆不┆ ┆ ┆这┆ ┆里┆ ┆没┆ ┆杀┆ ┆来┆ ┆ ┆来┆