计算圆与圆的交点,需要用到余弦定理

步骤如下:

  1. 求出两个圆的圆心距d
  2. 求出向量c2.c-c1.c与c1.c到某交点的向量夹角a
  3. 求出向量c2.c-c1.c与x轴的夹角t
  4. 那么,两个交点就分别是以c1.c为起点,大小为c1.r,角度为t+a、t-a的两个向量

题目:CGL_7_E

AC代码:

#include <iostream>
#include <cstdio>
#include <math.h>
using namespace std;

#define COUNTER_CLOCKWISE -1 //逆时针
#define CLOCKWISE 1          //顺时针
#define ONLINE_BACK -2       //p2 p0 p1依次排列在一条直线上
#define ONLINE_FRONT 2       //p0 p1 p2依次排列在一条直线上
#define ON_SEGMENT 0         //p2在线段p0p1上

#define EPS 1E-8

class Point
{
public:
    double x, y;
    Point()
    {
    }
    Point(double x, double y)
    {
        (*this).x = x;
        (*this).y = y;
    }

    double operator^(const Point &p) const //叉乘
    {
        return x * p.y - y * p.x;
    }

    double operator*(const Point &p) const //点乘
    {
        return x * p.x + y * p.y;
    }

    Point operator*(const double &d) const
    {
        return Point(x * d, y * d);
    }

    Point operator/(const double &d) const
    {
        return Point(x / d, y / d);
    }

    Point operator-(const Point &p) const
    {
        return Point(x - p.x, y - p.y);
    }

    Point operator+(const Point &p) const
    {
        return Point(x + p.x, y + p.y);
    }

    double sqr()
    {
        return x * x + y * y;
    }
    double abs()
    {
        return sqrt(sqr());
    }

    double distance(const Point &p)
    {
        return fabs((*this - p).abs());
    }

    void print()
    {

        printf("%.8lf %.8lf", x, y);
    }
};

class Line
{
public:
    Point p1, p2;
    Point vec;
    Line()
    {
    }
    Line(Point p1, Point p2)
    {
        (*this).p1 = p1;
        (*this).p2 = p2;
        (*this).vec = p2 - p1;
    }
};

class Circle
{
public:
    Point o;
    double r;
    Circle()
    {
    }

    Circle(Point o, double r)
    {
        (*this).o = o;
        (*this).r = r;
    }

    Circle(double cx, double cy, double r)
    {
        (*this).o.x = cx;
        (*this).o.y = cy;
        (*this).r = r;
    }
};

Point polar(double length, double angle) //根据模长、角度求向量
{
    return Point(length * cos(angle), length * sin(angle));
}

pair<Point, Point> get_Cross_Points(Circle c1, Circle c2) //求圆与圆的交点
{

    Point vec12 = c2.o - c1.o; //两圆圆心的向量
    double d = vec12.abs();    //圆心距

    double a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2.0 * c1.r * d)); //vec12与(c1与一个交点)的夹角

    double t = atan2(vec12.y, vec12.x); //vec12与x轴的夹角

    return make_pair(c1.o + polar(c1.r, t + a), c1.o + polar(c1.r, t - a));
}

int main()
{
    Circle c1, c2;
    cin >> c1.o.x >> c1.o.y >> c1.r;
    cin >> c2.o.x >> c2.o.y >> c2.r;

    auto ans = get_Cross_Points(c1, c2);
    if (ans.first.x < ans.second.x)
    {
        ans.first.print();
        cout << ' ';
        ans.second.print();
        cout << endl;
    }
    else if (ans.second.x < ans.first.x)
    {
        ans.second.print();
        cout << ' ';
        ans.first.print();
        cout << endl;
    }
    else
    {
        if (ans.first.y - ans.second.y <= EPS)
        {
            ans.first.print();
            cout << ' ';
            ans.second.print();
            cout << endl;
        }
        else
        {
            ans.second.print();
            cout << ' ';
            ans.first.print();
            cout << endl;
        }
    }
}

转载请注明来源:https://www.longjin666.top/?p=802

欢迎关注我的公众号“灯珑”,让我们一起了解更多的事物~

你也可能喜欢

发表评论