先通过三点确定一条直线,然后算出三条向量的夹角,与圆心角对比,如果呈倍数关系,说明可以接受。特别注意EPS 1e-2和1e-7过不了全部数据,改成1e-4通过全部数据。
点击查看代码
#include <bits/stdc++.h>
#define double long double
using namespace std;
const double PI = acos(-1);
const double EPS = 0.0001;
const double INF = numeric_limits<double>::max();
double fgcd(double x, double y) { // 实数域gcd
return abs(y) < EPS ? abs(x) : fgcd(y, fmod(x, y));
}
bool equal(double x, double y) {return -EPS < x - y && x - y < EPS;}
struct Point {
double x, y;
friend bool operator<(Point a, Point b) { return equal(a.x, b.x) ? a.y < b.y - EPS : a.x < b.x - EPS;}
friend bool operator>(Point a, Point b) { return b < a; }
friend bool operator==(Point a, Point b) { return !(a < b) && !(b < a); }
friend bool operator!=(Point a, Point b) { return a < b || b < a; }
};
struct Line {Point a, b;};
struct Circle{Point o;double r;};
Point operator + (Point a,Point b) {return {a.x + b.x,a.y + b.y};}
Point operator - (Point a,Point b) {return {a.x - b.x,a.y - b.y};}
Point operator * (Point a,double D) {return {a.x*D,a.y*D};};
Point operator / (Point a,double D) {return {a.x/D,a.y/D};};
double cross(Point a, Point b) {return a.x * b.y - a.y * b.x;}
double cross(Point p1, Point p2, Point p0) {return cross(p1 - p0, p2 - p0);}
double dot(Point a, Point b) {return a.x * b.x + a.y * b.y;}
double dot(Point p1, Point p2, Point p0) {return dot(p1 - p0, p2 - p0);}
double dis(Point a, Point b) {return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}
double toDeg(double x) { return x * 180 / PI;}// 弧度转角度
double toArc(double x) { return PI / 180 * x;}// 角度转弧度
double angle(Point a, Point b) {
double val = abs(cross(a, b));
return abs(atan2(val, a.x * b.x + a.y * b.y));
}
Point rotate(Point p1, Point p2) { // 旋转
Point vec = p1 - p2;
return {-vec.y, vec.x};
}
Line midSegment(Line l) {
Point mid = (l.a + l.b) / 2; // 线段中点
return {mid, mid + rotate(l.a, l.b)};
}
Point lineIntersection(Line l1, Line l2) {
double val = cross(l2.b - l2.a, l1.a - l2.a) / cross(l2.b - l2.a, l1.a - l1.b);
return l1.a + (l1.b - l1.a) * val;
}
Point getCircle(Point A, Point B, Point C) {
Line l1 = midSegment(Line{A, B});
Line l2 = midSegment(Line{A, C});
return lineIntersection(l1, l2);
}
double getAng(Point a,Point b){
return abs(atan2(cross(a,b),dot(a,b)));
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cout << fixed << setprecision(9);
array<Point,3> v;
for(int i = 0;i < 3;i ++ ) {
cin >> v[i].x >> v[i].y;
}
Point o = getCircle(v[0],v[1],v[2]);
double a1,a2;
a1 = getAng(o - v[0],o - v[1]);
a2 = getAng(o - v[0],o - v[2]);
int k = -1;
for(int i = 3;i <= 100;i ++ ) {
double A = 2*PI/i;
double a3 = fgcd(A,a1),
a4 = fgcd(A,a2);
if(abs(A - a3) < EPS && abs(A - a4) < EPS) {
k = i;break;
}
}
double r = dis(o,v[0]);
cout << abs(k*r*r*sin(2*PI/k) / 2.);
return 0;
}
/*
*/