地址:http://poj.org/problem?id=1329

题目:

Circle Through Three Points
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 3970   Accepted: 1667

Description

Your team is to write a program that, given the Cartesian coordinates of three points on a plane, will find the equation of the circle through them all. The three points will not be on a straight line. 
The solution is to be printed as an equation of the form

  1. (x - h)^2 + (y - k)^2 = r^2 (1)

and an equation of the form

  1. x^2 + y^2 + cx + dy - e = 0 (2)

Input

Each line of input to your program will contain the x and y coordinates of three points, in the order Ax, Ay, Bx, By, Cx, Cy. These coordinates will be real numbers separated from each other by one or more spaces.

Output

Your program must print the required equations on two lines using the format given in the sample below. Your computed values for h, k, r, c, d, and e in Equations 1 and 2 above are to be printed with three digits after the decimal point. Plus and minus signs in the equations should be changed as needed to avoid multiple signs before a number. Plus, minus, and equal signs must be separated from the adjacent characters by a single space on each side. No other spaces are to appear in the equations. Print a single blank line after each equation pair.

Sample Input

  1. 7.0 -5.0 -1.0 1.0 0.0 -6.0
  2. 1.0 7.0 8.0 6.0 7.0 -2.0

Sample Output

  1. (x - 3.000)^2 + (y + 2.000)^2 = 5.000^2
  2. x^2 + y^2 - 6.000x + 4.000y - 12.000 = 0
  3.  
  4. (x - 3.921)^2 + (y - 2.447)^2 = 5.409^2
  5. x^2 + y^2 - 7.842x - 4.895y - 7.895 = 0

Source

 
思路:
  维基有公式。
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <algorithm>
  5.  
  6. using namespace std;
  7. const double PI = acos(-1.0);
  8. const double eps = 1e-;
  9.  
  10. /****************常用函数***************/
  11. //判断ta与tb的大小关系
  12. int sgn( double ta, double tb)
  13. {
  14. if(fabs(ta-tb)<eps)return ;
  15. if(ta<tb) return -;
  16. return ;
  17. }
  18.  
  19. //点
  20. class Point
  21. {
  22. public:
  23.  
  24. double x, y;
  25.  
  26. Point(){}
  27. Point( double tx, double ty){ x = tx, y = ty;}
  28.  
  29. bool operator < (const Point &_se) const
  30. {
  31. return x<_se.x || (x==_se.x && y<_se.y);
  32. }
  33. friend Point operator + (const Point &_st,const Point &_se)
  34. {
  35. return Point(_st.x + _se.x, _st.y + _se.y);
  36. }
  37. friend Point operator - (const Point &_st,const Point &_se)
  38. {
  39. return Point(_st.x - _se.x, _st.y - _se.y);
  40. }
  41. //点位置相同(double类型)
  42. bool operator == (const Point &_off)const
  43. {
  44. return sgn(x, _off.x) == && sgn(y, _off.y) == ;
  45. }
  46.  
  47. };
  48.  
  49. /****************常用函数***************/
  50. //点乘
  51. double dot(const Point &po,const Point &ps,const Point &pe)
  52. {
  53. return (ps.x - po.x) * (pe.x - po.x) + (ps.y - po.y) * (pe.y - po.y);
  54. }
  55. //叉乘
  56. double xmult(const Point &po,const Point &ps,const Point &pe)
  57. {
  58. return (ps.x - po.x) * (pe.y - po.y) - (pe.x - po.x) * (ps.y - po.y);
  59. }
  60. //两点间距离的平方
  61. double getdis2(const Point &st,const Point &se)
  62. {
  63. return (st.x - se.x) * (st.x - se.x) + (st.y - se.y) * (st.y - se.y);
  64. }
  65. //两点间距离
  66. double getdis(const Point &st,const Point &se)
  67. {
  68. return sqrt((st.x - se.x) * (st.x - se.x) + (st.y - se.y) * (st.y - se.y));
  69. }
  70.  
  71. //两点表示的向量
  72. class Line
  73. {
  74. public:
  75.  
  76. Point s, e;//两点表示,起点[s],终点[e]
  77. double a, b, c;//一般式,ax+by+c=0
  78. double angle;//向量的角度,[-pi,pi]
  79.  
  80. Line(){}
  81. Line( Point ts, Point te):s(ts),e(te){}//get_angle();}
  82. Line(double _a,double _b,double _c):a(_a),b(_b),c(_c){}
  83.  
  84. //排序用
  85. bool operator < (const Line &ta)const
  86. {
  87. return angle<ta.angle;
  88. }
  89. //向量与向量的叉乘
  90. friend double operator / ( const Line &_st, const Line &_se)
  91. {
  92. 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);
  93. }
  94. //向量间的点乘
  95. friend double operator *( const Line &_st, const Line &_se)
  96. {
  97. 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);
  98. }
  99. //从两点表示转换为一般表示
  100. //a=y2-y1,b=x1-x2,c=x2*y1-x1*y2
  101. bool pton()
  102. {
  103. a = e.y - s.y;
  104. b = s.x - e.x;
  105. c = e.x * s.y - e.y * s.x;
  106. return true;
  107. }
  108. //半平面交用
  109. //点在向量左边(右边的小于号改成大于号即可,在对应直线上则加上=号)
  110. friend bool operator < (const Point &_Off, const Line &_Ori)
  111. {
  112. return (_Ori.e.y - _Ori.s.y) * (_Off.x - _Ori.s.x)
  113. < (_Off.y - _Ori.s.y) * (_Ori.e.x - _Ori.s.x);
  114. }
  115. //求直线或向量的角度
  116. double get_angle( bool isVector = true)
  117. {
  118. angle = atan2( e.y - s.y, e.x - s.x);
  119. if(!isVector && angle < )
  120. angle += PI;
  121. return angle;
  122. }
  123.  
  124. //点在线段或直线上 1:点在直线上 2点在s,e所在矩形内
  125. bool has(const Point &_Off, bool isSegment = false) const
  126. {
  127. bool ff = sgn( xmult( s, e, _Off), ) == ;
  128. if( !isSegment) return ff;
  129. return ff
  130. && sgn(_Off.x - min(s.x, e.x), ) >= && sgn(_Off.x - max(s.x, e.x), ) <=
  131. && sgn(_Off.y - min(s.y, e.y), ) >= && sgn(_Off.y - max(s.y, e.y), ) <= ;
  132. }
  133.  
  134. //点到直线/线段的距离
  135. double dis(const Point &_Off, bool isSegment = false)
  136. {
  137. ///化为一般式
  138. pton();
  139. //到直线垂足的距离
  140. double td = (a * _Off.x + b * _Off.y + c) / sqrt(a * a + b * b);
  141. //如果是线段判断垂足
  142. if(isSegment)
  143. {
  144. double xp = (b * b * _Off.x - a * b * _Off.y - a * c) / ( a * a + b * b);
  145. double yp = (-a * b * _Off.x + a * a * _Off.y - b * c) / (a * a + b * b);
  146. double xb = max(s.x, e.x);
  147. double yb = max(s.y, e.y);
  148. double xs = s.x + e.x - xb;
  149. double ys = s.y + e.y - yb;
  150. if(xp > xb + eps || xp < xs - eps || yp > yb + eps || yp < ys - eps)
  151. td = min( getdis(_Off,s), getdis(_Off,e));
  152. }
  153. return fabs(td);
  154. }
  155.  
  156. //关于直线对称的点
  157. Point mirror(const Point &_Off)
  158. {
  159. ///注意先转为一般式
  160. Point ret;
  161. double d = a * a + b * b;
  162. ret.x = (b * b * _Off.x - a * a * _Off.x - * a * b * _Off.y - * a * c) / d;
  163. ret.y = (a * a * _Off.y - b * b * _Off.y - * a * b * _Off.x - * b * c) / d;
  164. return ret;
  165. }
  166. //计算两点的中垂线
  167. static Line ppline(const Point &_a,const Point &_b)
  168. {
  169. Line ret;
  170. ret.s.x = (_a.x + _b.x) / ;
  171. ret.s.y = (_a.y + _b.y) / ;
  172. //一般式
  173. ret.a = _b.x - _a.x;
  174. ret.b = _b.y - _a.y;
  175. ret.c = (_a.y - _b.y) * ret.s.y + (_a.x - _b.x) * ret.s.x;
  176. //两点式
  177. if(fabs(ret.a) > eps)
  178. {
  179. ret.e.y = 0.0;
  180. ret.e.x = - ret.c / ret.a;
  181. if(ret.e == ret. s)
  182. {
  183. ret.e.y = 1e10;
  184. ret.e.x = - (ret.c - ret.b * ret.e.y) / ret.a;
  185. }
  186. }
  187. else
  188. {
  189. ret.e.x = 0.0;
  190. ret.e.y = - ret.c / ret.b;
  191. if(ret.e == ret. s)
  192. {
  193. ret.e.x = 1e10;
  194. ret.e.y = - (ret.c - ret.a * ret.e.x) / ret.b;
  195. }
  196. }
  197. return ret;
  198. }
  199.  
  200. //------------直线和直线(向量)-------------
  201. //向量向左边平移t的距离
  202. Line& moveLine( double t)
  203. {
  204. Point of;
  205. of = Point( -( e.y - s.y), e.x - s.x);
  206. double dis = sqrt( of.x * of.x + of.y * of.y);
  207. of.x= of.x * t / dis, of.y = of.y * t / dis;
  208. s = s + of, e = e + of;
  209. return *this;
  210. }
  211. //直线重合
  212. static bool equal(const Line &_st,const Line &_se)
  213. {
  214. return _st.has( _se.e) && _se.has( _st.s);
  215. }
  216. //直线平行
  217. static bool parallel(const Line &_st,const Line &_se)
  218. {
  219. return sgn( _st / _se, ) == ;
  220. }
  221. //两直线(线段)交点
  222. //返回-1代表平行,0代表重合,1代表相交
  223. static bool crossLPt(const Line &_st,const Line &_se, Point &ret)
  224. {
  225. if(parallel(_st,_se))
  226. {
  227. if(Line::equal(_st,_se)) return ;
  228. return -;
  229. }
  230. ret = _st.s;
  231. double t = ( Line(_st.s,_se.s) / _se) / ( _st / _se);
  232. ret.x += (_st.e.x - _st.s.x) * t;
  233. ret.y += (_st.e.y - _st.s.y) * t;
  234. return ;
  235. }
  236. //------------线段和直线(向量)----------
  237. //直线和线段相交
  238. //参数:直线[_st],线段[_se]
  239. friend bool crossSL( Line &_st, Line &_se)
  240. {
  241. return sgn( xmult( _st.s, _se.s, _st.e) * xmult( _st.s, _st.e, _se.e), ) >= ;
  242. }
  243.  
  244. //判断线段是否相交(注意添加eps)
  245. static bool isCrossSS( const Line &_st, const Line &_se)
  246. {
  247. //1.快速排斥试验判断以两条线段为对角线的两个矩形是否相交
  248. //2.跨立试验(等于0时端点重合)
  249. return
  250. max(_st.s.x, _st.e.x) >= min(_se.s.x, _se.e.x) &&
  251. max(_se.s.x, _se.e.x) >= min(_st.s.x, _st.e.x) &&
  252. max(_st.s.y, _st.e.y) >= min(_se.s.y, _se.e.y) &&
  253. max(_se.s.y, _se.e.y) >= min(_st.s.y, _st.e.y) &&
  254. sgn( xmult( _se.s, _st.s, _se.e) * xmult( _se.s, _se.e, _st.s), ) >= &&
  255. sgn( xmult( _st.s, _se.s, _st.e) * xmult( _st.s, _st.e, _se.s), ) >= ;
  256. }
  257. };
  258.  
  259. //寻找凸包的graham 扫描法所需的排序函数
  260. Point gsort;
  261. bool gcmp( const Point &ta, const Point &tb)/// 选取与最后一条确定边夹角最小的点,即余弦值最大者
  262. {
  263. double tmp = xmult( gsort, ta, tb);
  264. if( fabs( tmp) < eps)
  265. return getdis( gsort, ta) < getdis( gsort, tb);
  266. else if( tmp > )
  267. return ;
  268. return ;
  269. }
  270.  
  271. class triangle
  272. {
  273. public:
  274. Point a, b, c;//顶点
  275. triangle(){}
  276. triangle(Point a, Point b, Point c): a(a), b(b), c(c){}
  277.  
  278. //计算三角形面积
  279. double area()
  280. {
  281. return fabs( xmult(a, b, c)) / 2.0;
  282. }
  283.  
  284. //计算三角形外心
  285. //返回:外接圆圆心
  286. Point circumcenter()
  287. {
  288. double pa = a.x * a.x + a.y * a.y;
  289. double pb = b.x * b.x + b.y * b.y;
  290. double pc = c.x * c.x + c.y * c.y;
  291. double ta = pa * ( b.y - c.y) - pb * ( a.y - c.y) + pc * ( a.y - b.y);
  292. double tb = -pa * ( b.x - c.x) + pb * ( a.x - c.x) - pc * ( a.x - b.x);
  293. double tc = a.x * ( b.y - c.y) - b.x * ( a.y - c.y) + c.x * ( a.y - b.y);
  294. return Point( ta / 2.0 / tc, tb / 2.0 / tc);
  295. }
  296.  
  297. //计算三角形内心
  298. //返回:内接圆圆心
  299. Point incenter()
  300. {
  301. Line u, v;
  302. double m, n;
  303. u.s = a;
  304. m = atan2(b.y - a.y, b.x - a.x);
  305. n = atan2(c.y - a.y, c.x - a.x);
  306. u.e.x = u.s.x + cos((m + n) / );
  307. u.e.y = u.s.y + sin((m + n) / );
  308. v.s = b;
  309. m = atan2(a.y - b.y, a.x - b.x);
  310. n = atan2(c.y - b.y, c.x - b.x);
  311. v.e.x = v.s.x + cos((m + n) / );
  312. v.e.y = v.s.y + sin((m + n) / );
  313. Point ret;
  314. Line::crossLPt(u,v,ret);
  315. return ret;
  316. }
  317.  
  318. //计算三角形垂心
  319. //返回:高的交点
  320. Point perpencenter()
  321. {
  322. Line u,v;
  323. u.s = c;
  324. u.e.x = u.s.x - a.y + b.y;
  325. u.e.y = u.s.y + a.x - b.x;
  326. v.s = b;
  327. v.e.x = v.s.x - a.y + c.y;
  328. v.e.y = v.s.y + a.x - c.x;
  329. Point ret;
  330. Line::crossLPt(u,v,ret);
  331. return ret;
  332. }
  333.  
  334. //计算三角形重心
  335. //返回:重心
  336. //到三角形三顶点距离的平方和最小的点
  337. //三角形内到三边距离之积最大的点
  338. Point barycenter()
  339. {
  340. Line u,v;
  341. u.s.x = (a.x + b.x) / ;
  342. u.s.y = (a.y + b.y) / ;
  343. u.e = c;
  344. v.s.x = (a.x + c.x) / ;
  345. v.s.y = (a.y + c.y) / ;
  346. v.e = b;
  347. Point ret;
  348. Line::crossLPt(u,v,ret);
  349. return ret;
  350. }
  351.  
  352. //计算三角形费马点
  353. //返回:到三角形三顶点距离之和最小的点
  354. Point fermentPoint()
  355. {
  356. Point u, v;
  357. double step = fabs(a.x) + fabs(a.y) + fabs(b.x) + fabs(b.y) + fabs(c.x) + fabs(c.y);
  358. int i, j, k;
  359. u.x = (a.x + b.x + c.x) / ;
  360. u.y = (a.y + b.y + c.y) / ;
  361. while (step > eps)
  362. {
  363. for (k = ; k < ; step /= , k ++)
  364. {
  365. for (i = -; i <= ; i ++)
  366. {
  367. for (j =- ; j <= ; j ++)
  368. {
  369. v.x = u.x + step * i;
  370. v.y = u.y + step * j;
  371. if (getdis(u,a) + getdis(u,b) + getdis(u,c) > getdis(v,a) + getdis(v,b) + getdis(v,c))
  372. u = v;
  373. }
  374. }
  375. }
  376. }
  377. return u;
  378. }
  379. };
  380.  
  381. triangle tr;
  382.  
  383. char cgn(double x)
  384. {
  385. return x>?'+':'-';
  386. }
  387. int main(void)
  388. {
  389.  
  390. 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))
  391. {
  392. Point pp = tr.circumcenter();
  393. double r = getdis( tr.a, pp),d = pp.x*pp.x+pp.y*pp.y-r*r;
  394. pp.x = -pp.x, pp.y = -pp.y;
  395. 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);
  396. 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));
  397.  
  398. }
  399. return ;
  400. }

poj1329 Circle Through Three Points的更多相关文章

  1. POJ - 1329 Circle Through Three Points 求圆

    Circle Through Three Points Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4112   Acce ...

  2. poj 1329 Circle Through Three Points(求圆心+输出)

    题目链接:http://poj.org/problem?id=1329 输出很蛋疼,要考虑系数为0,输出也不同 #include<cstdio> #include<cstring&g ...

  3. ●POJ 1329 Circle Through Three Points

    题链: http://poj.org/problem?id=1329 题解: 计算几何,求过不共线的三点的圆 就是用向量暴力算出来的东西... (设出外心M的坐标,由于$|\vec{MA}|=|\ve ...

  4. POJ 1329 Circle Through Three Points(三角形外接圆)

    题目链接:http://poj.org/problem?id=1329 #include<cstdio> #include<cmath> #include<algorit ...

  5. POJ 1329 Circle Through Three Points(三角形外心)

    题目链接 抄的外心模版.然后,输出认真一点.1Y. #include <cstdio> #include <cstring> #include <string> # ...

  6. POJ1329题

    Circle Through Three Points Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Jav ...

  7. Circle Problem From 3Blue1Brown (分圆问题)

    Background\text{Background}Background Last night, lots of students from primary school came to our c ...

  8. MapFile生成WMS

    MAP  NAME "HBWMS"  STATUS ON  SIZE 800 600  EXTENT 107.795 28.559 116.977 33.627  UNITS ME ...

  9. 墓地雕塑-LA3708

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

随机推荐

  1. (DCloud)用这个来写H5,好像好厉害的样子哦

    HBuilder: http://www.dcloud.io MUI: http://dev.dcloud.net.cn/mui/getting-started/ http://dev.dcloud. ...

  2. ASP代码审计学习笔记-1.SQL注入

    ASP注入漏洞 一.SQL注入的原因 按照参数形式:数字型/字符型/搜索型 1.数字型sql查询 sql注入原因: ID=49 这类注入的参数是数字型,SQL语句原貌大致如下: id=request. ...

  3. php上传文件中文文件名乱码的解决方法

    文件上传是我们在处理表单提交时候最常用的功能之一,今天写了一个小小的demo,如下: 先看结构: html为表单提交的页面,php为处理表单的文件,upload为上传文件所放的位置 html: < ...

  4. jstl标签怎么实现分页中下一页

    <script type="text/javascript">           //分页按钮处理        function goPageAction(page ...

  5. CRUX下实现进程隐藏(3)

    通过一个内核模块拦截文件系统的回调函数来实现进程隐藏. VFS(Virtual File System)是Linux在实际文件系统(如ext3,ext4,vfat等)上抽象出的一个文件系统模型,简单来 ...

  6. Activity的LaunchMode应用场景思考

    本文链接:http://blog.csdn.net/xiaodongrush/article/details/28597855   1. 有哪几种类型?分别有什么用? http://developer ...

  7. HTML标签img--改变图片尺寸

    转自:https://blog.csdn.net/u012377333/article/details/50508484 1.统一大小? 我的网页上面有许多的图片,有的大,有的小,我想如果图片大的实现 ...

  8. 310实验室 Linux 软件安装常见问题

    电脑装好Linux系统后,系统默认安装软件不齐,需要自己根据自己的需要安装一些列工具软件,在linux系统中,用的最多的就是Synaptic Package Manager,什么是Synaptic?新 ...

  9. Linux系统下 Supervisor 安装搭建(yum安装)

    安装Supervisor # 安装supervisor yum install supervisor # 打开supervisor的配置文件 vi /etc/supervisord.conf 将sup ...

  10. mysql客户端不能插入中文字符

    问题:输入中文报错:Incorrect string value 步骤: 1.查看MySQL编码设置 show variables like '%character%'; 2.重新设置编码(注意:ut ...