虽然这道题是个简单题,但对于我这样的弱渣还是研究了好久,而且自己根据大白书写的代码始终不对,无奈最后还是抄袭大神代码,

通过这个题得到下面几条心得,

1.做计算几何一定要注意精度问题,很难有绝对的相等,主要相对精度而言

2.做计算几何比较繁琐,一定要理清思路,代码思路一定要清晰

由于感觉大神的代码思路清晰,而且代码风格比较好,特贴出大神代码

,以及我自己按照大白书写的始终WA的代码,留着没事思考人生:

大神代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<string>
using namespace std;
const double eps=1e-6;
const double pi=acos(-1.0);
int dcmp(double x)
{if(fabs(x)<eps) return 0;return x>eps?1:-1;
}
struct point
{double x,y;point(){}point(double x,double y):x(x),y(y){}point operator + (const point &t) const{return point(x+t.x,y+t.y);}point operator - (const point &t) const{return point(x-t.x,y-t.y);}point operator * (const double &t) const{return point(x*t,y*t);}point operator / (const double &t) const{return point(x/t,y/t);}bool operator < (const point &t) const{return x+eps<t.x||(!dcmp(x-t.x)&&y<t.y);}double len(){return sqrt(x*x+y*y);}double len2(){return x*x+y*y;}point normal(){return point(-y,x)/len();}void in(){cin>>x>>y;}void out(){printf("(%.6f,%.6f)",x,y);}
};
double dis(point a,point b)
{return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
point rotate(point a,double ct)
{return point(a.x*cos(ct)-a.y*sin(ct),a.y*cos(ct)+a.x*sin(ct));
}
double cross(point a,point b)
{return a.x*b.y-a.y*b.x;
}
double dot(point a,point b)
{return a.x*b.x+a.y*b.y;
}
double fix(double x)
{if(x<-eps) x+=pi;return x*180./pi;
}
double angle(point v)
{return atan2(v.y,v.x);
}
double disPointToLine(point a,point l,point r)
{return fabs(cross(a-l,r-l))/dis(l,r);
}
struct Line
{point a,v;void in(){a.in();v.in();v=v-a;}Line(){}Line(point a,point v):a(a),v(v){}
};
void lineLineIntersect(Line l,Line r,vector<point> &sol)
{double t=cross((r.a-l.a),r.v)/cross(l.v,r.v);sol.push_back(l.a+l.v*t);
}
struct Circle
{point o;double r;void in(){o.in();cin>>r;}point getpoint(double ct){return point(r*cos(ct),r*sin(ct))+o;}void out(){printf("(%.6f,%.6f,%.6f)\n",o.x,o.y,r);}Circle(point o,double r):o(o),r(r){}Circle(){}
};
void cirLineIntersect(Circle C,Line L,vector <point> &sol)
{double e=L.v.len2(),f=dot(L.a-C.o,L.v)*2,g=(L.a-C.o).len2()-C.r*C.r;double dlt=f*f-4*e*g;if(dlt<-eps) return;if(dlt<eps){double t=-f/(2*e);sol.push_back(L.v*t+L.a);return ;}dlt=sqrt(dlt);double t1=(-f+dlt)/(2*e),t2=(-f-dlt)/(2*e);sol.push_back(L.v*t1+L.a);sol.push_back(L.v*t2+L.a);
}
void cirCirIntersect(Circle C1,Circle C2, vector <point> &sol)
{point v=C2.o-C1.o;double d=v.len();if(dcmp(d-C1.r-C2.r)>0) return;double ct=angle(v),alf=acos((C1.r*C1.r+d*d-C2.r*C2.r)/(2*C1.r*d));sol.push_back(C1.getpoint(ct+alf));if(dcmp(alf)>eps) sol.push_back(C1.getpoint(ct-alf));
}
Circle CircumscribedCircle(point p1,point p2,point p3)
{double bx = p2.x-p1.x, by = p2.y-p1.y;double cx = p3.x-p1.x, cy = p3.y-p1.y;double d = 2*(bx*cy-by*cx);double ox = (cy*(bx*bx+by*by) - by*(cx*cx+cy*cy))/d + p1.x;double oy = (bx*(cx*cx+cy*cy) - cx*(bx*bx+by*by))/d + p1.y;point o = point(ox, oy);return Circle(o,dis(o,p1));
}
Circle InscribedCircle(point p1, point p2, point p3)
{double a = dis(p2, p3);double b = dis(p1, p3);double c = dis(p1, p2);point o = (p1*a+p2*b+p3*c)/(a+b+c);return Circle(o, disPointToLine(o, p1, p2));
}
vector<double> TangentLineThroughPoint(point p,Circle c)
{vector<double> sol;point u=c.o-p;double d=u.len();if(d+eps<c.r) return sol;else if(!dcmp(d-c.r)){sol.push_back(fix(angle(rotate(u,-pi/2))));}else{double alf=asin(c.r/d);sol.push_back(fix(angle(rotate(u,-alf))));sol.push_back(fix(angle(rotate(u,alf))));}sort(sol.begin(),sol.end());return sol;
}
vector <point> CircleThroughAPointAndTangentToALineWithRadius(point o, Line L, double r) {vector <point> sol;point v = L.v.normal();cirLineIntersect(Circle(o, r), Line(L.a+v*r, L.v), sol);cirLineIntersect(Circle(o, r), Line(L.a-v*r, L.v), sol);sort(sol.begin(), sol.end());return sol;
}vector <point> CircleTangentToTwoLinesWithRadius(Line L1, Line L2, double r) {vector <point> sol;point v1 = L1.v.normal();point v2 = L2.v.normal();lineLineIntersect(Line(L1.a+v1*r, L1.v), Line(L2.a+v2*r, L2.v), sol);lineLineIntersect(Line(L1.a+v1*r, L1.v), Line(L2.a-v2*r, L2.v), sol);lineLineIntersect(Line(L1.a-v1*r, L1.v), Line(L2.a+v2*r, L2.v), sol);lineLineIntersect(Line(L1.a-v1*r, L1.v), Line(L2.a-v2*r, L2.v), sol);sort(sol.begin(), sol.end());return sol;
}
vector <point> CircleTangentToTwoDisjointCirclesWithRadius(Circle C1, Circle C2, double r) {vector <point> sol;cirCirIntersect(Circle(C1.o, C1.r+r), Circle(C2.o, C2.r+r), sol);sort(sol.begin(), sol.end());return sol;
}string op;
void print(vector <point> sol) {printf("[");for(int i = 0; i < sol.size(); i++) {sol[i].out();if(i != sol.size()-1) printf(",");}printf("]\n");
}
int main() {while(cin >> op) {if(op == "CircumscribedCircle") {point a, b, c;a.in(), b.in(), c.in();CircumscribedCircle(a, b, c).out();}else if(op == "InscribedCircle") {point a, b, c;a.in(), b.in(), c.in();InscribedCircle(a, b, c).out();}else if(op == "TangentLineThroughPoint") {Circle c; point p;c.in(); p.in();vector <double> ans = TangentLineThroughPoint(p, c);printf("[");for(int i = 0; i < ans.size(); i++) {printf("%.6f", ans[i]);if(i != ans.size()-1) printf(",");}printf("]\n");}else if(op == "CircleThroughAPointAndTangentToALineWithRadius") {point p; Line l; double r;p.in(), l.in(), scanf("%lf", &r);print(CircleThroughAPointAndTangentToALineWithRadius(p, l, r));}else if(op == "CircleTangentToTwoLinesWithRadius") {Line L1, L2; double r;L1.in(); L2.in(); scanf("%lf", &r);print(CircleTangentToTwoLinesWithRadius(L1, L2, r));}else if(op == "CircleTangentToTwoDisjointCirclesWithRadius") {Circle c1, c2; double r;c1.in(); c2.in(); scanf("%lf", &r);print(CircleTangentToTwoDisjointCirclesWithRadius(c1, c2, r));}}return 0;
}

自己的WA代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<string>
#include<map>
#include<vector>
#include<set>
using namespace std;
const double eps=1e-6;
const double  PI=acos(-1.0);
int dcmp(double x)
{if(fabs(x)<eps)return 0;return x>eps?1:-1;
}
struct Point
{double x,y;Point(){}Point(double x,double y):x(x),y(y){}
};
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);
}
bool operator <(const Point &a,const Point &b)
{return a.x+eps<b.x||(!dcmp(a.x-b.x)&&a.y<b.y);
}
//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));
}
double Angle(Vector A,Vector B)
{return acos(Dot(A,B)/Length(A)/Length(B));
}
double Cross(Vector A,Vector B)
{return A.x*B.y-A.y*B.x;
}
Vector Rotate(Vector A,double rad)
{return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
Vector Normal(Vector A)
{double L=Length(A);return Vector(-A.y/L,A.x/L);
}
double DistaceToLine(Point P,Point A,Point B)
{Vector v1=B-A,v2=P-A;return fabs(Cross(v1,v2)/Length(v1));
}
double angle(Vector v)
{return atan2(v.y,v.x);
}
double fix(double x)
{if(x<-eps)x+=PI;return x*180.0/PI;
}
struct Line
{Point p;Vector v;Line() {}Line(Point p,Vector v):p(p),v(v){};Point point(double t){return Point(v*t+p);}
};
Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)
{Vector u=P-Q;double t=Cross(w,u)/Cross(v,w);return Vector(P+v*t);
}
struct Circle
{Point c;double r;Circle(Point c,double r):c(c),r(r){}Circle() {}Point point(double a){return Point(c.x+cos(a)*r,c.y+sin(a)*r);}
};
void getLineCircleIntersection(Line L,Circle C,vector<Point> &sol)
{double t1,t2;double a=L.v.x,b=L.p.x-C.c.x,c=L.v.y,d=L.p.y-C.c.y;double e=a*a+c*c,f=2*(a*b+c*d),g=b*b+d*d-C.r*C.r;double delta=f*f-4*e*g;if(delta<-eps) return;if(delta<eps){t1=t2=-f/(2*e);sol.push_back(L.point(t1));return;}t1=(-f-sqrt(delta))/(2*e);sol.push_back(L.point(t1));t2=(-f+sqrt(delta))/(2*e);sol.push_back(L.point(t2));
}
void getCircleIntersection(Circle C1,Circle C2,vector<Point> &sol)
{double d=Length(C1.c-C2.c);if(dcmp(d-C1.r-C2.r)>0) return;double a=angle(C2.c-C1.c);double da=acos((C1.r*C1.r+d*d-C2.r*C2.r)/(2*C1.r*d));sol.push_back(C1.point(a+da));if(dcmp(da)>eps)sol.push_back(C1.point(a-da));
}
void work1()
{Point A,B,C;cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y;Vector p1=A-B;Vector t1=Normal(p1);Point mid1=(A+B)/2;Vector p2=C-B;Vector t2=Normal(p2);Point mid2=(B+C)/2;Point T=GetLineIntersection(mid1,t1,mid2,t2);double r=Length(A-T);printf("(%.6f,%.6f,%.6f)\n",T.x,T.y,r);/*   Point p1,p2,p3;cin>>p1.x>>p1.y>>p2.x>>p2.y>>p3.x>>p3.y;double Bx=p2.x-p1.x,By=p2.y-p1.y;double Cx=p3.x-p1.x,Cy=p3.y-p1.y;double D=2*(Bx*Cy-By*Cx);double cx=(Cy*(Bx*Bx+By*By)-By*(Cx*Cx+Cy*Cy))/D+p1.x;double cy=(Bx*(Cx*Cx+Cy*Cy)-Cx*(Bx*Bx+By*By))/D+p1.y;Point p=Point(cx,cy);printf("(%.6f,%.6f,%.6f)\n",p.x,p.y,Length(p1-p));*/
}
void work2()
{Point A,B,C;cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y;Vector p1=A-B;Vector p2=C-B;Vector p3=C-A;double radb=Angle(p1,p2);double radc=Angle(p2,p3);cout<<radb<<radc<<endl;Vector BD=Rotate(p2,radb/2);Vector CD=Rotate(p3,radc/2);Point T=GetLineIntersection(B,BD,C,CD);double r=DistaceToLine(T,A,B);printf("(%.6f,%.6f,%.6f)\n",T.x,T.y,r);/*  Point p1,p2,p3;cin>>p1.x>>p1.y>>p2.x>>p2.y>>p3.x>>p3.y;double a=Length(p2-p3);double b=Length(p3-p1);double c=Length(p1-p2);Point p=(p1*a+p2*b+p3*c)/(a+b+c);double r=DistaceToLine(p,p1,p2);printf("(%.6f,%.6f,%.6f)\n",p.x,p.y,r);*/
}
void work3()
{Circle C;Point p;cin>>C.c.x>>C.c.y>>C.r>>p.x>>p.y;// Circle C(c,r);Vector u=C.c-p;//  cout<<u.x<<endl<<u.y<<endl;double dist=Length(u);//  cout<<dist<<endl;if(dist+eps<C.r)printf("[]\n");else if(dcmp(dist-C.r)==0){Vector v=Rotate(u,-PI/2);//   cout<<v.x<<endl<<v.y<<endl;//  double radd=rad+PI/2;// if(radd==PI) radd-=PI;printf("[%.6f]\n",fix(angle(v)));}else{double ang=asin(C.r/dist);Vector v1=Rotate(u,-ang);Vector v2=Rotate(u,ang);double rad1=angle(v1);double rad2=angle(v2);if(rad1<rad2) swap(rad1,rad2);printf("[%.6f,%.6f]\n",fix(rad1),fix(rad2));}
}
void work4()
{Point p,p1,p2;double r;cin>>p.x>>p.y>>p1.x>>p1.y>>p2.x>>p2.y;cin>>r;Line L(p1,p2-p1);Circle C(p,r);vector <Point> sol;Vector cc=Normal(L.v);getLineCircleIntersection(Line(L.p+cc*r,L.v),C,sol);getLineCircleIntersection(Line(L.p-cc*r,L.v),C,sol);sort(sol.begin(),sol.end());// cout<<sol.size()<<endl;cout<<"[";for(int i=0;i<sol.size();i++){printf("(%.6f,%.6f)",sol[i].x,sol[i].y);if(i!=sol.size()-1) cout<<",";}cout<<"]"<<endl;
}
void work5()
{Point p1,p2,p3,p4;double r;cin>>p1.x>>p1.y>>p2.x>>p2.y>>p3.x>>p3.y>>p4.x>>p4.y>>r;Line L1(p1,p2-p1),L2(p3,p4-p3);Vector LN1=Normal(L1.v);Vector LN2=Normal(L2.v);vector <Point> sol;sol.push_back(GetLineIntersection(L1.p+LN1*r,L1.v,L2.p+LN2*r,L2.v));sol.push_back(GetLineIntersection(L1.p+LN1*r,L1.v,L2.p-LN2*r,L2.v));sol.push_back(GetLineIntersection(L1.p-LN1*r,L1.v,L2.p+LN2*r,L2.v));sol.push_back(GetLineIntersection(L1.p-LN1*r,L1.v,L2.p-LN2*r,L2.v));sort(sol.begin(),sol.end());cout<<"[";for(int i=0;i<sol.size();i++){printf("(%.6f,%.6f)",sol[i].x,sol[i].y);if(i!=sol.size()-1) cout<<",";}cout<<"]"<<endl;
}
void work6()
{Circle C1,C2;double r;cin>>C1.c.x>>C1.c.y>>C1.r>>C2.c.x>>C2.c.y>>C2.r>>r;vector<Point> sol;getCircleIntersection(Circle(C1.c,C1.r+r),Circle(C2.c,C2.r+r),sol);sort(sol.begin(),sol.end());cout<<"[";for(int i=0;i<sol.size();i++){printf("(%.6f,%.6f)",sol[i].x,sol[i].y);if(i!=sol.size()-1) cout<<",";}cout<<"]"<<endl;
}
int main()
{string s;while(cin>>s){if(s=="CircumscribedCircle")work1();else if(s=="InscribedCircle")work2();else if(s=="TangentLineThroughPoint")work3();else if(s=="CircleThroughAPointAndTangentToALineWithRadius")work4();else if(s=="CircleTangentToTwoLinesWithRadius")work5();else if(s=="CircleTangentToTwoDisjointCirclesWithRadius")work6();}return 0;
}

UVA12304直线,圆,点的综合应用相关推荐

  1. 相控阵天线(九):平面阵列天线综合(不可分离型切比雪夫分布、圆口径泰勒综合、可分离型分布、配相抵消法)

    目录 简介 不可分离型分布 不可分离型切比雪夫 圆口径泰勒综合 可分离型分布 可分离切比雪夫综合 可分离泰勒综合 平面阵列配相抵消法 简介 按行.列排列的可分离型矩形平面阵,其阵因子是两个正交排列的直 ...

  2. halcon中如何生成椭圆_Halcon拟合系列(2)直线/圆/椭圆/矩形拟合算子

    fit_line_contour_xld.hdev fit_line_contour_xld(Contours : : Algorithm, MaxNumPoints, ClippingEndPoin ...

  3. 在MFC中,利用GDI绘制橡皮筋效果-直线,圆,椭圆,矩形

    这段时间学习了GDI和GDI+:如果想实现橡皮筋效果,还是离不开GDI.虽然GDI+也能实现,但比较麻烦,有局限性,必须用到双缓冲. 下面贴出GDI绘制橡皮筋效果的示例代码 ZKCADView.h: ...

  4. 相控阵天线(六):直线阵列天线特殊综合方法(变形泰勒综合法、贝利斯综合法、伍德沃德抽样法)

    目录 简介 变形泰勒综合法 贝利斯综合法 伍德沃德-劳森抽样法 配相抵消法 简介 阵列天线的综合问题是其分析的逆问题,即是在预先给定辐射特性(如方向图形状.副瓣电平等)的情况下,综合出阵列激励幅度和相 ...

  5. 相控阵天线之直线阵列综合

    简介 可以参考我最新的博文相控阵天线(三):直线阵列天线低副瓣综合(切比雪夫.泰勒分布.SinZ-Z和Villeneuve分布.含python代码). 本博客对常见的直线阵列综合方式如:切比雪夫.泰勒 ...

  6. [圆反演][笛卡尔定理]Rohith and Circles

    由于第一次做圆反演类型的题,进行了一番学习,于是就有的这篇博客. 题目描述 大厨有一个朋友叫 Rohith,他非常擅长几何.有一天大厨遇到了一道非常有意思的关于圆的题目,马上就跟 Rohith 分享. ...

  7. 相控阵天线分析综合、设计与测试

    目录 概述 HFSS特殊曲线天线建模 直线阵列天线特性和阵列因子(方向图乘积定理.波束扫描) 非规则直线阵列天线(稀布阵列.稀疏阵列.平方率分布阵列) 直线阵列天线低副瓣综合(切比雪夫.泰勒分布.Si ...

  8. javase哪部分最难_高中物理哪部分最难?这里有答案和方法!一定要收藏

    高中物理最难的部分是什么?对于大多数同学来说,电粒子在电磁场中的运动.动力学分析以及电学实验比较难搞定,看看下面的方法,希望对你有所帮助.从应试而言,应是带电粒子在电磁场中的运动(力,运动轨迹,几何特 ...

  9. 数学三大核心领域概述:代数、几何、分析

    数学发展到现在,已经成为科学世界中拥有100多个主要分支学科的庞大的"共和国".大体说来数学有三大核心领域: >>>> 数学中研究数的部分属于代数学的范畴: ...

最新文章

  1. Yacc 与 Lex 快速入门(词法分析和语法分析)
  2. SQLServer 大小写敏感配置
  3. Webservice开发之xsd中开发list请求参数的接口
  4. 资源分享 | 统计学最全思维导图,附下载链接
  5. Val编程-任务编程
  6. 计算机操作系统的新技术新知识,计算机操作系统教程:核心与设计原理
  7. C++中的也能使用正则表达式
  8. linux打包工具tar及一些压缩工具
  9. 如何用WinCC发送报警消息至钉钉
  10. php 加密解密算法
  11. php kindeditor,在PHP使用kindeditor
  12. Linux环境MySQL卸载教程
  13. lpb.wifi index.php,lpb(法国lpb是什么品牌)
  14. C语言求 阶乘 5!
  15. 6个UI面试技巧让你轻松入职大公司
  16. Tomcat修行之路-3.类加载机制的原理
  17. PB实现国密SM2/SM3/SM4算法(DLL方式)
  18. 2021江苏大学生编程大赛I题(省赛试水)
  19. 21.VIVO: Visual Vocabulary Pre-Training for Novel Object Captioning
  20. echarts 折线图 设置y轴最小刻度_用plotly和plt画图的基本设置(标题、坐标轴、图例、注释、图像)...

热门文章

  1. 二硬脂酰磷脂酰乙醇胺-聚乙二醇-巯基吡啶 DSPE-PEG-OPSS;常用于脂质体的合成
  2. 云计算-华为虚拟化平台FusionCompute
  3. opencv修改图片大小
  4. Log4j2维护者吐槽没工资还要挨骂!!!
  5. 论文略读:《地区如何随着时间的推移而多样化?产业关系与地区新增长路径的发展》
  6. mysql查询结果百分比表示_MySQL 查询结果以百分比显示简单实现
  7. 程序员都在读的实战书,你看懂封面了吗?
  8. 画册书籍封面设计|PSD分层模板
  9. 概率论由相关性求数学期望和方差的公式_概率论与数理统计(马涛)第4章——数学期望与方差.ppt...
  10. SmartRF04EB修复与修改ID号