zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    [Eclipse]GEF入门系列(四、其他功能)
    [Eclipse]GEF入门系列(三、应用实例)
    [Eclipse]GEF入门系列(一、Draw2D)
    打开Win2000的自动补齐功能
    让URLConnection使用代理服务器
    [Eclipse]GEF入门系列(序)
    给表格的单元格增加编辑功能(In place edit)
    设置Eclipse RCP程序的外观和首选项
    利用winrar自动备份重要资料(续,经验技巧)
    终于换了新电脑
  • 原文地址:https://www.cnblogs.com/Emcikem/p/12889617.html
Copyright © 2011-2022 走看看