Circle Through Three Points - 给出三个点求圆

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

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

方法2暴力解方程

\[\begin{array}{l} x=\frac{\left(x_{1}^{2}+y_{1}^{2}\right)\left(y_{2}-y_{3}\right)+\left(x_{2}^{2}+y_{2}^{2}\right)\left(y_{3}-y_{1}\right)+\left(x_{3}^{2}+y_{3}^{2}\right)\left(y_{1}-y_{2}\right)}{2\left(x_{1}\left(y_{2}-y_{3}\right)-y_{1}\left(x_{2}-x_{3}\right)+x_{2} y_{3}-x_{3} y_{2}\right)}=-\frac{B}{2 A} \\ y=\frac{\left(x_{1}^{2}+y_{1}^{2}\right)\left(x_{3}-x_{2}\right)+\left(x_{2}^{2}+y_{2}^{2}\right)\left(x_{1}-x_{3}\right)+\left(x_{3}^{2}+y_{3}^{2}\right)\left(x_{2}-x_{1}\right)}{2\left(x_{1}\left(y_{2}-y_{3}\right)-y_{1}\left(x_{2}-x_{3}\right)+x_{2} y_{3}-x_{3} y_{2}\right)}=-\frac{c}{2 A} \\ r=\sqrt{\left(x-x_{1}\right)^{2}+\left(y-y_{1}\right)^{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\n", 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\n\n", 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;
}

posted @ 2020-05-14 16:35  Emcikem  阅读(424)  评论(0编辑  收藏  举报