求一個三角形的最小圓覆蓋
兩種情況:
1. 是銳角及直角三角形, 那麼這個圓就是外接圓
2. 是鈍角三角形, 那麼這個圓的直徑是這個最長邊的中點
double getDis(Point a, Point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
///////////////////////////////////////////
//求三角形外接圓圓心座標 及半徑
///////////////////////////////////////////
void circle_center(Point ¢er,Point pt[3],double &radiu) //參數是圓心和半徑的引用
{
double x1,x2,x3,y1,y2,y3;
double x = 0;
double y = 0;
x1 = pt[0].x;
x2 = pt[1].x;
x3 = pt[2].x;
y1 = pt[0].y;
y2 = pt[1].y;
y3 = pt[2].y;
x=((y2-y1)*(y3*y3-y1*y1+x3*x3-x1*x1)-(y3-y1)*(y2*y2-y1*y1+x2*x2-x1*x1))/(2*(x3-x1)*(y2-y1)-2*((x2-x1)*(y3-y1)));
y=((x2-x1)*(x3*x3-x1*x1+y3*y3-y1*y1)-(x3-x1)*(x2*x2-x1*x1+y2*y2-y1*y1))/(2*(y3-y1)*(x2-x1)-2*((y2-y1)*(x3-x1)));
center.x = x ;
center.y = y ;
radiu = sqrt((pt[0].x - x)*(pt[0].x - x) + (pt[0].y - y)*(pt[0].y - y));
}
bool judgeDunJiao(Point pt[3], Point ¢er, double &r) //判斷是否是鈍角, 參數是引用
{
double c = getDis(pt[0], pt[1]);
double b = getDis(pt[0], pt[2]);
double a = getDis(pt[1], pt[2]);
if(a * a > b * b + c * c)
{
center.x = (pt[1].x + pt[2].x) / 2.0;
center.y = (pt[1].y + pt[2].y) / 2.0;
r = a / 2.0;
return true;
}
else if(b * b > a * a + c * c)
{
center.x = (pt[0].x + pt[2].x) / 2.0;
center.y = (pt[0].y + pt[2].y) / 2.0;
r = a / 2.0;
return true;
}
else if(c * c > a * a + b * b)
{
center.x = (pt[1].x + pt[0].x) / 2.0;
center.y = (pt[1].y + pt[0].y) / 2.0;
r = a / 2.0;
return true;
}
else
return false;
}
ac代碼:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#define print(a) cout << #a << " : " << a << endl;
using namespace std;
const int M = 1003;
const double e = 1e-6;
struct Point
{
double x, y;
};
Point wi[4];
double getDis(Point a, Point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
///////////////////////////////////////////
//求三角形外接圓圓心座標 及半徑
///////////////////////////////////////////
void circle_center(Point ¢er,Point pt[3],double &radiu) //參數是圓心和半徑的引用
{
double x1,x2,x3,y1,y2,y3;
double x = 0;
double y = 0;
x1 = pt[0].x;
x2 = pt[1].x;
x3 = pt[2].x;
y1 = pt[0].y;
y2 = pt[1].y;
y3 = pt[2].y;
x=((y2-y1)*(y3*y3-y1*y1+x3*x3-x1*x1)-(y3-y1)*(y2*y2-y1*y1+x2*x2-x1*x1))/(2*(x3-x1)*(y2-y1)-2*((x2-x1)*(y3-y1)));
y=((x2-x1)*(x3*x3-x1*x1+y3*y3-y1*y1)-(x3-x1)*(x2*x2-x1*x1+y2*y2-y1*y1))/(2*(y3-y1)*(x2-x1)-2*((y2-y1)*(x3-x1)));
center.x = x ;
center.y = y ;
radiu = sqrt((pt[0].x - x)*(pt[0].x - x) + (pt[0].y - y)*(pt[0].y - y));
}
bool judgeDunJiao(Point pt[3], Point ¢er, double &r)
{
double c = getDis(pt[0], pt[1]);
double b = getDis(pt[0], pt[2]);
double a = getDis(pt[1], pt[2]);
if(a * a > b * b + c * c)
{
center.x = (pt[1].x + pt[2].x) / 2.0;
center.y = (pt[1].y + pt[2].y) / 2.0;
r = a / 2.0;
return true;
}
else if(b * b > a * a + c * c)
{
center.x = (pt[0].x + pt[2].x) / 2.0;
center.y = (pt[0].y + pt[2].y) / 2.0;
r = a / 2.0;
return true;
}
else if(c * c > a * a + b * b)
{
center.x = (pt[1].x + pt[0].x) / 2.0;
center.y = (pt[1].y + pt[0].y) / 2.0;
r = a / 2.0;
return true;
}
else
return false;
}
void solve()
{
double r;
Point center;
int dun = judgeDunJiao(wi, center, r);
if(dun)
{
if(getDis(wi[3], center) - r > 0)
cout << "Safe" << endl;
else
cout << "Danger" << endl;
return;
}
circle_center(center, wi, r);
double dis = getDis(center, wi[3]);
if(dis - r > 0)
cout << "Safe" << endl;
else
cout << "Danger" << endl;
}
int main()
{
int ncase;
int tmp = 0;
cin >> ncase;
while(ncase--)
{
for(int i = 0; i < 4; i++)
cin >> wi[i].x >> wi[i].y;
printf("Case #%d: ", ++tmp);
solve();
}
return 0;
};