题目地址:https://vjudge.net/problem/UVA-10674

题目:


https://uva.onlinejudge.org/external/106/10674.pdf

给出两个圆的圆心坐标和半径,求公切线数目(-1表示无穷)、两圆公切线的切点和这条公切线上切点的距离。

ac代码:


注意精度!!比较大小尽量用三态函数

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 10;
const double eps = 1e-6;//eps用于控制精度,或者更高精度
const double pi = acos(-1.0);//pi
struct Point//点或向量
{double x, y;Point(double x = 0, double y = 0) :x(x), y(y) {}friend bool operator < (Point a, Point b){return a.x == b.x ? a.y < b.y : a.x < b.x;}
};
struct Circle
{Point c;double r;Circle(Point c, double r):c(c),r(r){}Point point(double a)//基于圆心角求圆上一点坐标{return Point(c.x + cos(a)*r, c.y + sin(a)*r);}
};
typedef Point Vector;
Vector operator + (Vector a, Vector b)//向量加法
{return Vector(a.x + b.x, a.y + b.y);
}
Vector operator - (Vector a, Vector b)//向量减法
{return Vector(a.x - b.x, a.y - b.y);
}
Vector operator * (Vector a, double p)//向量数乘
{return Vector(a.x * p, a.y * p);
}
Vector operator / (Vector a, double p)//向量数除
{return Vector(a.x / p, a.y / p);
}
int dcmp(double x)//精度三态函数(>0,<0,=0)
{if (fabs(x) < eps)return 0; //等于else return x < 0 ? -1 : 1;//小于,大于
}
bool operator == (const Point &a, const Point &b)//向量相等
{return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
double Dot(Vector a, Vector b)//点积
{return a.x * b.x + a.y * b.y;
}
double Length(Vector a)//模
{return sqrt(Dot(a, a));
}
//a[i]和b[i]分别表示第i条切线在圆A和圆B上的切点
int getTangents(Circle A, Circle B, Point* a, Point* b)
{int cnt = 0;if(dcmp(A.r - B.r) < 0) {swap(A, B);swap(a, b);}double d2 = (A.c.x - B.c.x)*(A.c.x - B.c.x) + (A.c.y - B.c.y)*(A.c.y - B.c.y); //圆心距离double rdiff = A.r - B.r;double rsum = A.r + B.r;if(dcmp(d2 - rdiff*rdiff) < 0) return 0;//insidedouble base = atan2(B.c.y - A.c.y, B.c.x - A.c.x); // AB向量的极角,A位大圆if(dcmp(d2 - 0) == 0 && dcmp(A.r - B.r) == 0) return -1;//无数条if(dcmp(d2 - rdiff*rdiff) == 0)//内切{a[cnt] = A.point(base); b[cnt] = B.point(base); cnt++; // 左侧相切return 1;}double ang = acos((A.r - B.r) / sqrt(d2));//外公切线的图a[cnt] = A.point(base + ang); b[cnt] = B.point(base + ang); cnt++;a[cnt] = A.point(base - ang); b[cnt] = B.point(base - ang); cnt++;if(dcmp(d2 - rsum * rsum) == 0)//一条内公切线{a[cnt] = A.point(base); b[cnt] = B.point(base + pi); cnt++;}else if(dcmp(d2 - rsum * rsum) > 0)//两条内公切线,对应内公切线的图{double ang = acos((A.r + B.r) / sqrt(d2));a[cnt] = A.point(base + ang); b[cnt] = B.point(base + ang + pi); cnt++;a[cnt] = A.point(base - ang); b[cnt] = B.point(base - ang + pi); cnt++;}return cnt;
}
struct node{Point A, B;double len;friend bool operator < (node a, node b){return dcmp(a.A.x - b.A.x) == 0 ? a.A.y < b.A.y : a.A.x < b.A.x;}
};
int main()
{//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);double x1, y1, r1, x2, y2, r2;while(scanf("%lf %lf %lf %lf %lf %lf", &x1, &y1, &r1, &x2, &y2, &r2)){Point aq[maxn], bq[maxn];node ans[maxn];if(!dcmp(x1) && !dcmp(y1) && !dcmp(r1) && !dcmp(x2) && !dcmp(y2) && !dcmp(r2)) break;Point a = {x1, y1}, b = {x2, y2};Circle A ={a, r1}, B = {b, r2};int cnt = getTangents(A, B, aq, bq);printf("%d\n", cnt);if(cnt == 0 || cnt == -1) continue;for(int i = 0; i < cnt; i++){ans[i].A = aq[i];ans[i].B = bq[i];ans[i].len = Length(aq[i] - bq[i]);//printf("i:%d  A(%lf, %lf) B(%lf, %lf) len:%lf\n", i, ans[i].A.x, ans[i].A.y, ans[i].B.x, ans[i].B.y, ans[i].len);}sort(ans, ans + cnt);for(int i = 0; i < cnt; i++)printf("%.5lf %.5lf %.5lf %.5lf %.5lf\n",ans[i].A.x, ans[i].A.y, ans[i].B.x, ans[i].B.y, ans[i].len);}return 0;
}

【UVa10674】Tangents(两圆公切线的切点--验板子题)相关推荐

  1. 两个圆公切线求法_求两圆的公切线计算

    关于两圆的公切线计算我们首先需要搞清楚的是两个圆之间有哪些位置关系,两个圆的位置包括内含.内切.外切.外离几种方式,可以看出位置关系可以根据"两圆心之间的距离"与"两圆半 ...

  2. 两个圆公切线求法_两圆的公切线教案

    两圆的公切线教案 第一课时 两圆的公切线(一) 教学目标: (1)理解两圆相切长等有关概念,掌握两圆外公切线长的求法: (2)培养学生的归纳.总结能力: (3)通过两圆外公切线长的求法向学生渗透&qu ...

  3. 两圆的外切线与内切线的切点算法

    最近想画两球水滴效果所有在网上找两圆外切点和内切点的算法,找了很久没有找到所以自己写了一个工具类来计算两圆的公切线点.具体效果如下图: 根据CircleUtils类的getCircleTangentP ...

  4. 两个圆公切线求法_两个圆的公切线

    两个圆的公切线 圆上任意一点拥有唯一的圆心角 struct circle{ Point p; double r; // 通过圆心角求圆上某一点 Point point(double a){ retur ...

  5. JAVA 三点定位相关计算(一,两圆关系)

    判断两圆相交 两圆圆心坐标(X1,Y1),(X2,Y2),半径分别为r1,r2. 1,直线距离 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离 double s = Math.sq ...

  6. 两圆重叠问题你会求解吗?这个问题的准确答案,德国数学家最近才找到

    萧箫 发自 凹非寺 量子位 报道 | 公众号 QbitAI 先来看一道简单的几何问题: 下图中,黑圆恰好将红圆的面积等分,且黑圆的圆心恰好在红圆上.假设红圆半径为R,黑圆半径为r,求r. 是不是感觉已 ...

  7. Square Card 计算几何-两圆相交面积

    题意 : 给两个圆,分别代表得分区域和奖励区域,边长为a的正方形以均等概率扔到平面后绕中心旋转,保证一定会有某时刻正方形完全在得分区域内. 如果某时刻正方形完全落在区域内,获得相应分数,求正方形 既获 ...

  8. [codevs 3273] 两圆的交

    题解 需要考虑几种情况: 外切或外离.面积为0,注意要输出 0.000. 内切或内含或重合.面积为较小圆的面积. 相交,还需要讨论交点位置: 交点在两圆心中间 即异侧 交点在两圆心同侧 在求三角形面积 ...

  9. 两圆相交求面积 hdu5120

    转载 两圆相交分如下集中情况:相离.相切.相交.包含. 设两圆圆心分别是O1和O2,半径分别是r1和r2,设d为两圆心距离.又因为两圆有大有小,我们设较小的圆是O1. 相离相切的面积为零,代码如下: ...

  10. MATLAB求图片两圆圆心,求助:如何求此图中两圆的圆心距?

    对于你给出的图片,我根据之前提到的思路编写了以下程序.感觉还蛮准的.这个程序只能用于两圆相交的情况.当小圆在大圆内部时,需要在其中加以判定.仅供参考. clear;clc c = imread('1. ...

最新文章

  1. 你不知道的javascript事件
  2. 初识boost之boost::share_ptr用法
  3. 网络编程(part10)--socket套接字编程之UDP套接字
  4. 3-3 编程练习:jQuery键盘事件案例
  5. (195)FPGA上电后IO的默认状态(ISE软件默认为1)
  6. php导入导出xls表,TP5.0 PHPExcel 数据表格导出导入
  7. 小辣椒手机创始人王晓雁加入小米;手机 QQ 可显示对方实时电量;Git Extensions 3.3.1 发布 | 极客头条...
  8. codeforces 580C Kefa and Park(DFS)
  9. 【机器学习系列】MCMC第四讲:Metropolis Hastings采样算法
  10. 动视暴雪利润下降22%,投身移动端能否重回王座?
  11. python关键词排名批量查排名_Python批量查询百度排名
  12. Ubuntu中禁止与使能鼠标中键的复制功能(vscode出现莫名其妙的多余的代码段)
  13. 3D中的OBJ文件格式详解
  14. 决策规划算法二:生成参考线(FEM_POS_DEVIATION_SMOOTHING)
  15. (Docker实战)在CentOS7上使用Docker;(超详细、附图、附代码)
  16. 图片与文字排版-flex
  17. 滴滴十大技术方向开源项目出炉!有点牛啊!
  18. 华兴数控g71外圆循环编程_华兴数控的循环指令是怎么定义的。也就是G71。G72。那样的。...
  19. Python-列表切片list[-1]、list[-1:]、list[:-1]、list[::1]、list[::-1]的区别
  20. 中国碱性电解二氧化锰市场行业动态与投资规划分析报告2022-2028年

热门文章

  1. C++的 RTTI 观念和用途
  2. LFM算法详解和实战
  3. 《MySQL必知必会》学习笔记——第五章(排序检索数据)
  4. 2、两数相加(python)
  5. 283、移动零(python)
  6. Python中将字典保存为文件并读取
  7. 计算机组成原理学习-哈工大《计算机组成原理》第四章-上篇
  8. javaSE基础篇之char
  9. 在成长中遇到的挫折事件对你的影响_孩子一遇到困难就退缩?3个方法培养孩子逆商,提升抗挫折能力...
  10. 计算机主页为什么打不开怎么办,主页被限制,打不开怎么办?