comment:
trappedPoint.Index is the base circle index: 0 (center), 1-N (in ring) trappedPoint.Delta is the level: 0 - Steps-1
See the paper: "Evolution of Math into Art via Mobius Transformations" by Anne M. Burns, Department of Mathematics, Long Island University. http://myweb.cwpost.liu.edu/aburns/
Also, see pages 88-89 in the book: "Indra's Pearls, The Vision of Felix Klein" by David Mumford, Caroline Series, David Wright. http://klein.math.okstate.edu/IndrasPearls/
global:
Complex ShowCenter[] = LC1,LC2,LC3,LC4,LC5,LC6,LC7,LC8,LC9,LC10,LC11,LC12,LC13,LC14,LC15,LC16 Complex ShowRing[] = LR1,LR2,LR3,LR4,LR5,LR6,LR7,LR8,LR9,LR10,LR11,LR12,LR13,LR14,LR15,LR16 AbsV = Sqrt(AbsU^2 - 1) u = AbsU * Cis(DegreeToRadian(ArgU)) v = AbsV * Cis(DegreeToRadian(ArgV)) Mobius UnitCircleGroup = Mobius(u, v, Conj(v), Conj(u))
totalGen = 1 + N + 32 Mobius m[totalGen] ' ' Given N, find radius R such that N circles with radius R can be ' placed along the inside of the unit circle, each tangent to the ' unit circle and each of its two adjacent neighbors. ' r = 1/(1+1/Sin(Math.PI/N))
step = 2Math.PI/N
ang = IIf(Shift, step/2, 0)
'
' Center generator (index 0)
'
m[0] = Mobius(1-2r, 0, 0, 1)
'
' Ring generators (indices 1..N)
'
for (i = 1, i <= N, i += 1) {
rotate = Cis(ang)
m[i] = Mobius.Multiply(
Mobius(rrotate, (1-r)rotate, 0, 1),
UnitCircleGroup
)
ang += step
}
'
' Custom generators
'
m[N+1]=Mobius(0.085786442,Complex( 0.292893222, 0.292893222),0,1)
m[N+2]=Mobius(0.085786442,Complex(-0.292893222,-0.292893222),0,1)
m[N+3]=Mobius(0.085786442,Complex( 0.292893222,-0.292893222),0,1)
m[N+4]=Mobius(0.085786442,Complex(-0.292893222, 0.292893222),0,1)
m[N+5]=Mobius(0.022407752,Complex(0.216388382,0.216388382), 0, 1) m[N+6]=Mobius(0.022407752,Complex(-0.216388382,0.216388382), 0, 1) m[N+7]=Mobius(0.022407752,Complex(-0.216388382,-0.216388382), 0, 1) m[N+8]=Mobius(0.022407752,Complex(0.216388382,-0.216388382), 0, 1)
m[N+9]=Mobius(0.041421362,Complex(0.400000002,0.224264072), 0, 1) m[N+10]=Mobius(0.041421362,Complex(0.224264072,0.400000002), 0, 1)
m[N+11]=Mobius(0.041421362,Complex(-0.400000002,0.224264072), 0, 1) m[N+12]=Mobius(0.041421362,Complex(-0.224264072,0.400000002), 0, 1)
m[N+13]=Mobius(0.041421362,Complex(-0.400000002,-0.224264072), 0, 1) m[N+14]=Mobius(0.041421362,Complex(-0.224264072,-0.400000002), 0, 1)
m[N+15]=Mobius(0.041421362,Complex(0.400000002,-0.224264072), 0, 1) m[N+16]=Mobius(0.041421362,Complex(0.224264072,-0.400000002), 0, 1)
m[N+17]=Mobius(0.022407752,Complex( 0.076504842, 0.076504842), 0, 1) m[N+18]=Mobius(0.022407752,Complex(-0.076504842, -0.076504842), 0, 1) m[N+19]=Mobius(0.022407752,Complex( 0.076504842, -0.076504842), 0, 1) m[N+20]=Mobius(0.022407752,Complex(-0.076504842, 0.076504842), 0, 1)
m[N+21]=Mobius(0.010318672,Complex(0.099645922, 0.099645922), 0, 1) m[N+22]=Mobius(0.008518112,Complex(0.082258122, 0.046118852), 0, 1) m[N+23]=Mobius(0.008518112,Complex(0.046118852, 0.08225812*2), 0, 1)
m[N+24]=Mobius(0.010318672,Complex(-0.099645922, 0.099645922), 0, 1) m[N+25]=Mobius(0.008518112,Complex(-0.082258122, 0.046118852), 0, 1) m[N+26]=Mobius(0.008518112,Complex(-0.046118852, 0.08225812*2), 0, 1)
m[N+27]=Mobius(0.010318672,Complex(-0.099645922, -0.099645922), 0, 1) m[N+28]=Mobius(0.008518112,Complex(-0.082258122, -0.046118852), 0, 1) m[N+29]=Mobius(0.008518112,Complex(-0.046118852, -0.08225812*2), 0, 1)
m[N+30]=Mobius(0.010318672,Complex(0.099645922, -0.099645922), 0, 1) m[N+31]=Mobius(0.008518112,Complex(0.082258122, -0.046118852), 0, 1) m[N+32]=Mobius(0.008518112,Complex(0.046118852, -0.08225812*2), 0, 1)
' ' Assign Total = the total number of circles. ' const Complex Total = 0 count = totalGen
for (i = 0, i < Steps, i += 1) { Total += count count *= totalGen } const Circle c[Total] const Complex index[Total] const Complex level[Total] Circle UnitCircle = CircleC(0, 1) ' ' Generate the base circles (all generators applied to unit circle) ' for (i = 0, i < totalGen, i += 1) { c[i] = Mobius.TransformCircle(m[i], UnitCircle) index[i] = i level[i] = 0 } count = totalGen max = 0 ' ' Generate the remaining circles by applying all generators iteratively. ' if (Steps > 1) { for (i = 1, i < Steps, i += 1) { min = max max = count
for (j = min, j < max, j += 1) { for (k = 0, k < totalGen, k += 1) { c[count] = Mobius.TransformCircle(m[k], c[j]) if (c[count].Radius >= RadiusMin) { index[count] = index[j] level[count] = i count += 1 } } } } } Total = count
CurveTrap.Initialize(
Center, DegreeToRadian(Angle), Scale, AlternateAngle, 6, False, LineWidth
)
'
' Add the circles to the trap.
'
for (i = 0, i < Total, i += 1) {
lev = level[i]
idx = index[i]
if (idx = 0) {
if (ShowCenter[lev]) {
CurveTrap.AddCircle2(c[i], Solid, IIf(Solid, lev, 0), idx, lev)
}
} else {
if (ShowRing[lev]) {
CurveTrap.AddCircle2(c[i], Solid, IIf(Solid, lev, 0), idx, lev)
}
}
}
trap:
trappedPoint = CurveTrap.Apply(z)
properties:
divider { caption = "General Options" } option Center { type = Complex caption = "Center" details = "Center of trap" default = 0 } option Angle { type = Float caption = "Angle" details = "Angle of rotation" default = 0 range = [-360,360] } option Scale { type = Float caption = "Scale" details = "Scale factor applied to trap" range = (0,) default = 2 } option Solid { type = Boolean caption = "Solid" details = "Check to create solid trap" default = False } option AlternateAngle { type = Boolean caption = "Alternate Angle" details = "Use alternate angle calculation" default = False } option LineWidth { type = Float caption = "Line Width" details = "Extent of trap on either side of curve (> 0)" range = (0,) default = 0.00411522633744855967078189300413 enabled = ~Solid } divider { caption = "U/V Controls" } option AbsU { type = Float caption = "Abs(U)" details = "Magnitude of U (1-2)" default = 1.1 range = [1,2] } option ArgU { type = Float caption = "Arg(U)" details = "Angle of U" default = 0 range = [-360,360] } option ArgV { type = Float caption = "Arg(V)" details = "Angle of V" default = 180 range = [-360,360] } divider { caption = "Circle Controls" } option N { type = IntegerEnum(3,12) caption = "N" details = "Number of base circles" default = 4 } option Steps { type = IntegerEnum(1,16) caption = "Steps" details = "Number of inversion steps" default = 4 ' <-- REDUCED from 8 to 4 to avoid memory crash } option Shift { type = Boolean caption = "Shift" details = "Check to rotate initial chain by pi/N" default = False } option RadiusMin { type = Float caption = "Radius Min" details = "Minimum acceptable circle radius" default = 0 range = [0,) } #define ShowLevel(Index)
divider { caption = "Level #Index# Options" } option LR#Index# { type = Boolean caption = "Show Ring" details = "Show ring of circles at level #Index#" default = True enabled = Steps >= #Index# } option LC#Index# { type = Boolean caption = "Show Center" details = "Show center circle at level #Index#" default = True enabled = Steps >= #Index# } #end
#include ShowLevel("1") #include ShowLevel("2") #include ShowLevel("3") #include ShowLevel("4") #include ShowLevel("5") #include ShowLevel("6") #include ShowLevel("7") #include ShowLevel("8") #include ShowLevel("9") #include ShowLevel("10") #include ShowLevel("11") #include ShowLevel("12") #include ShowLevel("13") #include ShowLevel("14") #include ShowLevel("15") #include ShowLevel("16")