Circle Through Three Points

题目
给出三个点,求圆的两种表示

方法1 圆心在 A和B的垂直平分线以及A和C的垂直平分线的交点

方法2暴力解方程

[egin{array}{l} x=frac{left(x_{1}^{2}+y_{1}^{2} ight)left(y_{2}-y_{3} ight)+left(x_{2}^{2}+y_{2}^{2} ight)left(y_{3}-y_{1} ight)+left(x_{3}^{2}+y_{3}^{2} ight)left(y_{1}-y_{2} ight)}{2left(x_{1}left(y_{2}-y_{3} ight)-y_{1}left(x_{2}-x_{3} ight)+x_{2} y_{3}-x_{3} y_{2} ight)}=-frac{B}{2 A} \ y=frac{left(x_{1}^{2}+y_{1}^{2} ight)left(x_{3}-x_{2} ight)+left(x_{2}^{2}+y_{2}^{2} ight)left(x_{1}-x_{3} ight)+left(x_{3}^{2}+y_{3}^{2} ight)left(x_{2}-x_{1} ight)}{2left(x_{1}left(y_{2}-y_{3} ight)-y_{1}left(x_{2}-x_{3} ight)+x_{2} y_{3}-x_{3} y_{2} ight)}=-frac{c}{2 A} \ r=sqrt{left(x-x_{1} ight)^{2}+left(y-y_{1} ight)^{2}}=sqrt{frac{B^{2}+C^{2}-4 A D}{4 A^{2}}} end{array} ]

void getCircle(Point a, Point b, Point c) {
    double B = (a.x * a.x + a.y * a.y) * (b.y - c.y) + (b.x * b.x + b.y * b.y) * (c.y - a.y) + (c.x * c.x + c.y * c.y) * (a.y - b.y);
    double A = a.x * (b.y - c.y) - a.y * (b.x - c.x) + b.x * c.y - c.x * b.y;
    double C = (a.x * a.x + a.y * a.y) * (c.x - b.x) + (b.x * b.x + b.y * b.y) * (a.x - c.x) + (c.x * c.x + c.y * c.y) * (b.x - a.x);
    double x = - B / (2 * A);
    double y = - C / (2 * A);
}
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double eps = 1e-8;
struct Point{
    double x, y;
    Point(double x = 0, double y = 0):x(x),y(y){}
    Point operator + (const Point& u) const { return Point(x + u.x, y + u.y); }
    Point operator - (const Point& u) const { return Point(x - u.x, y - u.y); }
    Point operator * (const double& k) const { return Point(x * k, y * k); }
};
typedef Point Vector;

double Cross (Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
double Dot (Vector a, Vector b) { return a.x * b.x + a.y + b.y; }
double Length(Vector a) { return sqrt(Dot(a, a)); }
Vector Normal (Vector a) { return Vector(-a.y, a.x); }//逆时针旋转90度

struct Circle{
    Point o;
    double r;
    Circle(Point o, double r):o(o),r(r){}
    void read(){scanf("%lf%lf%lf", &o.x, &o.y, &r);}
};

inline int dcmp(double x) {
    if (fabs(x) < eps) return 0; 
    return x < 0 ? -1 : 1;
}

Point GetLinersection(Point P, Vector v, Point Q, Vector w){//求两个直线的交点
    Vector u = P - Q;
    double t = Cross(w, u) / Cross(v, w);
    return P + v * t;
}
Vector chuizhi(Point A, Point B){//求垂直平分线的向量
    return Normal(Vector(A - B));
}
char sign(double x){//符号判断
    return dcmp(x) == 1 ? '+' : '-';
}
Circle getcircle(Point A, Point B, Point C){
    Point xx((A.x + B.x) / 2, (A.y + B.y) / 2);
    Point yy((A.x + C.x) / 2, (A.y + C.y) / 2);
    Point O = GetLinersection(xx, chuizhi(A, B), yy, chuizhi(A, C));
    double r = sqrt(pow(C.x - O.x, 2) + pow(C.y - O.y, 2));
    return Circle(O, r);
}
int main(){
    double x1, x2, x3, y1, y2, y3;
    while(~scanf("%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3)){
        Circle circle = getcircle(Point(x1, y1), Point(x2, y2), Point(x3, y3));

        Point O = circle.o;
        double r = circle.r;

        printf("(x %c %.3lf)^2 + (y %c %.3lf)^2 = %.3lf^2
", sign(-O.x) ,abs(O.x), sign(-O.y), abs(O.y), r);
    
        printf("x^2 + y^2 %c %.3lfx %c %.3lfy %c %.3lf = 0

", sign(-O.x), abs(2 * O.x), sign(-O.y), abs(2 * O.y), sign(O.x * O.x + O.y * O.y - r * r), abs(O.x * O.x + O.y * O.y - r * r));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Emcikem/p/12889617.html