题意:
这道题目就是单纯的计算几何的板子,我照着板子自己敲了一遍,希望大家不熟悉板子的也可以自己敲一下。
两点:

  1. 要选择适合自己的板子
  2. 注意最后结果要排序

题目要求的六种结果:

  1. 三角形的外接圆
  2. 三角形的内切圆
  3. 过定点的圆的切线
  4. 过定点并且与给定直线相切的圆
  5. 与两条给定直线相切的圆
  6. 与不相交的两个圆相切的圆
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
using namespace std;
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxn = 1010;
int sgn(double x){if(fabs(x)<eps)return 0;if(x<0)return -1;else return 1;
}
struct Point {double x,y;Point (){};Point (double _x,double _y){x=_x;y=_y;}void input(){scanf("%lf%lf",&x,&y);}bool operator < (Point b)const{return sgn(x-b.x)==0?sgn(y-b.y)<0:x<b.x;}bool operator == (Point b)const{return sgn(x-b.x)==0&&sgn(y-b.y)==0;}Point operator + (const Point &b)const{return Point(x+b.x,y+b.y);}Point operator - (const Point &b)const{return Point(x-b.x,y-b.y);}Point operator / (const double &b)const{return Point (x/b,y/b);}Point operator * (const double &b)const{return Point (x*b,y*b);}double operator ^ (const Point &b)const{return x*b.y-y*b.x;}double operator * (const Point &b)const{return x*b.x+y*b.y;}double len(){return hypot(x,y);}double len2(){return x*x+y*y;}Point trunc(double r){double l=len();if(!sgn(l))return *this;r/=l;return Point(x*r,y*r);}Point rotleft(){return Point(-y,x);}Point rotright(){return Point(y,-x);}double distance (Point p){return hypot(x-p.x,y-p.y);}
};
struct Line{Point s,e;Line(){};Line(Point _s,Point _e){s=_s;e=_e;}void input(){s.input();e.input();}double legth(){return s.distance (e);}double angle(){double k=atan2(e.y-s.y,e.x-s.x);if(sgn(k)<0)k+=pi;if(sgn(k-pi)==0)k-=pi;return k;}Point cross_point(Line v){double a1 = (v.e-v.s)^(s-v.s);double a2 = (v.e-v.s)^(e-v.s);return Point ((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));}double dis_point_to_line(Point p){return fabs((p-s)^(e-s))/legth();}double dis_point_to_seg(Point p){if(sgn((p-s)*(e-s))<0||sgn((p-e)*(s-e))<0)return min(p.distance(s),p.distance(e));return dis_point_to_line(p);}//返回点p在直线上的投影Point line_prog(Point p){return s+(((e-s)*((e-s)*(p-s)))/((e-s).len2()));}bool parallel (Line v){return sgn((e-s)^(v.e-v.s))==0;}
};
struct circle{Point p;double r;circle(){};circle(Point _p,double _r){p=_p;r=_r;}circle(double x,double y,double _r){p=Point(x,y);r=_r;}//三角形的外接圆circle(Point a,Point b,Point c){Line u = Line((a+b)/2,((a+b)/2)+((b-a).rotleft()));Line v = Line((b+c)/2,((b+c)/2)+((c-b).rotleft()));p = u.cross_point(v);r = p.distance(a);}//三角形内切圆circle(Point a,Point b,Point c,bool t){Line u,v;double m = atan2(b.y-a.y,b.x-a.x), n = atan2(c.y-a.y,c.x-a.x);u.s=a;u.e=u.s+Point(cos((n+m)/2),sin((n+m)/2));v.s=b;m=atan2(a.y-b.y,a.x-b.x), n= atan2(c.y-b.y,c.x-b.x);v.e = v.s+Point(cos((n+m)/2),sin((n+m)/2));p = u.cross_point(v);r = Line(a,b).dis_point_to_seg(p);}void input(){p.input();scanf("%lf",&r);}int relation_point(Point b){double dist = b.distance(p);if(sgn(dist - r)<0)return 2;else if(sgn(dist - r)==0) return 1;return 0;}//求直线和圆的交点int relation_line(Line v){double dist = v.dis_point_to_line(p);if(sgn(dist-r)<0)return 2;else if(sgn(dist-r)==0) return 1;return 0;}int relation_circle(circle v){double d = p.distance(v.p);if(sgn(d-r-v.r)>0)return 5;if(sgn(d-r-v.r)==0)return 4;double l =fabs(r-v.r);if(sgn(d-r-v.r)<0&&sgn(d-l)>0)return 3;if(sgn(d-l)==0)return 2;if(sgn(d-l)<0)return 1;}int point_cross_line(Line v,Point &p1,Point &p2){if(!(*this).relation_line(v))return 0;Point a = v.line_prog(p);double d = v.dis_point_to_line(p);d = sqrt(r*r-d*d);if(sgn(d)==0){p1=a;p2=a;return 1;}p1 = a+(v.e-v.s).trunc(d);p2 = a-(v.e-v.s).trunc(d);return 2;}int point_cross_circle(circle v,Point &p1,Point &p2){int rel = relation_circle(v);if(rel==1||rel==5)return 0;double d = p.distance(v.p);double l = (d*d+r*r-v.r*v.r)/(2*d);double h = sqrt(r*r-l*l);Point temp = p+(v.p-p).trunc(l);p1=temp + ((v.p-p).rotleft().trunc(h));p2=temp + ((v.p-p).rotright().trunc(h));if(rel == 2||rel ==4){return 1;}return 2;}int tangent_line(Point q,Line &u,Line &v){int x = relation_point(q);if(x==2) return 0;if(x==1){u=Line(q,q+(q-p).rotleft());v=u;return 1;}double d=p.distance (q);double l=r*r/d;double h=sqrt(r*r-l*l);u=Line(q,p+((q-p).trunc(l)+(q-p).rotleft().trunc(h)));v=Line(q,p+((q-p).trunc(l)+(q-p).rotright().trunc(h)));return 2;}//得过与直线u相切,过点q,半径为r1的圆int get_circle(Line u,Point q,double r1,circle &c1,circle &c2){double dis=u.dis_point_to_line(q);if(sgn(dis-r1*2)>0)return 0;if(sgn(dis)==0){c1.p=q+((u.e-u.s).rotleft().trunc(r1));c2.p=q+((u.e-u.s).rotright().trunc(r1));c1.r=c2.r=r1;return 2;}Line u1=Line((u.s+(u.e-u.s).rotleft().trunc(r1)),(u.e+(u.e-u.s).rotleft().trunc(r1)));Line u2=Line((u.s+(u.e-u.s).rotright().trunc(r1)),(u.e+(u.e-u.s).rotright().trunc(r1)));circle cc=circle(q,r1);Point p1,p2;if(!cc.point_cross_line(u1,p1,p2))cc.point_cross_line(u2,p1,p2);c1=circle(p1,r1);if(p1==p2){c2=c1;return 1;}c2=circle(p2,r1);return 2;}//同时与直线u,v相切,半径为r1的圆;int get_circle(Line u,Line v,double r1,circle &c1,circle &c2,circle &c3,circle &c4){if(u.parallel(v))return 0;Line u1=Line(u.s+(u.e-u.s).rotleft().trunc(r1),u.e+(u.e-u.s).rotleft().trunc(r1));Line u2=Line(u.s+(u.e-u.s).rotright().trunc(r1),u.e+(u.e-u.s).rotright().trunc(r1));Line v1=Line(v.s+(v.e-v.s).rotleft().trunc(r1),v.e+(v.e-v.s).rotleft().trunc(r1));Line v2=Line(v.s+(v.e-v.s).rotright().trunc(r1),v.e+(v.e-v.s).rotright().trunc(r1));c1.r=c2.r=c3.r=c4.r=r1;c1.p=u1.cross_point(v1);c2.p=u1.cross_point(v2);c3.p=u2.cross_point(v1);c4.p=u2.cross_point(v2);return 4;}//同时与不相交的两个圆cx,cy相切  ,半径为r1的圆int get_circle(circle cx,circle cy,double r1,circle &c1,circle &c2){circle x(cx.p,r1+cx.r),y(cy.p,r1+cy.r);int t=x.point_cross_circle(y,c1.p,c2.p);if(!t)return 0;c1.r=c2.r=r1;return t;}
};
int main()
{string s;while(cin>>s){if(s=="CircumscribedCircle"){Point a1,a2,a3;a1.input();a2.input();a3.input();circle ans(a1,a2,a3);printf("(%.6lf,%.6lf,%.6lf)\n",ans.p.x,ans.p.y,ans.r);}if(s=="InscribedCircle"){Point a1,a2,a3;a1.input();a2.input();a3.input();circle ans(a1,a2,a3,true);printf("(%.6lf,%.6lf,%.6lf)\n",ans.p.x,ans.p.y,ans.r);}if(s=="TangentLineThroughPoint"){circle c;c.input();Point pp;pp.input();Line uu,vv;int ans=c.tangent_line(pp,uu,vv);if(ans==0)printf("[]\n");if(ans==1)printf("[%.6lf]\n",uu.angle()/pi*180.0);if(ans==2){double res[5];res[0]=uu.angle();res[1]=vv.angle();sort(res,res+2);printf("[%.6lf,%.6lf]\n",res[0]/pi*180.0,res[1]/pi*180.0);}}if(s=="CircleThroughAPointAndTangentToALineWithRadius"){Point pp;pp.input();Line uu;uu.input();double rr;scanf("%lf",&rr);circle c,c1,c2;int ans=c.get_circle(uu,pp,rr,c1,c2);if(ans==0)printf("[]\n");if(ans==1)printf("[(%.6lf,%.6lf)]\n",c1.p.x,c1.p.y);if(ans==2){Point yx[5];yx[0]=c1.p;yx[1]=c2.p;sort(yx,yx+2);printf("[(%.6lf,%.6lf),(%.6lf,%.6lf)]\n",yx[0].x,yx[0].y,yx[1].x,yx[1].y);}}if(s=="CircleTangentToTwoLinesWithRadius"){Line u,v;double r1;circle c,c1,c2,c3,c4;u.input();v.input();scanf("%lf",&r1);c.get_circle(u,v,r1,c1,c2,c3,c4);Point yx[5];yx[0]=c1.p;yx[1]=c2.p;yx[2]=c3.p;yx[3]=c4.p;sort(yx,yx+4);printf("[(%.6lf,%.6lf),(%.6lf,%.6lf),(%.6lf,%.6lf),(%.6lf,%.6lf)]\n",yx[0].x,yx[0].y,yx[1].x,yx[1].y,yx[2].x,yx[2].y,yx[3].x,yx[3].y);}if(s=="CircleTangentToTwoDisjointCirclesWithRadius"){circle c,cx,cy,c1,c2;cx.input();cy.input();double r1;scanf("%lf",&r1);int ans=c.get_circle(cx,cy,r1,c1,c2);if(ans==0)printf("[]\n");if(ans==1)printf("[(%.6lf,%.6lf)]\n",c1.p.x,c1.p.y);if(ans==2){Point yx[5];yx[0]=c1.p;yx[1]=c2.p;sort(yx,yx+2);printf("[(%.6lf,%.6lf),(%.6lf,%.6lf)]\n",yx[0].x,yx[0].y,yx[1].x,yx[1].y);}}}
}

UVA - 12304(B - 2D Geometry 110 in 1!)计算几何板子相关推荐

  1. LA 3263 That Nice Euler Circuit (2D Geometry)

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  2. UVA 11178 Morley’s Theorem(莫雷定理 计算几何)

    Morley's Theorem Input: Standard Input Output: Standard Output Morley's theorem states that that the ...

  3. 第7期:计算几何(持续更新中......)

    // 2022/01/22更新 更新内容主要为算法竞赛入门经典--训练指南(升级版)(刘汝佳.陈锋编著)第4章几何问题 1 二维几何基础 在平面坐标系下,向量和点一样,也用两个数x,y表示.第6章介绍 ...

  4. 1、DirectX 系列之 Direct 2D

    Direct 2D是一个 采用立即模式 绘图的2D 图形API,也就是跟显卡驱动打交道的一个小程序,图形业务能力包括 2-D geometry, bitmaps, and text. WM_Paint ...

  5. CGAL中2D三角剖分

    @TOCCGAL 2D三角剖分 三角剖分概念 三角剖分是代数拓扑学里最基本的研究方法. 特性:(1)每一个面都是一个三角形(2)任何两个这样的曲边三角形,要么不相交,要么恰好相交于一条公共边 CGAL ...

  6. Python库全部整理出来了,非常全面

    库名称简介 Chardet 字符编码探测器,可以自动检测文本.网页.xml的编码. colorama 主要用来给文本添加各种颜色,并且非常简单易用. Prettytable 主要用于在终端或浏览器端构 ...

  7. 1000+ 常用 Python 库一览

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 来源 | 法纳斯特 这次给大家总结整理了1000+常用Python库 ...

  8. [读书笔记]《Head First Servlets JSP》2nd

    书名:Head First Servlets and JSP: Passing the Sun Certified Web Component Developer Exam 出版商:O'Reilly ...

  9. 【python】整理的 Python 库

    常用库 Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主要用于在终端或浏览器端构建格式化的 ...

  10. 使用WPF创建画图箭头

    使用WPF创建画图箭头 原文:使用WPF创建画图箭头 今天要给leader line画个箭头,所以就google一下,找到下面的文章,写的不错,可以实现我的需求,所以就摘录下来. 我把源代码中的arr ...

最新文章

  1. MySQL 中 6 个常见的日志问题
  2. 安卓指令和命令学习总结
  3. 【常见笔试面试算法题12续集一】动态规划算法案例1台阶问题练习题
  4. Android 系统(49)---Android获取窗口可视区域大小: getWindowVisibleDisplayFrame()
  5. 经典的同态滤波算法的优化及其应用参数配置。
  6. 混淆矩阵与精确度、召回率、F1 Score
  7. 软件因丢失.dll文件(未找到)而无法启动?
  8. android 打开微信代码,微信跳转浏览器或提示手机端打开HTML代码
  9. 浏览器被hao123劫持首页处理
  10. Android攻城狮重新认识Toast
  11. Workflow 在数据仓库建设中的应用与优化
  12. 计算机ps特效教程,计算机一级photoshop给照片制作半素描效果教程
  13. Android与GNU体系
  14. Linux 配置关掉虚拟防火墙
  15. html f12键的作用,电脑键盘中F1-F12每个功能键的作用您都知道吗?
  16. oracle 序列迁移
  17. 大学生查重网站有哪些
  18. [统计学教程] 第七章 假设检验
  19. 计算机插入的图片怎么改成线条格式,电脑把CAD转化为JPG格式后图片不清晰怎么办...
  20. Solid Converter PDF,PDF转Word的利器

热门文章

  1. 【jQWidgets】jqxGrid控件在页面上重新加载的问题
  2. 荣耀笔记本锐龙版和linux,在家办公的最佳利器:荣耀笔记本14锐龙版体验
  3. 寒假2019培训:白银莲花池-usaco2007(洛谷P2411)
  4. 程序员,金三银四该不该跳槽?
  5. 爱加密Android APk 原理解析
  6. win10读不到移动硬盘
  7. HTML heading
  8. OpenCV中踩过的坑系列 01- Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)
  9. E - Eddy的难题
  10. 洛谷刷题C语言:第一次,第二次,成交!、Bessie‘s Secret Pasture S、金币、Bookshelf B、东南西北