CGL_7_F: Tangent to a Circle

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F
円外の一点を通る円の接線の接点を求める問題。
相変わらずデカルト座標で解いているので場合わけが必要。
レベルが低い解き方だがなぜかC++で2番目に短いコードになっている。


#include<stdio.h>
#include<algorithm>
#include<math.h>
struct E{
   double x,y;
   bool operator<(const E& e1)const{
       if(x!=e1.x)return x<e1.x;
       return y<e1.y;
   }
};

int main(){
   double x2,y2,cx,cy,r;
   double a,b,c,d;
   E ans[2];
   scanf("%lf %lf %lf %lf %lf",&x2,&y2,&cx,&cy,&r);
   x2-=cx;
   y2-=cy;
   if(y2!=0){
       a=y2*y2+x2*x2;
       b=-2*r*r*x2;
       c=r*r*r*r-r*r*y2*y2;
       d=b*b-4*a*c;
       if(d<0)d=0;
       ans[0].x=(-b-sqrt(d))/(2*a);
       ans[1].x=(-b+sqrt(d))/(2*a);
       ans[0].y=(r*r-ans[0].x*x2)/y2;
       ans[1].y=(r*r-ans[1].x*x2)/y2;
   }else{
       a=y2*y2+x2*x2;
       b=-2*r*r*y2;
       c=r*r*r*r-r*r*x2*x2;
       d=b*b-4*a*c;
       if(d<0)d=0;
       ans[0].y=(-b-sqrt(d))/(2*a);
       ans[1].y=(-b+sqrt(d))/(2*a);
       ans[0].x=(r*r-ans[0].y*y2)/x2;
       ans[1].x=(r*r-ans[1].y*y2)/x2;
   }
    
   //printf("%lf %lf\n%lf %lf\n",ans[0].x,ans[0].y,ans[1].x,ans[1].y);
   ans[0].x+=cx;
   ans[0].y+=cy;
   ans[1].x+=cx;
   ans[1].y+=cy;
   std::sort(ans,ans+2);
   printf("%.8lf %.8lf\n%.8lf %.8lf\n",ans[0].x,ans[0].y,ans[1].x,ans[1].y);
}
最終更新:2016年11月08日 19:00