Apollonius圆和反复计算得到的图案

这种问题首选的地址是维基百科: http://en.wikipedia.org/wiki/Circles_of_Apollonius

从作图的角度则要看笛卡尔定理(也是维基),尤其是其复数版本,同时给出半径和圆心位置的计算公式:http://en.wikipedia.org/wiki/Descartes%27_theorem

有了计算公式,就可以从任意一组(三个)Apollonius圆反复计算它们的公切圆,以及新的三圆组的公切圆,得到意想不到的图案:

1.首先,从Steiner chain (去维基!http://en.wikipedia.org/wiki/Steiner_chain)中的三个圆出发时得到的图案:

2. 从某个一个大圆和它直径上两边的两个半径1/2的小圆出发得到的结果:

圆里面数字对应直径或半径的比例;所以,可以放缩其数字(鉴于都是六的倍数);

用Mathematica完成这些图像制作非常容易:

d[A_, B_] := Sqrt[(A - B).(A - B)];
tangentCircle[{Circle[{x1_, y1_}, r1_], Circle[{x2_, y2_}, r2_],
    Circle[{x3_, y3_}, r3_]}] :=
  Module[{sols, x, y, r},
    sols = NSolve[{(x - x1)^2 + (y - y1)^2 == (r -
           r1)^2, (x - x2)^2 + (y - y2)^2 == (r +
           r2)^2, (x - x3)^2 + (y - y3)^2 == (r + r3)^2}, {x, y, r}];
    Circle[{x, y}, r] /. sols] /;
   r1 == r2 + r3 && r1 > d[{x1, y1}, {x2, y2}];

tangentCircle[{Circle[{x1_, y1_}, r1_], Circle[{x2_, y2_}, r2_],
    Circle[{x3_, y3_}, r3_]}] :=
  Module[{a2, b2, c2, d2, a3, b3, c3, d3, x, y, r, sign},
   If[r1 > d[{x1, y1}, {x2, y2}], sign = -1, sign = 1];
   a2 = 2 (x1 - x2); b2 = 2 (y1 - y2); c2 = 2 (sign r1 - r2);
   d2 = (x1^2 + y1^2 - r1^2) - (x2^2 + y2^2 - r2^2);
   a3 = 2 (x1 - x3); b3 = 2 (y1 - y3); c3 = 2 (sign r1 - r3);
   d3 = (x1^2 + y1^2 - r1^2) - (x3^2 + y3^2 - r3^2);
   x = (b3 d2 - b2 d3 - b3 c2 r + b2 c3 r)/(a2 b3 - b2 a3) // N;
   y = (-a3 d2 + a2 d3 + a3 c2 r - a2 c3 r)/(a2 b3 - a3 b2) // N;
   r = Min[
     Abs[r /. Solve[(x - x1)^2 + (y - y1)^2 == (r + sign r1)^2, r]]];
   Circle[{x, y}, r]];
tangentCircles[{Circle[{x1_, y1_}, r1_], Circle[{x2_, y2_}, r2_],
    Circle[{x3_, y3_}, r3_]}] :=
  Module[{a2, b2, c2, d2, a3, b3, c3, d3, x, y, r, sign},
   If[r1 > d[{x1, y1}, {x2, y2}], sign = -1, sign = 1];
   a2 = 2 (x1 - x2); b2 = 2 (y1 - y2); c2 = 2 (sign r1 - r2);
   d2 = (x1^2 + y1^2 - r1^2) - (x2^2 + y2^2 - r2^2);
   a3 = 2 (x1 - x3); b3 = 2 (y1 - y3); c3 = 2 (sign r1 - r3);
   d3 = (x1^2 + y1^2 - r1^2) - (x3^2 + y3^2 - r3^2);
   x = (b3 d2 - b2 d3 - b3 c2 r + b2 c3 r)/(a2 b3 - b2 a3) // N;
   y = (-a3 d2 + a2 d3 + a3 c2 r - a2 c3 r)/(a2 b3 - a3 b2) // N;
   Circle[{x, y}, Abs[r]] /.
    Solve[(x - x1)^2 + (y - y1)^2 == (r + sign r1)^2, r]];
triplets[{a_, b_, c_}, d_] := {{a, b, d}, {a, c, d}, {b, c, d}};
triplets[{a_, b_, c_Circle}, l_List] := triplets[{a, b, c}, #] & /@ l;
apollonianStep[{a_Circle, b_, c_}] :=
  triplets[{a, b, c}, tangentCircle[{a, b, c}]];
apollonianStep[l_List] := apollonianStep /@ l;

(*{circ1,circ2,circ3,circ4}={Circle[{0,0},1/6],Circle[{1/6-1/11,0},1/11],Circle[{-8/105,-2/35},1/14],Circle[{-3/50,2/25},1/15]};
init={{circ1,circ2,circ3},{circ1,circ2,circ4},{circ1,circ3,circ4},{circ2,circ3,circ4}};*)

{circ1, circ2, circ3} = {Circle[{0, 0}, 1/6],
   Circle[{-1/12, 0}, 1/12], Circle[{1/12, 0}, 1/12]};
init = {{circ1, circ2, circ3}};

circs = TimeConstrained[
   Union[Flatten[
     init //. {a_, b_, Circle[p_, r_]} :>
       apollonianStep[{a, b, Circle[p, r]}] /; r > .01]], 10];
moreCircs =
  Union[Flatten[
    init //. {a_, b_, Circle[p_, r_]} :>
      apollonianStep[{a, b, Circle[p, r]}] /; r > .0005]];

number[Circle[c_, r_]] :=
  Text[Style[Round[1/r/6], FontSize -> 550 r], c];
Graphics[{Blue, circs, moreCircs,
  Map[number, DeleteCases[circs, Circle[{0, 0}, _]]]},
 ImageSize -> Full]

这段代码是蓝色图案生成用的,容易修改init的生成,修改Text中字体的设置生成其它的。

代码绝大部分来自于:

Mathematica.stackexchange.com: http://mathematica.stackexchange.com/questions/11016/is-there-a-way-to-solve-the-apollonius-circle-problem-in-mathematica

时间: 2024-08-04 16:51:43

Apollonius圆和反复计算得到的图案的相关文章

圆的相关计算

package 练习; import java.awt.BorderLayout;import java.awt.Color;import java.awt.Font; import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import java.awt.GridLayout;import java.awt.TextArea;import j

创建一个圆类Circle的对象,分别设置圆的半径计算并分别显示圆半径、圆面积、圆周长。

编写一个圆类Circle,该类拥有: ①一个成员变量 Radius(私有,浮点型): // 存放圆的半径: ②两个构造方法 Circle( ) // 将半径设为0 Circle(double r ) //创建Circle对象时将半径初始化为r ③ 三个成员方法 double getArea( ) //计算圆的面积 double getPerimeter( ) //计算圆的周长 void show( ) //将圆的半径.周长.面积输出到屏幕 编写应用程序,创建类的对象,分别设置圆的半径计算并分别显

1-3-09:与圆相关的计算

描述 给出圆的半径,求圆的直径.周长和面积. 输入输入包含一个实数r(0 < r <= 10,000),表示圆的半径.输出输出一行,包含三个数,分别表示圆的直径.周长.面积,数与数之间以一个空格分开,每个数保留小数点后4位.样例输入 3.0 样例输出 6.0000 18.8495 28.2743 提示如果圆的半径是r,那么圆的直径.周长.面积分别是2*r.2 * pi * r.pi * r * r,其中约定pi=3.14159.可以使用printf("%.4lf", ...

Java作业 输入圆的半径计算输出圆的周长和面积

1 package text1; 2 3 import java.util.Scanner; 4 5 public class text11 { 6 public static void main(String[] args){ 7 8 Scanner sc =new Scanner(System.in); 9 10 11 System.out.print("输入圆的半径"); 12 int a =sc.nextInt(); 13 14 15 System.out.print(&quo

HDU 4773 Problem of Apollonius——圆反演

题面 HDU4773 解析  大概是圆反演的模板吧. 以点$P(x3, y3)$为反演中心,任意长为反演半径,将两个已知圆反演,设反演后的圆为$A'$, $B'$,所求圆反演后为一条直线,根据题目中的要求,该直线为两圆的外公切线.因此我们只需要求出两圆的外公切线即可. 然后会发现WA了,因为题目中还有一个要求,所求圆要外切于两圆,即反演变换后反演中心$P$和$A'$的圆心要在同侧. 还有一个我一开始做错了的地方,原来的圆心$O$反演后就不是新的圆心了!!!可以连接$PO$,求其与圆的两个交点,两

OpenGL研究2.0 计算圆

DionysosLai2014-06-18 在游戏中.常常有些地方涉及到一些圆的轨迹计算,例如一些转轴类的游戏,人物一般在角色转轴上面运动.这时,我们就要时刻计算角色的位置. 分析一下.圆位置的一般算法. 首先.例如以下图的一个圆: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRGlvbnlzb3NfbGFp/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

计数方法(扫描线):JLOI 2016 圆的异或并

Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面 积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆内则不考虑. Input 第一行包含一个正整数N,代表圆的个数.接下来N行,每行3个非负整数x,y,r,表示一个圆心在(x,y),半径为r的 圆.保证|x|,|y|,≤10^8,r>0,N<=200000 Output 仅一行一个整数,表示所有圆的异或面积并除以圆周率Pi的结果. Sample

Bzoj4561 [JLoi2016]圆的异或并

Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 521  Solved: 224 Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面 积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆内则不考虑. Input 第一行包含一个正整数N,代表圆的个数.接下来N行,每行3个非负整数x,y,r,表示一个圆心在(x,y),半径为r的 圆.保证|x|,|y|,≤

Hadoop的计算特征以及一般用在哪些业务场景?(转载)

其实我们要知道大数据的实质特性:针对增量中海量的结构化,非结构化,半结构数据,在这种情况下,如何快速反复计算挖掘出高效益的市场数据? 带着这个问题渗透到业务中去分析,就知道hadoop需要应用到什么业务场景了!!!如果关系型数据库都能应付的工作还需要hadoop吗? 比如 1.银行的信用卡业务,当你正在刷卡完一笔消费的那一瞬间,假如在你当天消费基础上再消费满某个额度,你就可以免费获得某种令你非常满意的利益等等,你可能就会心动再去消费,这样就可能提高银行信用卡业务,那么这个消费额度是如何从海量的业