UVA 10674 || Tangents(求两圆的共切线

大白模板题,但是大白模板放这题会有精度误差,死Wa,看了个题解,也是从大白模板改的,全部都用了浮点误差,偷偷敲走。


两圆的共切线,根据两圆的圆心距从小到大排列,一共有种情况。

1)两圆完全重合,有无数条公切线,返回-1;

2)两圆内含,没有公共点,无公切线,返回0;

3)两圆内切,有一条外公切线;

4)两圆相交,有两条外公切线;

5)两圆外切,有两条外公切线,一条内公切线;

6)两圆相离,有两条外公切线,两条内公切线;


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#define FIR first
#define SEC second
using namespace std;
const double eps = 1e-8;
const double PI = acos(-1.0);
int dcmp(double x)
{
    if(fabs(x)<eps)
        return 0;
    return x < 0? -1: 1;
}
struct pnode
{
    double x,y;
    pnode(double x=0.0,double y
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的 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 getOuterTangents(Circle A, Circle B, Line &l1, Line &l2) { 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(p3, p4); } int main() { Circle A(Point(0, 0), 2); Circle B(Point(3, 0), 1); Line l1, l2; getOuterTangents(A, B, l1, l2); 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; return 0; } ``` 这个例子中,我们假设两个心分别为 (0, 0) 和 (3, 0),半径分别为 2 和 1。程序输出了两个的外公切线的坐标。在实际使用中,可以根据需要进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值