圆的反演变换(*)

58 篇文章 1 订阅
46 篇文章 0 订阅

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4773


题意:给定两个圆,告诉半径和圆心,它们是相离的,在这两个圆外给定一个点p,求符合条件:过点p的圆且与已知的两个

外切的所有圆的总数和它们的圆心坐标和半径。



分析:根据题意,我们设已知两个圆的半径分别为,它们的圆心分别为,设点p的坐标为


并设要求的圆的圆心为,半径为,那么根据它们的关系我们可以很快就列出方程组:




然后,现在的问题就是来解,但是你会发现这个方程是很难解的,因此为了简化问题,我们利用反演变换来做。



那么,怎么用反演变换来做? 首先,得知道什么是反演变换以及它有什么性质。


反演的定义:


已知一圆C,圆心为O,半径为r,如果P与P’在过圆心O的直线上,且,则称P与P'关于O互为反演。


反演的性质:


(1)除反演中心外,平面上的每一个点都只有唯一的反演点,且这种关系是对称的,位于反演圆上的点,保持在原处,位于

反演圆外部的点,变为圆内部的点,位于反演圆内部的点,变为圆外部的点。 举个最简单的例子,区间以1为反演

半径,那么反演后的区间就是,这就是一维反演,而圆的反演是二维反演。


(2)任意一条不过反演中心的直线,它的反形是经过反演中心的圆,反之亦然,特别地,过反演中心相交的圆,变为不过反

演中心的相交直线。





定理:不过反演中心的圆,它的反形是一个圆,反演中心是这两个互为反形的圆的一个位似中心,任意一对反演点是逆对应

点。用图形来解释,如下图:




那么,对于一个不过反演中心的圆,怎样求它的反形圆?


很容易知道我们只需要求出反形圆的圆心和半径就可以了。


对于上图我们设圆C1的半径为,C2的半径为,反演半径为


那么根据反演的定义有:




那么,消去得到:




这样我们就得到了反形圆的半径,那么还要求反形圆的圆心。



由于C1和O两点的坐标已知,而且我们知道O,C1,C2位于同一直线上,那么很明显对于C2的坐标,我们可以这样计算:


设O的坐标为,C1的坐标为,C2的坐标为


那么有:




至于由上面解处可以很容易得到,这样我们就完成了圆的反演变换。



由于本题的做法是这样的,先以点P为为反演中心,反演半径随便设置都可以,为了计算方便就设为1,把圆C1和圆C2反演后再求这两个圆的

公切线,再把这个公切线反演回去,那么就是一个过点P的圆,且与原来的C1和C2相切。



那么接下来就是如何计算两个圆的公切线了。这里只需要考虑公切线在同一侧的情况。那么,这个自己画图就能很容易计算了。

找到公切线后还要把它反演成圆,这个圆还经过P点,那么很容易得到了。


[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include <string.h>  
  3. #include <stdio.h>  
  4. #include <math.h>  
  5.   
  6. using namespace std;  
  7. double const eps = 1e-8;  
  8.   
  9. struct Point  
  10. {  
  11.     double x,y;  
  12.     Point(double a = 1.0,double b = 1.0):x(a),y(b){}  
  13.     Point operator + (const Point &a)  
  14.     {  
  15.         return Point(x+a.x,y+a.y);  
  16.     }  
  17.     Point operator - (const Point &a)  
  18.     {  
  19.         return Point(x-a.x,y-a.y);  
  20.     }  
  21.     Point operator * (const double a)  
  22.     {  
  23.         return Point(a*x,a*y);  
  24.     }  
  25.     Point Trans()  
  26.     {  
  27.         return Point(-y,x);  
  28.     }  
  29.     void Input()  
  30.     {  
  31.         scanf("%lf%lf",&x,&y);  
  32.     }  
  33. } ;  
  34.   
  35. struct Circle  
  36. {  
  37.     Point o;  
  38.     double r;  
  39.     Circle(Point a = Point(),double b = 1.0):o(a),r(b) {}  
  40.     Point getPoint(double alpha)  
  41.     {  
  42.         return o + Point(r*cos(alpha),r*sin(alpha));  
  43.     }  
  44.     void Input()  
  45.     {  
  46.         o.Input();  
  47.         scanf("%lf",&r);  
  48.     }  
  49.     void Output()  
  50.     {  
  51.         printf("%.8lf %.8lf %.8lf\n",o.x,o.y,r);  
  52.     }  
  53. } ;  
  54.   
  55. Point p;  
  56. Circle c[15];  
  57.   
  58. double dist(Point A,Point B)  
  59. {  
  60.     return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y));  
  61. }  
  62.   
  63. double cross(Point A,Point B,Point C)  
  64. {  
  65.     return (B.x-A.x)*(C.y-A.y) - (B.y-A.y)*(C.x-A.x);  
  66. }  
  67.   
  68. int sign(double x)  
  69. {  
  70.     return (x > eps) - (x < -eps);  
  71. }  
  72.   
  73. Circle Inverse(Circle C)  
  74. {  
  75.     Circle T;  
  76.     double t = dist(C.o,p);  
  77.     double x = 1.0 / (t - C.r);  
  78.     double y = 1.0 / (t + C.r);  
  79.     T.r = (x - y) / 2.0;  
  80.     double s = (x + y) / 2.0;  
  81.     T.o = p + (C.o - p) * (s / t);  
  82.     return T;  
  83. }  
  84.   
  85. void add(Point a,Point b,int &k)  
  86. {  
  87.     double t = cross(a,p,b);  
  88.     if(t < 0) t = -t;  
  89.     double d = dist(a,b);  
  90.     t /= d;  
  91.     if(t > eps)  
  92.     {  
  93.         double w = 0.5 / t;  
  94.         Point dir = (b-a).Trans();  
  95.         Point a1 = p + dir * (w / d);  
  96.         Point b1 = p - dir * (w / d);  
  97.         if(fabs(cross(a,b,a1)) < fabs(cross(a,b,b1)))  
  98.            c[k++] = Circle(a1,w);  
  99.         else  
  100.            c[k++] = Circle(b1,w);  
  101.     }  
  102. }  
  103.   
  104. int Work()  
  105. {  
  106.     c[0] = Inverse(c[0]);  
  107.     c[1] = Inverse(c[1]);  
  108.     if(c[1].r > c[0].r) swap(c[1],c[0]);  
  109.     Point v = c[1].o - c[0].o;  
  110.     double alpha = atan2(v.y,v.x);  
  111.     double d = dist(c[0].o,c[1].o);  
  112.     double beta  = acos((c[0].r - c[1].r) / d);  
  113.     int k = 2;  
  114.     Point a = c[0].getPoint(alpha + beta);  
  115.     Point b = c[1].getPoint(alpha + beta);  
  116.     if(sign(cross(a,c[0].o,b)) == sign(cross(a,p,b)) &&  
  117.        sign(cross(a,c[1].o,b)) == sign(cross(a,p,b)))  
  118.         add(a,b,k);  
  119.     a = c[0].getPoint(alpha - beta);  
  120.     b = c[1].getPoint(alpha - beta);  
  121.     if(sign(cross(a,c[0].o,b)) == sign(cross(a,p,b)) &&  
  122.        sign(cross(a,c[1].o,b)) == sign(cross(a,p,b)))  
  123.         add(a,b,k);  
  124.     return k - 2;  
  125. }  
  126.   
  127. int main()  
  128. {  
  129.     int T;  
  130.     scanf("%d",&T);  
  131.     while(T--)  
  132.     {  
  133.         c[0].Input();  
  134.         c[1].Input();  
  135.         p.Input();  
  136.         int num = Work();  
  137.         printf("%d\n",num);  
  138.         for(int i=0;i<num;i++)  
  139.             c[i+2].Output();  
  140.     }  
  141.     return 0;  
  142. }  
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作者: 萧振纲 出版社: 大连理工大学出版社 副标题: 几何变换与几何证题 出版年: 2010-5 页数: 749 定价: 88.00元 ISBN: 9787560329956 内容简介 · · · · · · 《几何变换与几何证题》所研究的几何变换仅限于平面上的合同变换、相似变换反演变换这三类初等几何变换;《几何变换与几何证题》系统地阐述了这三类几何变换的理论和它们在几何证题方面的应用。阅读《几何变换与几何证题》只需要具有中学数学知识即可;对于阅读几何变换理论有困难的读者,也可以只阅读与几何证题有关的章节。 《几何变换与几何证题》适合大中师生及数学爱好者使用。 目录 · · · · · · 第1章 合同变换 1.1 映射·变换·变换群  1.2 合同变换及其性质 1.3 三种基本合同变换——平移、旋转、轴反射 1.4 合同变换与基本合同变换的关系 1.5 自对称图形 习题1第2章 相似变换 2.1 相似变换及其性质 2.2 基本相似变换——位似变换 2.3 位似旋转变换 2.4 位似轴反射变换 2.5 三相似图形 习题2第3章 平移变换与几何证题 3.1 平行四边形与平移变换 3.2 共线相等线段与平移变换 3.3 一般相等线段与平移变换 3.4 平行与平移变换 3.5 线段比及其他与平移变换 习题3第4章 旋转变换与几何证题 4.1 中点与中心反射变换 4.2 平行四边形及其他与中心反射变换 4.3 正三角形与旋转变换 4.4 正方形、等腰直角三角形与旋转变换 4.5 等腰三角形、相等线段与旋转变换 4.6 三角形的连接与旋转变换之积 习题4第5章 轴反射变换与几何证题 5.1 轴对称图形与轴反射变换 5.2 角平分线与轴反射变换 5.3 垂直与轴反射变换 5.4 与轴反射变换 5.5 内接四边形的两个基本性质 5.6 30°的角与轴反射变换 5.7 两类几何不等式与轴反射变换 5.8 轴反射变换处理其他问题举例 习题5第6章 位似变换与几何证题 6.1 线段比与位似变换 6.2 共点线、共线点与位似变换 6.3 Menelaus定理与Ceva定理 6.4 两与位似变换 6.5 平行及其他与位似变换 习题6第7章 位似旋转变换、位似轴反射变换与几何证题 7.1 三角形与位似旋转变换 7.2 同向相似三角形与位似旋转变换 7.3 两与位似旋转变换 7.4 等角线及其他与位似旋转变换 7.5 三角形的连接与位似旋转变换之积 7.6 位似轴反射变换与几何证题 习题7第8章 反演变换 8.1 反演变换及其性质 8.2 线段度量关系与反演变换 8.3 反演变换 8.4 两的互反性 8.5 几何命题的反演命题 8.6 极点与极线 习题8附录 附录A 点对的幂·根轴·根心 附录B Menelaus定理与Ceva定理的角元形式参考解答参考文献编辑手记 萧振纲,教授。毕业于湖南师范大学数学系。长期致力于初等数学与竞赛数学的教学研究工作。自1984年开始,先后在国内外刊物上发表初等数学与竞赛数学的教学研究论文130余篇。 出版《几何变换与几何证题》学术专著1部;与他人合作出版《初等数论》教材一部;参与编写《初等几何研究》教材一部;在全国数学竞赛命题比赛中曾获一等奖;并先后为全国高中数学联赛,IMO中国国家集训队,IMO中国国家队选拔考试以及中国东南地区数学奥林匹克提供过平面几何试题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值