计算几何 三点求最小圆

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<string>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<list>
#include<map>
#include<set>
using namespace std;
const double eps=1e-10;

inline int sign(const double &x){
  if(x>eps) return 1;
  else if(x<-eps) return -1;
  else return 0;
}
struct point{
   double x,y;
   point(double x=0,double y=0):x(x),y(y){}
   void init(){
      scanf("%lf%lf",&x,&y);
   }
   point operator - (const point &a) const{
    return point(x-a.x, y-a.y);
   }
   point operator + (const point &a) const{
    return point(x+a.x, y+a.y);
   }
   point operator * (const double a) const{
     return point(x*a, y*a);
   }
   point operator / (const double a) const{
      return point(x/a, y/a);
   }
   double operator ^ (const point &a) const{
     return x*a.y - y*a.x;
   }
};

inline double dob(const double &x){
    return x*x;
}
inline double mul(const point &p0,const point &p1,const point &p2){
   return (p1-p0) ^ (p2-p0);
}
inline double dis2(const point &st,const point &ed){
   return dob(st.x-ed.x) + dob(st.y-ed.y);
}
inline double dis(const point &st,const point &ed){
   return sqrt(dis2(st,ed));
}
//struct straightline{
//   double A,B,C;
//   straightline(double a=0,double b=0,double c=0):A(a),B(b),C(C){}
//   point cross(const straightline &p) const{
//      double xx= -(C*p.B - p.C*B)/(A*p.B - B*p.A);
//      double yy= -(C*p.A - p.C*A)/(B*p.A - A*p.B);
//      return point(xx,yy);
//   }
//};
 struct straightline{
     double A,B,C;
     straightline(double a=0,double b=0,double c=0):A(a),B(b),C(c){}
     point cross(const straightline &pp) const{
         double xx= -(C * pp.B - pp.C * B)/(A * pp.B - B * pp.A);
         double yy= -(C * pp.A - pp.C * A)/(B * pp.A - A * pp.B);
         return point(xx,yy);
     }
 };
inline void circumcenter(const point &p1,const point &p2,const point &p3,point &center,double &dia){
   center=p1+straightline(p3.x-p1.x, p3.y-p1.y, -dis2(p3,p1)/2.0).cross(straightline(p2.x-p1.x, p2.y-p1.y, -dis2(p2,p1)/2.0));
   dia=dis(center,p1);
}

inline bool IsIncircum(const point &x,const point &center,const double &dia){
   double tp=dis2(x,center);  //点到圆心距离;
   if(sign(tp-dob(dia))<=0) return 1;
   else return 0;
}
inline void TwoPointMid(const point &st,const point &ed,point &center,double &dia){
   dia=dis(st,ed)/2.0;
   center=st+(st-ed)/2.0;
}
void work(const point &a,const point &b,const point &c,point &center,double &dia){
    double tmp;
    point newcenter;
    TwoPointMid(a,b,newcenter,tmp);
    if(IsIncircum(c,newcenter,tmp)&&tmp<dia){
        dia=tmp;center=newcenter;
    }
}
void getRoundness(point x,point y,point z,point &center,double &dia){
   circumcenter(x,y,z,center,dia);
//           printf("pre center: %lf,%lf,,dia=%lf\n",center.x,center.y,dia);

   work(x,y,z,center,dia);
   work(y,z,x,center,dia);
   work(z,x,y,center,dia);
}

int main()
{

//     freopen("in.in","r",stdin);
     int T;
     scanf("%d",&T);
     point x,y,z,center;
     double dia;
     while(T--){
        x.init();
        y.init();
        z.init();
        getRoundness(x,y,z,center,dia);
        printf("center: %lf,%lf,,dia=%lf\n",center.x,center.y,dia);

     }

     return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值