题目链接:https://cn.vjudge.net/problem/UVA-12304

题意:

作为题目大合集,有以下一些要求:

①给出三角形三个点,求三角形外接圆,求外接圆的圆心和半径。

②给出三角形三个点,求三角形内接圆,求内接圆的圆心和半径。

③给出一个圆,和一个点,求过该点的圆的切线与x轴的夹角(0<=angle<180);

④给出一条直线,一个点p,指定半径r,求经过点p的与直线相切的半径为r的圆;

⑤给出两条直线,求与这两条直线相切的圆;

⑥给出两个圆,求同时与这两个圆相切的圆;

题解:

综合运用平面几何模板即可。

AC代码:

#include<bits/stdc++.h>
using namespace std; //--------------------------------------计算几何模板 - st-------------------------------------- const double eps = 1e-; struct Point{
double x,y;
Point(double tx=,double ty=):x(tx),y(ty){}
};
typedef Point Vctor; //向量的加减乘除
Vctor operator + (Vctor A,Vctor B){return Vctor(A.x+B.x,A.y+B.y);}
Vctor operator - (Point A,Point B){return Vctor(A.x-B.x,A.y-B.y);}
Vctor operator * (Vctor A,double p){return Vctor(A.x*p,A.y*p);}
Vctor operator / (Vctor A,double p){return Vctor(A.x/p,A.y/p);}
bool operator < (Point A,Point B){return A.x < B.x || (A.x == B.x && A.y < B.y);} struct Line{
Point p;
Vctor v;
Line(Point p=Point(0,0),Vctor v=Vctor(,)):p(p),v(v){}
Point point(double t){return p + v*t;} //获得直线上的距离p点t个单位长度的点
};
struct Circle{
Point c;
double r;
Circle(Point tc=Point(,),double tr=):c(tc),r(tr){}
Point point(double a){return Point( c.x + cos(a)*r , c.y + sin(a)*r);}
}; int dcmp(double x)
{
if(fabs(x)<eps) return ;
else return (x<)?(-):();
}
bool operator == (Point A,Point B){return dcmp(A.x-B.x)== && dcmp(A.y-B.y)==;} //向量的点积,长度,夹角
double Dot(Vctor A,Vctor B){return A.x*B.x+A.y*B.y;}
double Length(Vctor A){return sqrt(Dot(A,A));}
double Angle(Vctor A,Vctor B){return acos(Dot(A,B)/Length(A)/Length(B));} //叉积,三角形面积
double Cross(Vctor A,Vctor B){return A.x*B.y-A.y*B.x;}
double TriangleArea(Point A,Point B,Point C){return Cross(B-A,C-A);} //向量的旋转,求向量的单位法线(即左转90度,然后长度归一)
Vctor Rotate(Vctor A,double rad){return Vctor( A.x*cos(rad) - A.y*sin(rad) , A.x*sin(rad) + A.y*cos(rad) );}
Vctor Normal(Vctor A)
{
double L = Length(A);
return Vctor(-A.y/L, A.x/L);
} //直线的交点
Point getLineIntersection(Line L1,Line L2)
{
Vctor u = L1.p-L2.p;
double t = Cross(L2.v,u)/Cross(L1.v,L2.v);
return L1.p + L1.v*t;
} //点到直线的距离
double DistanceToLine(Point P,Line L)
{
return fabs(Cross(P-L.p,L.v))/Length(L.v);
} //点到线段的距离
double DistanceToSegment(Point P,Point A,Point B)
{
if(A==B) return Length(P-A);
Vctor v1 = B-A, v2 = P-A, v3 = P-B;
if (dcmp(Dot(v1,v2)) < ) return Length(v2);
else if (dcmp(Dot(v1,v3)) > ) return Length(v3);
else return fabs(Cross(v1,v2))/Length(v1);
} //点到直线的映射
Point getLineProjection(Point P,Line L)
{
return L.v + L.v*Dot(L.v,P-L.p)/Dot(L.v,L.v);
} //判断线段是否规范相交
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)
{
double c1 = Cross(a2 - a1,b1 - a1), c2 = Cross(a2 - a1,b2 - a1),
c3 = Cross(b2 - b1,a1 - b1), c4 = Cross(b2 - b1,a2 - b1);
return dcmp(c1)*dcmp(c2)< && dcmp(c3)*dcmp(c4)<;
} //判断点是否在一条线段上
bool OnSegment(Point P,Point a1,Point a2)
{
return dcmp(Cross(a1 - P,a2 - P))== && dcmp(Dot(a1 - P,a2 - P))<;
} //多边形面积
double PolgonArea(Point *p,int n)
{
double area=;
for(int i=;i<n-;i++) area += Cross( p[i]-p[] , p[i + ]-p[] );
return area/;
} //判断圆与直线是否相交以及求出交点
int 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 = *(a*b + c*d), g = b*b + d*d - C.r*C.r;
double delta = f*f - 4.0*e*g;
if(dcmp(delta)<) return ;
else if(dcmp(delta)==)
{
t1 = t2 = -f/(2.0*e);
sol.push_back(L.point(t1));
return ;
}
else
{
t1 = (-f-sqrt(delta))/(2.0*e); sol.push_back(L.point(t1));
t2 = (-f+sqrt(delta))/(2.0*e); sol.push_back(L.point(t2));
return ;
}
} //判断并求出两圆的交点
double angle(Vctor v){return atan2(v.y,v.x);}
int getCircleIntersection(Circle C1,Circle C2,vector<Point> &sol)
{
double d = Length(C1.c - C2.c);
//圆心重合
if(dcmp(d)==)
{
if(dcmp(C1.r-C2.r)==) return -; //两圆重合
else return ; //包含关系
} //圆心不重合
if(dcmp(C1.r+C2.r-d)<) return ; // 相离
if(dcmp(fabs(C1.r-C2.r)-d)>) return ; // 包含 double a = angle(C2.c - C1.c);
double da = acos((C1.r*C1.r + d*d - C2.r*C2.r) / (*C1.r*d));
Point p1 = C1.point(a - da), p2 = C1.point(a + da);
sol.push_back(p1);
if(p1==p2) return ;
sol.push_back(p2);
return ;
} //求点到圆的切线
int getTangents(Point p,Circle C,vector<Line> &sol)
{
Vctor u=C.c-p;
double dis=Length(u);
if(dis<C.r) return ;
else if(dcmp(dis-C.r) == )
{
sol.push_back(Line(p,Rotate(u,M_PI/)));
return ;
}
else
{
double ang=asin(C.r/dis);
sol.push_back(Line(p,Rotate(u,-ang)));
sol.push_back(Line(p,Rotate(u,ang)));
return ;
}
} //求两圆的切线
int getCircleTangents(Circle A,Circle B,Point *a,Point *b)
{
int cnt = ;
if(A.r<B.r){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;
double base = angle(B.c - A.c);
//重合有无限多条
if(d2 == && dcmp(A.r - B.r) == ) return -;
//内切
if(dcmp(d2-rdiff*rdiff) == )
{
a[cnt] = A.point(base);
b[cnt] = B.point(base);
cnt++;
return ;
}
//有外公切线
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) == )
{
a[cnt] = A.point(base);
b[cnt] = B.point(M_PI + base);
cnt++;
}//两条内切线
else if(dcmp(d2-rsum*rsum) > )
{
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++;
}
return cnt;
} //--------------------------------------计算几何模板 - ed-------------------------------------- Circle CircumscribedCircle(Point p1,Point p2,Point p3) //求外切圆,三点不能共线
{
double up,down,x,y,r;
double& x1=p1.x, x2=p2.x, x3=p3.x;
double& y1=p1.y, y2=p2.y, y3=p3.y; up = (pow(x1,)-pow(x2,) + pow(y1,)-pow(y2,))*(y1-y3) - (pow(x1,)-pow(x3,) + pow(y1,)-pow(y3,))*(y1-y2);
down = *(y1-y3)*(x1-x2) - *(y1-y2)*(x1-x3);
x = up/down; up = (pow(x1,)-pow(x2,) + pow(y1,)-pow(y2,))*(x1-x3) - (pow(x1,)-pow(x3,) + pow(y1,)-pow(y3,))*(x1-x2);
down = *(y1-y2)*(x1-x3) - *(y1-y3)*(x1-x2);
y = up/down; r = sqrt( pow(x1-x,)+pow(y1-y,) ); return Circle(Point(x,y),r);
} Circle InscribedCircle(Point p1,Point p2,Point p3) //求内切圆,三点不能共线
{
double a,b,c,x,y,r;
double& x1=p1.x, x2=p2.x, x3=p3.x;
double& y1=p1.y, y2=p2.y, y3=p3.y; a = sqrt( pow(x2-x3,) + pow(y2-y3,) );
b = sqrt( pow(x3-x1,) + pow(y3-y1,) );
c = sqrt( pow(x1-x2,) + pow(y1-y2,) ); x = ( a*x1 + b*x2 + c*x3 )/( a+b+c );
y = ( a*y1 + b*y2 + c*y3 )/( a+b+c ); double p = (a+b+c)/;
r = sqrt( (p-a)*(p-b)*(p-c)/p ); return Circle(Point(x,y),r);
} bool Line_cmp(Line a,Line b){return a.v<b.v;}
void TangentLineThroughPoint(Circle C,Point p)
{
vector<Line> Lines;
int cnt=getTangents(p,C,Lines);
vector<double> ans;
for(int i=;i<cnt;i++)
{
double ang=angle(Lines[i].v);
if(ang<) ang+=M_PI;
if(!dcmp(ang-M_PI)) ang-=M_PI;
ans.push_back(ang);
}
sort(ans.begin(),ans.end());
printf("[");
for(int i=;i<ans.size();i++)
{
if(i!=) printf(",");
printf("%lf",*ans[i]/M_PI);
}
printf("]\n");
} void CircleThroughAPointAndTangentToALineWithRadius(Point p,Point d1,Point d2,double r)
{
Vctor normal=Normal(d2-d1);
normal=normal/Length(normal)*r;
Line l1=Line(d1+normal,d2-d1), l2=Line(d1-normal,d2-d1);
vector<Point> ans;
getLineCircleIntersection(l1,Circle(p,r),ans);
getLineCircleIntersection(l2,Circle(p,r),ans);
sort(ans.begin(),ans.end());
printf("[");
for(int i=;i<ans.size();i++)
{
if(i!=) printf(",");
printf("(%.6lf,%.6lf)",ans[i].x,ans[i].y);
}
printf("]\n");
} void CircleTangentToTwoLinesWithRadius(Line L1,Line L2,double r)
{
Vctor normal1=Normal(L1.v), normal2=Normal(L2.v);
normal1=normal1/Length(normal1)*r;
normal2=normal2/Length(normal2)*r;
Line L1_a=Line(L1.p+normal1,L1.v);
Line L1_b=Line(L1.p-normal1,L1.v);
Line L2_a=Line(L2.p+normal2,L2.v);
Line L2_b=Line(L2.p-normal2,L2.v);
vector<Point> ans;
ans.push_back(getLineIntersection(L1_a,L2_a));
ans.push_back(getLineIntersection(L1_a,L2_b));
ans.push_back(getLineIntersection(L1_b,L2_a));
ans.push_back(getLineIntersection(L1_b,L2_b));
sort(ans.begin(),ans.end());
printf("[");
for(int i=;i<ans.size();i++)
{
if(i!=) printf(",");
printf("(%.6lf,%.6lf)",ans[i].x,ans[i].y);
}
printf("]\n");
} void CircleTangentToTwoDisjointCirclesWithRadius(Circle C1,Circle C2,double r)
{
C1.r+=r, C2.r+=r;
vector<Point> ans;
getCircleIntersection(C1,C2,ans);
sort(ans.begin(),ans.end());
printf("[");
for(int i=;i<ans.size();i++)
{
if(i!=) printf(",");
printf("(%.6lf,%.6lf)",ans[i].x,ans[i].y);
}
printf("]\n");
} int main()
{
string input;
while(cin>>input)
{
if(input=="CircumscribedCircle")
{
Point p1,p2,p3;
cin>>p1.x>>p1.y>>p2.x>>p2.y>>p3.x>>p3.y;
Circle ans=CircumscribedCircle(p1,p2,p3);
printf("(%.6lf,%.6lf,%.6lf)\n",ans.c.x,ans.c.y,ans.r);
}
else if(input=="InscribedCircle")
{
Point p1,p2,p3;
cin>>p1.x>>p1.y>>p2.x>>p2.y>>p3.x>>p3.y;
Circle ans=InscribedCircle(p1,p2,p3);
printf("(%.6lf,%.6lf,%.6lf)\n",ans.c.x,ans.c.y,ans.r);
}
else if(input=="TangentLineThroughPoint")
{
Circle C;
Point p;
cin>>C.c.x>>C.c.y>>C.r>>p.x>>p.y;
TangentLineThroughPoint(C,p);
}
else if(input=="CircleThroughAPointAndTangentToALineWithRadius")
{
Point d1,d2;
Point p;
double r;
cin>>p.x>>p.y>>d1.x>>d1.y>>d2.x>>d2.y>>r;
CircleThroughAPointAndTangentToALineWithRadius(p,d1,d2,r);
}
else if(input=="CircleTangentToTwoLinesWithRadius")
{
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;
CircleTangentToTwoLinesWithRadius(Line(p1,(p2-p1)),Line(p3,(p4-p3)),r);
}
else //if(input=="CircleTangentToTwoDisjointCirclesWithRadius")
{
Circle C1,C2;
double r;
cin>>C1.c.x>>C1.c.y>>C1.r>>C2.c.x>>C2.c.y>>C2.r>>r;
CircleTangentToTwoDisjointCirclesWithRadius(C1,C2,r);
}
}
}

UVA 12304 - 2D Geometry 110 in 1! - [平面几何基础题大集合][计算几何模板]的更多相关文章

  1. Uva 12304 - 2D Geometry 110 in 1!

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  2. UVA-12304 2D Geometry 110 in 1! (有关圆的基本操作)

    UVA-12304 2D Geometry 110 in 1! 该问题包含以下几个子问题 CircumscribedCircle x1 y1 x2 y2 x3 y3 : 三角形外接圆 Inscribe ...

  3. UVA12304 2D Geometry 110 in 1! 计算几何

    计算几何: 堆几何模版就能够了. . .. Description Problem E 2D Geometry 110 in 1! This is a collection of 110 (in bi ...

  4. UVa 12304 (6个二维几何问题合集) 2D Geometry 110 in 1!

    这个题能1A纯属运气,要是WA掉,可真不知道该怎么去调了. 题意: 这是完全独立的6个子问题.代码中是根据字符串的长度来区分问题编号的. 给出三角形三点坐标,求外接圆圆心和半径. 给出三角形三点坐标, ...

  5. UVA12304-2D Geometry 110 in 1!

    就是给了六个关于圆的算法.实现它们. 注意的是,不仅输出格式那个符号什么的要一样.坐标的顺序也要从小到大-- 基本上没考虑什么精度的问题,然后就过了. 大白鼠又骗人.也许我的方法比較好? 我的做法就是 ...

  6. uva 12304点与直线与圆之间的关系

    Problem E 2D Geometry 110 in 1! This is a collection of 110 (in binary) 2D geometry problems. Circum ...

  7. uva 12304

    题意:要求解答6个关于圆的问题. 1.给出三角形坐标求外接圆 2.给出三角形坐标求内切圆 3.给出一个圆心和半径已知的圆,求过点(x,y)的所有和这个圆相切的直线 4.求所有和已知直线相切的过定点(x ...

  8. UVA 12304 /// 圆的综合题 圆的模板

    题目大意: ①给出三角形三个点,求三角形外接圆,求外接圆的圆心和半径. ②给出三角形三个点,求三角形内接圆,求内接圆的圆心和半径. ③给出一个圆,和一个点,求过该点的圆的切线与x轴的夹角(0<= ...

  9. UVA - 10014 - Simple calculations (经典的数学推导题!!)

    UVA - 10014 Simple calculations Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...

随机推荐

  1. 关于Android打版本号的小白文

    尽管常常和android打交道.但事实上我对android不是非常了解. 这里记录一下ant编译androidproject的过程,然后顺便记录一下android的一些基本概念.不求渡人,但求渡己.这 ...

  2. VMWare------安装时出现无法将值写入注册表项

    安装时提示详情: 无法打开注册表项UNKNOWN\Components\...请确认你是否有足够的权限访问该注册表项,或者与技术支持人员联系. 解决方法: 关掉360安全卫士等软件再安装

  3. Lua协程-测试2

    print("Lua 协程测试2") function testFun(n) print("into foo,n = "..n) * n) -- 挂起co协程 ...

  4. 基于端口的弱口令检测工具--iscan

    亲手打造了一款弱口令检测工具,用Python编写,主要可以用于内网渗透.弱口令检测等方面,目前集成了常见端口服务,包含 系统弱口令:ftp.ssh.telnet.ipc$ 数据库弱口令:mssql.m ...

  5. [PyCharm] 设置自动启动时自动打开项目

    设置启动PyCharm时自动打开(或不打开)上次进行的项目: 选择 “Settings - General - Reopen last project on startup”,勾选该选项则启动时自动打 ...

  6. centos6.4安装 jupyter-notebook

    自上次发布了文章后有些网友就说不能实现效果,根据自己的实验发现确实有此事,那是因为版本的变化问题.这次基于yum仓库里的jupyter notebook 5.0.0版本实现: 系统:最小化安装[习惯性 ...

  7. IOS设计模式第三篇之外观设计模式

    外观设计模式: 这个外观设计模式提供了一个单独的接口给复杂的子系统.而不是暴露用户的一组类和API,你仅仅暴露一个简单的同一的API. 下面的图片解释这个概念: API的用户根本不知道后面系统的复杂性 ...

  8. ios设备唯一标识获取策略

    In iOS 7 and later, if you ask for the MAC address of an iOS device, the system returns the value 02 ...

  9. 【cs229-Lecture9】经验风险最小化

    写在前面:机器学习的目标是从训练集中得到一个模型,使之能对测试集进行分类,这里,训练集和测试集都是分布D的样本.而我们会设定一个训练误差来表示测试集的拟合程度(训练误差),虽然训练误差具有一定的参考价 ...

  10. Linux 下误删除恢复,(文件名无法找回)

    手贱命令写错了,直接把一个目录下的文件全删了,用下面的方法虽然恢复了,但是还是有几个文件没有找回来...(可以找回,但是要在另一个盘进行操作) 如果不小心用rm –rf xxx删除了文件或目录,在ex ...