poj1329 Circle Through Three Points
地址:http://poj.org/problem?id=1329
题目:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 3970 | Accepted: 1667 |
Description
The solution is to be printed as an equation of the form
- (x - h)^2 + (y - k)^2 = r^2 (1)
and an equation of the form
- x^2 + y^2 + cx + dy - e = 0 (2)
Input
Output
Sample Input
- 7.0 -5.0 -1.0 1.0 0.0 -6.0
- 1.0 7.0 8.0 6.0 7.0 -2.0
Sample Output
- (x - 3.000)^2 + (y + 2.000)^2 = 5.000^2
- x^2 + y^2 - 6.000x + 4.000y - 12.000 = 0
- (x - 3.921)^2 + (y - 2.447)^2 = 5.409^2
- x^2 + y^2 - 7.842x - 4.895y - 7.895 = 0
Source
- #include <iostream>
- #include <cstdio>
- #include <cmath>
- #include <algorithm>
- using namespace std;
- const double PI = acos(-1.0);
- const double eps = 1e-;
- /****************常用函数***************/
- //判断ta与tb的大小关系
- int sgn( double ta, double tb)
- {
- if(fabs(ta-tb)<eps)return ;
- if(ta<tb) return -;
- return ;
- }
- //点
- class Point
- {
- public:
- double x, y;
- Point(){}
- Point( double tx, double ty){ x = tx, y = ty;}
- bool operator < (const Point &_se) const
- {
- return x<_se.x || (x==_se.x && y<_se.y);
- }
- friend Point operator + (const Point &_st,const Point &_se)
- {
- return Point(_st.x + _se.x, _st.y + _se.y);
- }
- friend Point operator - (const Point &_st,const Point &_se)
- {
- return Point(_st.x - _se.x, _st.y - _se.y);
- }
- //点位置相同(double类型)
- bool operator == (const Point &_off)const
- {
- return sgn(x, _off.x) == && sgn(y, _off.y) == ;
- }
- };
- /****************常用函数***************/
- //点乘
- double dot(const Point &po,const Point &ps,const Point &pe)
- {
- return (ps.x - po.x) * (pe.x - po.x) + (ps.y - po.y) * (pe.y - po.y);
- }
- //叉乘
- double xmult(const Point &po,const Point &ps,const Point &pe)
- {
- return (ps.x - po.x) * (pe.y - po.y) - (pe.x - po.x) * (ps.y - po.y);
- }
- //两点间距离的平方
- double getdis2(const Point &st,const Point &se)
- {
- return (st.x - se.x) * (st.x - se.x) + (st.y - se.y) * (st.y - se.y);
- }
- //两点间距离
- double getdis(const Point &st,const Point &se)
- {
- return sqrt((st.x - se.x) * (st.x - se.x) + (st.y - se.y) * (st.y - se.y));
- }
- //两点表示的向量
- class Line
- {
- public:
- Point s, e;//两点表示,起点[s],终点[e]
- double a, b, c;//一般式,ax+by+c=0
- double angle;//向量的角度,[-pi,pi]
- Line(){}
- Line( Point ts, Point te):s(ts),e(te){}//get_angle();}
- Line(double _a,double _b,double _c):a(_a),b(_b),c(_c){}
- //排序用
- bool operator < (const Line &ta)const
- {
- return angle<ta.angle;
- }
- //向量与向量的叉乘
- friend double operator / ( const Line &_st, const Line &_se)
- {
- return (_st.e.x - _st.s.x) * (_se.e.y - _se.s.y) - (_st.e.y - _st.s.y) * (_se.e.x - _se.s.x);
- }
- //向量间的点乘
- friend double operator *( const Line &_st, const Line &_se)
- {
- return (_st.e.x - _st.s.x) * (_se.e.x - _se.s.x) - (_st.e.y - _st.s.y) * (_se.e.y - _se.s.y);
- }
- //从两点表示转换为一般表示
- //a=y2-y1,b=x1-x2,c=x2*y1-x1*y2
- bool pton()
- {
- a = e.y - s.y;
- b = s.x - e.x;
- c = e.x * s.y - e.y * s.x;
- return true;
- }
- //半平面交用
- //点在向量左边(右边的小于号改成大于号即可,在对应直线上则加上=号)
- friend bool operator < (const Point &_Off, const Line &_Ori)
- {
- return (_Ori.e.y - _Ori.s.y) * (_Off.x - _Ori.s.x)
- < (_Off.y - _Ori.s.y) * (_Ori.e.x - _Ori.s.x);
- }
- //求直线或向量的角度
- double get_angle( bool isVector = true)
- {
- angle = atan2( e.y - s.y, e.x - s.x);
- if(!isVector && angle < )
- angle += PI;
- return angle;
- }
- //点在线段或直线上 1:点在直线上 2点在s,e所在矩形内
- bool has(const Point &_Off, bool isSegment = false) const
- {
- bool ff = sgn( xmult( s, e, _Off), ) == ;
- if( !isSegment) return ff;
- return ff
- && sgn(_Off.x - min(s.x, e.x), ) >= && sgn(_Off.x - max(s.x, e.x), ) <=
- && sgn(_Off.y - min(s.y, e.y), ) >= && sgn(_Off.y - max(s.y, e.y), ) <= ;
- }
- //点到直线/线段的距离
- double dis(const Point &_Off, bool isSegment = false)
- {
- ///化为一般式
- pton();
- //到直线垂足的距离
- double td = (a * _Off.x + b * _Off.y + c) / sqrt(a * a + b * b);
- //如果是线段判断垂足
- if(isSegment)
- {
- double xp = (b * b * _Off.x - a * b * _Off.y - a * c) / ( a * a + b * b);
- double yp = (-a * b * _Off.x + a * a * _Off.y - b * c) / (a * a + b * b);
- double xb = max(s.x, e.x);
- double yb = max(s.y, e.y);
- double xs = s.x + e.x - xb;
- double ys = s.y + e.y - yb;
- if(xp > xb + eps || xp < xs - eps || yp > yb + eps || yp < ys - eps)
- td = min( getdis(_Off,s), getdis(_Off,e));
- }
- return fabs(td);
- }
- //关于直线对称的点
- Point mirror(const Point &_Off)
- {
- ///注意先转为一般式
- Point ret;
- double d = a * a + b * b;
- ret.x = (b * b * _Off.x - a * a * _Off.x - * a * b * _Off.y - * a * c) / d;
- ret.y = (a * a * _Off.y - b * b * _Off.y - * a * b * _Off.x - * b * c) / d;
- return ret;
- }
- //计算两点的中垂线
- static Line ppline(const Point &_a,const Point &_b)
- {
- Line ret;
- ret.s.x = (_a.x + _b.x) / ;
- ret.s.y = (_a.y + _b.y) / ;
- //一般式
- ret.a = _b.x - _a.x;
- ret.b = _b.y - _a.y;
- ret.c = (_a.y - _b.y) * ret.s.y + (_a.x - _b.x) * ret.s.x;
- //两点式
- if(fabs(ret.a) > eps)
- {
- ret.e.y = 0.0;
- ret.e.x = - ret.c / ret.a;
- if(ret.e == ret. s)
- {
- ret.e.y = 1e10;
- ret.e.x = - (ret.c - ret.b * ret.e.y) / ret.a;
- }
- }
- else
- {
- ret.e.x = 0.0;
- ret.e.y = - ret.c / ret.b;
- if(ret.e == ret. s)
- {
- ret.e.x = 1e10;
- ret.e.y = - (ret.c - ret.a * ret.e.x) / ret.b;
- }
- }
- return ret;
- }
- //------------直线和直线(向量)-------------
- //向量向左边平移t的距离
- Line& moveLine( double t)
- {
- Point of;
- of = Point( -( e.y - s.y), e.x - s.x);
- double dis = sqrt( of.x * of.x + of.y * of.y);
- of.x= of.x * t / dis, of.y = of.y * t / dis;
- s = s + of, e = e + of;
- return *this;
- }
- //直线重合
- static bool equal(const Line &_st,const Line &_se)
- {
- return _st.has( _se.e) && _se.has( _st.s);
- }
- //直线平行
- static bool parallel(const Line &_st,const Line &_se)
- {
- return sgn( _st / _se, ) == ;
- }
- //两直线(线段)交点
- //返回-1代表平行,0代表重合,1代表相交
- static bool crossLPt(const Line &_st,const Line &_se, Point &ret)
- {
- if(parallel(_st,_se))
- {
- if(Line::equal(_st,_se)) return ;
- return -;
- }
- ret = _st.s;
- double t = ( Line(_st.s,_se.s) / _se) / ( _st / _se);
- ret.x += (_st.e.x - _st.s.x) * t;
- ret.y += (_st.e.y - _st.s.y) * t;
- return ;
- }
- //------------线段和直线(向量)----------
- //直线和线段相交
- //参数:直线[_st],线段[_se]
- friend bool crossSL( Line &_st, Line &_se)
- {
- return sgn( xmult( _st.s, _se.s, _st.e) * xmult( _st.s, _st.e, _se.e), ) >= ;
- }
- //判断线段是否相交(注意添加eps)
- static bool isCrossSS( const Line &_st, const Line &_se)
- {
- //1.快速排斥试验判断以两条线段为对角线的两个矩形是否相交
- //2.跨立试验(等于0时端点重合)
- return
- max(_st.s.x, _st.e.x) >= min(_se.s.x, _se.e.x) &&
- max(_se.s.x, _se.e.x) >= min(_st.s.x, _st.e.x) &&
- max(_st.s.y, _st.e.y) >= min(_se.s.y, _se.e.y) &&
- max(_se.s.y, _se.e.y) >= min(_st.s.y, _st.e.y) &&
- sgn( xmult( _se.s, _st.s, _se.e) * xmult( _se.s, _se.e, _st.s), ) >= &&
- sgn( xmult( _st.s, _se.s, _st.e) * xmult( _st.s, _st.e, _se.s), ) >= ;
- }
- };
- //寻找凸包的graham 扫描法所需的排序函数
- Point gsort;
- bool gcmp( const Point &ta, const Point &tb)/// 选取与最后一条确定边夹角最小的点,即余弦值最大者
- {
- double tmp = xmult( gsort, ta, tb);
- if( fabs( tmp) < eps)
- return getdis( gsort, ta) < getdis( gsort, tb);
- else if( tmp > )
- return ;
- return ;
- }
- class triangle
- {
- public:
- Point a, b, c;//顶点
- triangle(){}
- triangle(Point a, Point b, Point c): a(a), b(b), c(c){}
- //计算三角形面积
- double area()
- {
- return fabs( xmult(a, b, c)) / 2.0;
- }
- //计算三角形外心
- //返回:外接圆圆心
- Point circumcenter()
- {
- double pa = a.x * a.x + a.y * a.y;
- double pb = b.x * b.x + b.y * b.y;
- double pc = c.x * c.x + c.y * c.y;
- double ta = pa * ( b.y - c.y) - pb * ( a.y - c.y) + pc * ( a.y - b.y);
- double tb = -pa * ( b.x - c.x) + pb * ( a.x - c.x) - pc * ( a.x - b.x);
- double tc = a.x * ( b.y - c.y) - b.x * ( a.y - c.y) + c.x * ( a.y - b.y);
- return Point( ta / 2.0 / tc, tb / 2.0 / tc);
- }
- //计算三角形内心
- //返回:内接圆圆心
- Point incenter()
- {
- Line u, v;
- double m, n;
- u.s = a;
- m = atan2(b.y - a.y, b.x - a.x);
- n = atan2(c.y - a.y, c.x - a.x);
- u.e.x = u.s.x + cos((m + n) / );
- u.e.y = u.s.y + sin((m + n) / );
- 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.x = v.s.x + cos((m + n) / );
- v.e.y = v.s.y + sin((m + n) / );
- Point ret;
- Line::crossLPt(u,v,ret);
- return ret;
- }
- //计算三角形垂心
- //返回:高的交点
- Point perpencenter()
- {
- Line u,v;
- u.s = c;
- u.e.x = u.s.x - a.y + b.y;
- u.e.y = u.s.y + a.x - b.x;
- v.s = b;
- v.e.x = v.s.x - a.y + c.y;
- v.e.y = v.s.y + a.x - c.x;
- Point ret;
- Line::crossLPt(u,v,ret);
- return ret;
- }
- //计算三角形重心
- //返回:重心
- //到三角形三顶点距离的平方和最小的点
- //三角形内到三边距离之积最大的点
- Point barycenter()
- {
- Line u,v;
- u.s.x = (a.x + b.x) / ;
- u.s.y = (a.y + b.y) / ;
- u.e = c;
- v.s.x = (a.x + c.x) / ;
- v.s.y = (a.y + c.y) / ;
- v.e = b;
- Point ret;
- Line::crossLPt(u,v,ret);
- return ret;
- }
- //计算三角形费马点
- //返回:到三角形三顶点距离之和最小的点
- Point fermentPoint()
- {
- Point u, v;
- double step = fabs(a.x) + fabs(a.y) + fabs(b.x) + fabs(b.y) + fabs(c.x) + fabs(c.y);
- int i, j, k;
- u.x = (a.x + b.x + c.x) / ;
- u.y = (a.y + b.y + c.y) / ;
- while (step > eps)
- {
- for (k = ; k < ; step /= , k ++)
- {
- for (i = -; i <= ; i ++)
- {
- for (j =- ; j <= ; j ++)
- {
- v.x = u.x + step * i;
- v.y = u.y + step * j;
- if (getdis(u,a) + getdis(u,b) + getdis(u,c) > getdis(v,a) + getdis(v,b) + getdis(v,c))
- u = v;
- }
- }
- }
- }
- return u;
- }
- };
- triangle tr;
- char cgn(double x)
- {
- return x>?'+':'-';
- }
- int main(void)
- {
- while(~scanf("%lf%lf%lf%lf%lf%lf",&tr.a.x,&tr.a.y,&tr.b.x,&tr.b.y,&tr.c.x,&tr.c.y))
- {
- Point pp = tr.circumcenter();
- double r = getdis( tr.a, pp),d = pp.x*pp.x+pp.y*pp.y-r*r;
- pp.x = -pp.x, pp.y = -pp.y;
- printf("(x %c %.3f)^2 + (y %c %.3f)^2 = %.3f^2\n",cgn(pp.x),fabs(pp.x),cgn(pp.y), fabs(pp.y),r);
- printf("x^2 + y^2 %c %.3fx %c %.3fy %c %.3f = 0\n\n", cgn(pp.x),fabs(pp.x*),cgn(pp.y),fabs(pp.y*),cgn(d), fabs(d));
- }
- return ;
- }
poj1329 Circle Through Three Points的更多相关文章
- POJ - 1329 Circle Through Three Points 求圆
Circle Through Three Points Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4112 Acce ...
- poj 1329 Circle Through Three Points(求圆心+输出)
题目链接:http://poj.org/problem?id=1329 输出很蛋疼,要考虑系数为0,输出也不同 #include<cstdio> #include<cstring&g ...
- ●POJ 1329 Circle Through Three Points
题链: http://poj.org/problem?id=1329 题解: 计算几何,求过不共线的三点的圆 就是用向量暴力算出来的东西... (设出外心M的坐标,由于$|\vec{MA}|=|\ve ...
- POJ 1329 Circle Through Three Points(三角形外接圆)
题目链接:http://poj.org/problem?id=1329 #include<cstdio> #include<cmath> #include<algorit ...
- POJ 1329 Circle Through Three Points(三角形外心)
题目链接 抄的外心模版.然后,输出认真一点.1Y. #include <cstdio> #include <cstring> #include <string> # ...
- POJ1329题
Circle Through Three Points Time Limit : 2000/1000ms (Java/Other) Memory Limit : 20000/10000K (Jav ...
- Circle Problem From 3Blue1Brown (分圆问题)
Background\text{Background}Background Last night, lots of students from primary school came to our c ...
- MapFile生成WMS
MAP NAME "HBWMS" STATUS ON SIZE 800 600 EXTENT 107.795 28.559 116.977 33.627 UNITS ME ...
- 墓地雕塑-LA3708
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=20& ...
随机推荐
- (DCloud)用这个来写H5,好像好厉害的样子哦
HBuilder: http://www.dcloud.io MUI: http://dev.dcloud.net.cn/mui/getting-started/ http://dev.dcloud. ...
- ASP代码审计学习笔记-1.SQL注入
ASP注入漏洞 一.SQL注入的原因 按照参数形式:数字型/字符型/搜索型 1.数字型sql查询 sql注入原因: ID=49 这类注入的参数是数字型,SQL语句原貌大致如下: id=request. ...
- php上传文件中文文件名乱码的解决方法
文件上传是我们在处理表单提交时候最常用的功能之一,今天写了一个小小的demo,如下: 先看结构: html为表单提交的页面,php为处理表单的文件,upload为上传文件所放的位置 html: < ...
- jstl标签怎么实现分页中下一页
<script type="text/javascript"> //分页按钮处理 function goPageAction(page ...
- CRUX下实现进程隐藏(3)
通过一个内核模块拦截文件系统的回调函数来实现进程隐藏. VFS(Virtual File System)是Linux在实际文件系统(如ext3,ext4,vfat等)上抽象出的一个文件系统模型,简单来 ...
- Activity的LaunchMode应用场景思考
本文链接:http://blog.csdn.net/xiaodongrush/article/details/28597855 1. 有哪几种类型?分别有什么用? http://developer ...
- HTML标签img--改变图片尺寸
转自:https://blog.csdn.net/u012377333/article/details/50508484 1.统一大小? 我的网页上面有许多的图片,有的大,有的小,我想如果图片大的实现 ...
- 310实验室 Linux 软件安装常见问题
电脑装好Linux系统后,系统默认安装软件不齐,需要自己根据自己的需要安装一些列工具软件,在linux系统中,用的最多的就是Synaptic Package Manager,什么是Synaptic?新 ...
- Linux系统下 Supervisor 安装搭建(yum安装)
安装Supervisor # 安装supervisor yum install supervisor # 打开supervisor的配置文件 vi /etc/supervisord.conf 将sup ...
- mysql客户端不能插入中文字符
问题:输入中文报错:Incorrect string value 步骤: 1.查看MySQL编码设置 show variables like '%character%'; 2.重新设置编码(注意:ut ...