求一个三角形的最小圆覆盖
两种情况:
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; };