这是我第一题几何题。 纪念下。
题意: 有一个圆形的斗兽场, 圆上有X个树桩, 刚好能组成一个正多边形的舞台。 但是, 有3个树桩不见了。
现在给你这3个树桩的坐标, 让你判断这个舞台最小的面积。(数组绝对合法。 绝对能组成三角形) 不会大于100边型。
思路:
#include <stdio.h>
#include <math.h>
#define pi acos(-1.0)
#include <cmath>
#define feq(a, b) (fabs((a)-(b))<1E-2)
using namespace std;
double fgcd(double a, double b){
if (feq(a, 0))
return b;
if (feq(b, 0))
return a;
return fgcd(b, fmod(a, b));
}
double diameter(double a, double b, double c) {
double p = (a + b + c) / 2;
double s = sqrt(p * (p - a) * (p - b) * (p - c));
return a * b * c / (4 *s);
}
int main() {
double x[3], y[3], d[3];
int i = 0;
while(~scanf("%lf%lf", &x[i], &y[i])) {
i++;
if(i == 3) {
for(int j = 0; j < 3; ++j)
d[j] = sqrt((x[j] - x[(j+1)%3]) * (x[j] - x[(j+1)%3]) + (y[j] - y[(j+1)%3]) * (y[j] - y[(j+1)%3]));
double R = diameter(d[0], d[1], d[2]);
double angle[4];
for(int j = 0; j < 2; ++j)
angle[j] = acos(1 - d[j] * d[j] / (2 * R * R));
angle[2] = 2 * pi - angle[0] - angle[1];
angle[3] = fgcd(angle[0], fgcd(angle[1], angle[2]));
printf("%.6lf\n", R * R * sin(angle[3]) / 2 * (2 * pi / angle[3]));
i = 0;
}
}
}
如图 给出A(x0, y0) B(x1, y1) C(x2, y2)
1.求3边a,b,c
2. 先求外接圆半径。(一定存在)
海伦公式 + 正弦定理 得 R = a * b * c / (4 * S) S = sqrt(q * (q - a) * (q - b) * (q -c)); q = (a + b + c) / 2;
-----因为是正多边形。 那么只要求出一边与两半径围成的面积 * N 就好。
3. 余弦定理 求3个角。 求最大公约数就是 正多边形 每一份 最小的角度。
4. 最后就是 用正弦求面积了。 S = R * R * sin( angle ) / 2 * (倍数) (竟然坐标是合法的, 倍数 = 2 * pi / angle);