C++ 实现求两圆外公切线
时间: 2023-08-12 10:10:19 浏览: 131
假设两个圆的圆心分别为 $(x_1,y_1)$ 和 $(x_2,y_2)$,半径分别为 $r_1$ 和 $r_2$。我们可以根据两个圆心之间的距离和半径之和、差的关系,分类讨论两个圆的位置关系:
1. 两个圆不相交,即 $d > r_1+r_2$ 或 $d < |r_1-r_2|$(其中 $d=\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}$ 表示两个圆心之间的距离)。此时不存在公切线。
2. 两个圆相交,即 $d < r_1+r_2$ 且 $d > |r_1-r_2|$。此时存在两条内公切线和两条外公切线。内公切线的两个切点均在两个圆的连线上,外公切线的两个切点均在两个圆的连线的延长线上。如果两个圆的圆心重合,则存在无数条公切线。
3. 一个圆包含另一个圆,即 $d < r_1-r_2$ 或 $d < r_2-r_1$。此时存在一条内公切线和一条外公切线。内公切线的两个切点均在小圆上,外公切线的两个切点均在大圆上。如果两个圆的圆心重合,则存在无数条公切线。
我们只需要考虑外公切线的情况。两个圆的连线的中垂线与两个圆的半径分别构成一个直角三角形,我们可以利用三角函数求出中垂线与连线的夹角 $\theta$,然后根据 $\theta$ 算出公切线与中垂线的夹角 $\alpha$,最后旋转 $\alpha$ 即可求出公切线的方向向量。具体实现代码如下:
相关问题
C++ 实现两圆外公切线交点计算
实现两圆外公切线交点计算,可以按照以下步骤进行:
1. 计算两圆心之间的距离,如果两圆相离或相切,则不存在外公切线;
2. 计算两圆心的连线与两圆的切点,得到切线的斜率;
3. 根据切线斜率和两圆心的位置,求出切线的方程;
4. 求出两圆心到切点的距离,即切线的截距;
5. 求解切线方程组,得到两条外公切线的交点。
以下是使用 C++ 实现两圆外公切线交点计算的代码示例:
```c++
#include <iostream>
#include <cmath>
using namespace std;
struct Point {
double x, y;
};
struct Circle {
Point center;
double radius;
};
// 计算两点之间的距离
double distance(Point p1, Point p2) {
return sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2));
}
// 计算两圆的公切线的交点
void calcOuterTangent(Circle c1, Circle c2) {
// 计算两圆心之间的距离
double d = distance(c1.center, c2.center);
// 如果两圆相离或相切,则不存在外公切线
if (d > c1.radius + c2.radius || d < abs(c1.radius - c2.radius)) {
cout << "No outer tangent." << endl;
return;
}
// 计算两圆心的连线与两圆的切点,得到切线的斜率
double angle = atan2(c2.center.y - c1.center.y, c2.center.x - c1.center.x);
double sinAngle = sin(angle);
double cosAngle = cos(angle);
// 根据切线斜率和两圆心的位置,求出切线的方程
double m1 = c1.radius * sinAngle - c2.radius * sinAngle;
double n1 = c1.radius * cosAngle - c2.radius * cosAngle;
double m2 = c1.radius * sinAngle + c2.radius * sinAngle;
double n2 = c1.radius * cosAngle + c2.radius * cosAngle;
// 求出两圆心到切点的距离,即切线的截距
double b1 = c1.center.y - m1 / n1 * c1.center.x;
double b2 = c2.center.y - m2 / n2 * c2.center.x;
// 求解切线方程组,得到两条外公切线的交点
double x = (b2 - b1) / (m1 / n1 - m2 / n2);
double y = m1 / n1 * x + b1;
cout << "The intersection point of outer tangents is: (" << x << ", " << y << ")." << endl;
}
int main() {
Circle c1 = {{0, 0}, 2};
Circle c2 = {{5, 0}, 3};
calcOuterTangent(c1, c2);
return 0;
}
```
上述代码中,我们定义了两个结构体 Point 和 Circle,分别表示点和圆。distance 函数用于计算两点之间的距离。calcOuterTangent 函数用于计算两圆的外公切线的交点。在主函数中,我们定义了两个圆,并调用 calcOuterTangent 函数计算它们的外公切线的交点。
c++ 实现求两个圆切线
下面是一个简单的 C++ 实现,可以求解两个圆的外公切线和内公切线。其中,Circle 类表示圆,包含圆心坐标和半径信息,Line 类表示直线,包含直线上的两个点的坐标信息。
```
#include <iostream>
#include <cmath>
using namespace std;
const double eps = 1e-8;
struct Point {
double x, y;
Point() {}
Point(double x, double y) : x(x), y(y) {}
};
struct Circle {
Point c;
double r;
Circle() {}
Circle(Point c, double r) : c(c), r(r) {}
};
struct Line {
Point p1, p2;
Line() {}
Line(Point p1, Point p2) : p1(p1), p2(p2) {}
};
double dis(Point A, Point B) {
return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}
int dcmp(double x) {
if (fabs(x) < eps) return 0;
return x < 0 ? -1 : 1;
}
Point getIntersection(Line a, Line b) {
double x1 = a.p1.x, y1 = a.p1.y;
double x2 = a.p2.x, y2 = a.p2.y;
double x3 = b.p1.x, y3 = b.p1.y;
double x4 = b.p2.x, y4 = b.p2.y;
double k1 = (y2 - y1) / (x2 - x1);
double k2 = (y4 - y3) / (x4 - x3);
double b1 = y1 - k1 * x1;
double b2 = y3 - k2 * x3;
double x = (b2 - b1) / (k1 - k2);
double y = k1 * x + b1;
return Point(x, y);
}
void getTangents(Circle A, Circle B, Line &l1, Line &l2, Line &l3, Line &l4) {
double d = dis(A.c, B.c);
double cosA = (A.r - B.r) / d;
double sinA = sqrt(1 - cosA * cosA);
Point v = (B.c - A.c) / d;
Point p1 = A.c + v * (A.r / cosA);
Point p2 = B.c - v * (B.r / cosA);
Point p3 = A.c + v * (A.r / cosA * cosA * sinA);
Point p4 = B.c - v * (B.r / cosA * cosA * sinA);
l1 = Line(p1, p2);
l2 = Line(p1, p3);
l3 = Line(p2, p4);
l4 = Line(p3, p4);
}
int main() {
Circle A(Point(0, 0), 2);
Circle B(Point(3, 0), 1);
Line l1, l2, l3, l4;
getTangents(A, B, l1, l2, l3, l4);
cout << "Outer tangents: " << endl;
cout << "(" << l1.p1.x << ", " << l1.p1.y << ") -> (" << l1.p2.x << ", " << l1.p2.y << ")" << endl;
cout << "(" << l2.p1.x << ", " << l2.p1.y << ") -> (" << l2.p2.x << ", " << l2.p2.y << ")" << endl;
cout << "Inner tangents: " << endl;
cout << "(" << l3.p1.x << ", " << l3.p1.y << ") -> (" << l3.p2.x << ", " << l3.p2.y << ")" << endl;
cout << "(" << l4.p1.x << ", " << l4.p1.y << ") -> (" << l4.p2.x << ", " << l4.p2.y << ")" << endl;
return 0;
}
```
这个例子中,我们假设两个圆的圆心分别为 (0, 0) 和 (3, 0),半径分别为 2 和 1。程序输出了两个圆的外公切线和内公切线的坐标。在实际使用中,可以根据需要进行修改。
相关推荐
![text/x-c](https://img-home.csdnimg.cn/images/20210720083646.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)