C++ 实现两圆外公切线交点计算
时间: 2023-07-11 11:42:06 浏览: 87
实现两圆外公切线交点计算,需要先判断两个圆是否有公切线,如果有,则可以根据两圆心和半径计算两个切点的坐标。
假设两个圆分别为圆A和圆B,圆心坐标分别为(xa,ya)和(xb,yb),半径分别为ra和rb。如果两个圆有公切线,则公切线与两个圆的切点坐标分别为(x1,y1)和(x2,y2)。
首先,根据两圆心之间的距离d,判断两个圆是否有公切线:
1. d > ra + rb,两个圆外离,无公切线;
2. d < |ra - rb|,一个圆包含在另一个圆内,无公切线;
3. d = 0,两圆重合,无公切线;
4. 其他情况,两圆相交,有公切线。
如果存在公切线,则可以根据两个圆心和半径计算切点坐标:
1. 求出两圆心的连线斜率k和截距b;
2. 以圆A的圆心为起点,向切点方向移动ra个单位长度,求出切点坐标(x1,y1);
3. 以圆B的圆心为起点,向切点方向移动rb个单位长度,求出切点坐标(x2,y2)。
下面是C++代码实现:
```cpp
#include <iostream>
#include <cmath>
using namespace std;
// 判断两个浮点数是否相等
bool isEqual(double a, double b) {
return fabs(a - b) < 1e-6;
}
// 计算两圆的公切线交点
bool getTangentialPoints(double xa, double ya, double ra, double xb, double yb, double rb, double &x1, double &y1, double &x2, double &y2) {
double d = sqrt((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb)); // 两圆心之间的距离
if (isEqual(d, 0) || d > ra + rb || d < fabs(ra - rb)) {
// 两圆重合或相离或包含,无公切线
return false;
}
double A = (ra - rb + d) * (ra + rb - d) * (ra + rb + d) * (ra - rb - d);
double B = 2 * (ra + rb + d) * (ra + rb - d) * (rb - ra + d) * (ra - rb + d);
double C = (ra + rb + d) * (ra - rb - d) * (ra - rb + d) * (rb - ra + d);
double x3 = (xa + xb) / 2.0 + (xb - xa) * (ra * ra - rb * rb) / (2.0 * d * d);
double y3 = (ya + yb) / 2.0 + (yb - ya) * (ra * ra - rb * rb) / (2.0 * d * d);
if (isEqual(A, 0) && isEqual(B, 0)) {
// 两圆相切,只有一条公切线
x1 = x3;
y1 = y3;
return true;
}
double k = sqrt(B * B - 4 * A * C);
double x4 = (2.0 * C * x3) / (-B + k);
double y4 = (-B * x3 + 2.0 * A * y3) / (-B + k);
x1 = x4 + (xb - xa) * sqrt(ra * ra - (x4 - xa) * (x4 - xa) - (y4 - ya) * (y4 - ya)) / d;
y1 = y4 + (yb - ya) * sqrt(ra * ra - (x4 - xa) * (x4 - xa) - (y4 - ya) * (y4 - ya)) / d;
x2 = x4 - (xb - xa) * sqrt(ra * ra - (x4 - xa) * (x4 - xa) - (y4 - ya) * (y4 - ya)) / d;
y2 = y4 - (yb - ya) * sqrt(ra * ra - (x4 - xa) * (x4 - xa) - (y4 - ya) * (y4 - ya)) / d;
return true;
}
int main() {
double xa = 0, ya = 0, ra = 3;
double xb = 6, yb = 0, rb = 2;
double x1, y1, x2, y2;
if (getTangentialPoints(xa, ya, ra, xb, yb, rb, x1, y1, x2, y2)) {
cout << "Circle A and Circle B have tangential points:" << endl;
cout << "(" << x1 << ", " << y1 << ")" << endl;
cout << "(" << x2 << ", " << y2 << ")" << endl;
} else {
cout << "Circle A and Circle B don't have tangential points." << endl;
}
return 0;
}
```
其中,isEqual()函数是用来判断两个浮点数是否相等的,getTangentialPoints()函数根据上述算法实现了两圆公切线交点的计算。在主函数中,我们可以设置两个圆的圆心坐标和半径,然后调用getTangentialPoints()函数计算切点坐标。
相关推荐
![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)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)