poj 1090:The Circumference of the Circle(计算几何,求三角形外心)
To calculate the circumference of a circle seems to be an easy task - provided you know its diameter. But what if you don't?
You are given the cartesian coordinates of three non-collinear points in the plane.
Your job is to calculate the circumference of the unique circle that intersects all three points.
Input Specification
The input file will contain one or more test cases. Each test case consists of one line containing six real numbers x1,y1, x2,y2,x3,y3, representing the coordinates of the three points. The diameter of the circle determined by the three points will never exceed a million. Input is terminated by end of file.
Output Specification
For each test case, print one line containing one real number telling the circumference of the circle determined by the three points. The circumference is to be printed accurately rounded to two decimals. The value of pi is approximately 3.141592653589793.
Sample Input
0.0 -0.5 0.5 0.0 0.0 0.5 0.0 0.0 0.0 1.0 1.0 1.0 5.0 5.0 5.0 7.0 4.0 6.0 0.0 0.0 -1.0 7.0 7.0 7.0 50.0 50.0 50.0 70.0 40.0 60.0 0.0 0.0 10.0 0.0 20.0 1.0 0.0 -500000.0 500000.0 0.0 0.0 500000.0
Sample Output
3.14 4.44 6.28 31.42 62.83 632.24 3141592.65
计算几何,求三角形外心。
题意是给你三个点,让你求穿过这三个点的圆的周长。很显然,这个圆是这三个点构成的三角形的外接圆,只要求出这个外接圆的圆心,就能确定半径r,进而求得外接圆的周长。外接圆的圆心就是三角形的外心,外心的求法是三角新任意两边的垂直平分线线的交点(外心到三角形任意一个顶点的距离相等)。
那么这个题的重心就转移到了求三角形的外心。我是用解析几何的解法做的,因为知道两点的坐标,可以求出任意两条边的斜截式(y=kx+b)的斜率k和截距b,根据垂直的两条直线k1*k2=-1,求出垂直平分线的斜率,然后在根据边的中点可以写出任意两条边的垂直平分线的斜截式。最后联立三角形两条边的垂直平分线的方程,求得交点,就是三角形的外心。
需要注意的是,有一条边斜率是0的情况,这条边的垂直平分线的斜率是不存在的(因为是垂直的),所以需要拿出来特殊考虑。
用解析几何做可能会伤精度,但是应付这道题是够了,有时间把其他做法贴上来。
代码:
1 #include <stdio.h>
2 #include <math.h>
3 #define PI 3.141592653589793
4 typedef struct { //定义点
5 double x,y;
6 } Point;
7 double dis(Point a,Point b) //两点距离
8 {
9 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
10 }
11 Point getWai(Point a,Point b,Point c) //解析几何方法,求三角形abc的外心
12 {
13 Point w;
14 Point cen1,cen2; //边ab和边ac的中点
15 cen1.x = (a.x+b.x)/2;
16 cen1.y = (a.y+b.y)/2;
17 cen2.x = (a.x+c.x)/2;
18 cen2.y = (a.y+c.y)/2;
19 if(a.y==b.y){ //ab的垂线垂直,不存在斜率k的情况
20 double k2 = -1.0/((a.y-c.y)/(a.x-c.x));
21 double b2 = cen2.y - k2*cen2.x;
22 w.x = cen1.x;
23 w.y = cen1.x*k2 + b2;
24 return w;
25 }
26 else if(a.y==c.y){ //ac的垂线垂直
27 double k1 = -1.0/((a.y-b.y)/(a.x-b.x));
28 double b1 = cen1.y - k1*cen1.x;
29 w.x = cen2.x;
30 w.y = cen2.x*k1 + b1;
31 return w;
32 }
33 else { //不存在垂线垂直的情况
34 double k1 = -1.0/((a.y-b.y)/(a.x-b.x));
35 double b1 = cen1.y - k1*cen1.x;
36 double k2 = -1.0/((a.y-c.y)/(a.x-c.x));
37 double b2 = cen2.y - k2*cen2.x;
38 w.x = (b2-b1)/(k1-k2);
39 w.y = k1*w.x+b1;
40 return w;
41 }
42 }
43 int main()
44 {
45 Point a,b,c; //三角形的三点
46 while(scanf("%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y)!=EOF){
47 Point w = getWai(a,b,c);
48 double r = dis(w,a);
49 printf("%.2lf\n",2*PI*r);
50 }
51 return 0;
52 }
Freecode : www.cnblogs.com/yym2013