This is a child of InvertSphere. For the case of 3 base circles
(Apollonian Gasket) methods for perturbation of the initiating circles
are available.
Class InvertCircles(InvertSphere) {
;
; circle inversions <br>
; <p>
; This is a child of InvertSphere. For the case of 3 base circles
; (Apollonian Gasket) methods for perturbation of the initiating circles
; are available.
; <p>
$define debug
public:
import "common.ulb"
; constructor for circle inversions using spheres
func InvertCircles(Generic pparent)
InvertSphere.InvertSphere(0)
ang = 2*#pi/@ncircle
ipi = flip(#pi)
cpi = flip(#pi/@ncircle)
complex cr1 = exp((0,0)*ang+ipi)
complex cr2 = exp((0,1)*ang+ipi)
float rdd = cabs(cr1-cr2)/2
dd = cabs(cr1)
float dtan = sqrt(dd*dd-rdd*rdd)
fscle = (dd+rdd)/dtan
pert = @pert
pert = 11 - pert
fscle2 = 1
fbaserad = fscle*2*sqrt(3)/3
fii = @ncircle+1
fjj = @ncircle+1
fks = @ncircle
fk = fks
g = 0
b = 0
circles = true
showc = @showc
lace = @lace
if @ncircle == 3
rlevel = 4
scale = 0.5
if @ptype == "Inner Circle" && pert <= 2
cir3 = true
endif
if @ptype == "None"
fscle = 2 + sqrt(3)
fscle2 = 1
elseif @ptype == "Outer Circles"
fscle = (2 + sqrt(3))*cos(#pi/(pert+6))
fscle2 = (fscle-sqrt(3)-1.5)/0.5
else
if pert == 10
fscle2 = 1.0041268407
elseif pert == 9
fscle2 = 1.0049465720
elseif pert == 8
fscle2 = 1.0060422243
elseif pert == 7
fscle2 = 1.0075560883
elseif pert == 6
fscle2 = 1.0097381547
elseif pert == 5
fscle2 = 1.0130643119
elseif pert == 4
fscle2 = 1.0185254
elseif pert == 3
fscle2 = 1.0286754
elseif pert == 2
fscle2 = 1.0515254
elseif pert == 1
fscle2 = 1.1277437913
endif
endif
elseif @ncircle == 4
rlevel = 9
scale = 0.55
elseif @ncircle == 5
rlevel = 16
scale = 0.6
elseif @ncircle == 6
rlevel = 25
scale = 0.65
elseif @ncircle == 7
rlevel = 36
scale = 0.65
elseif @ncircle == 8
rlevel = 49
scale = 0.7
elseif @ncircle == 9
rlevel = 64
scale = 0.7
elseif @ncircle == 10
rlevel = 81
scale = 0.7
elseif @ncircle == 11
rlevel = 100
scale = 0.7
elseif @ncircle == 12
rlevel = 121
scale = 0.7
endif
initSpheres()
endfunc
; Initializes base and generator spheres
func InitSpheres()
complex Fc[26]
float Fz[26]
float Fr[26]
; generator set
int i = 0
while i < @ncircle
Fc[i] = exp(flip(i)*ang+ipi)*fscle
Fz[i] = 0
i = i + 1
endwhile
Fc[i] = 0
if @ncircle == 3
Fr[0] = sqrt(3)+1.5
else
Fr[0] = cabs(Fc[0]-Fc[1])/2
endif
i = 1
while i < @ncircle
Fr[i] = Fr[0]
i = i + 1
endwhile
if @ncircle == 3
if @ptype == "None"
Fr[3] = 0.5
elseif @ptype == "Outer Circles"
Fr[3] = fscle-sqrt(3)-1.5
elseif @ptype == "Inner Circle"
if pert == 10
Fr[3] = 0.5151714074
elseif pert == 9
Fr[3] = 0.5181320854
elseif pert == 8
Fr[3] = 0.5220631074
elseif pert == 7
Fr[3] = 0.5274464005
elseif pert == 6
Fr[3] = 0.5351105381
elseif pert == 5
Fr[3] = 0.5465863845
elseif pert == 4
Fr[3] = 0.564987
elseif pert == 3
Fr[3] = 0.597588
elseif pert == 2
Fr[3] = 0.665053
elseif pert == 1
Fr[3] = 0.8524941755
endif
endif
else
Fr[i] = cabs(Fc[0])-Fr[0]
endif
g = i
; Base set
i = i + 1
if @ncircle%2 == 0
while i < 2*@ncircle+1
Fc[i] = exp(flip(i-4)*ang+cpi)*fscle2
Fz[i] = 0
i = i + 1
endwhile
else
sflag = false
while i < 2*@ncircle+1
Fc[i] = exp(flip(i-3)*ang)*fscle2
Fz[i] = 0
i = i + 1
endwhile
endif
Fc[i] = 0
if @ncircle == 3
if @ptype == "Outer Circles" || @ptype == "None"
Fr[4] = sqrt(3)/2*fscle2
Fr[7] = Fr[4]+fscle2
elseif @ptype == "Inner Circle"
if pert == 10
Fr[4] = 0.8618985631
elseif pert == 9
Fr[4] = 0.8610788318
elseif pert == 8
Fr[4] = 0.8599831795
elseif pert == 7
Fr[4] = 0.8584693155
elseif pert == 6
Fr[4] = 0.8562872491
elseif pert == 5
Fr[4] = 0.8529610919
elseif pert == 4
Fr[4] = 0.8475
elseif pert == 3
Fr[4] = 0.83735
elseif pert == 2
Fr[4] = 0.8145
elseif pert == 1
Fr[4] = 0.7382816125
endif
Fr[7] = Fr[4] + 1
endif
else
Fr[@ncircle+1] = cabs(Fc[@ncircle+1]-Fc[@ncircle+2])/2
endif
i = @ncircle+2
while i < 2*@ncircle+1
Fr[i] = Fr[@ncircle+1]
i = i + 1
endwhile
if @ncircle != 3
dd = cabs(Fc[0])
Fr[i] = sqrt(dd*dd-Fr[0]*Fr[0])
endif
b = i
i = 0
; scale and translate the spheres to screen dimensions
;
repeat
if reflect
Fc[i] = -conj(Fc[i])
else
Fc[i] = Fc[i]
endif
; Z axis rotation
Fc[i] = Fc[i]*zrot
; Y axis rotation
temp = real(Fc[i]) + flip(Fz[i])
temp = temp*yrot
Fc[i] = real(temp) + flip(imag(Fc[i]))
Fz[i] = imag(temp)
; X axis rotation
temp = imag(Fc[i]) + flip(Fz[i])
temp = temp*xrot
Fc[i] = real(Fc[i]) + flip(real(temp))
Fz[i] = imag(temp)
; scaling
Fc[i] = Fc[i]*#magn*scale
Fz[i] = Fz[i]*#magn*scale
if i > 12
Fr[i] = Fr[i]*#magn*scale*@bradadj
else
Fr[i] = Fr[i]*#magn*scale*@radadj
endif
i = i+1
until i == 2*@ncircle+2
;
; declare the generator spheres
i = 0
while i <= g
fg[i] = new Sphere(Fc[i],Fz[i],Fr[i],0,i)
i = i + 1
endwhile
; declare the base Spheres
i = 0
while i <= g
fb[i] = new Sphere(Fc[i+g+1],Fz[i+g+1],Fr[i+g+1],0,i)
i = i + 1
endwhile
bradius = fb[0].frad
i = 0
while i <= g
s.sph[i] = fb[i]
i = i + 1
endwhile
endfunc
int g
int b
float ang
complex ipi
complex cpi
float dd
int pert
float fscle2
bool showc
default:
title = "Circle Inversions"
int param v_invcircle
caption = "Version (Circle Inversions)"
default = 100
hint = "This version parameter is used to detect when a change has been made to the formula that is incompatible with the previous version. When that happens, this field will reflect the old version number to alert you to the fact that an alternate rendering is being used."
visible = @v_invcircle < 100
endparam
int param ncircle
caption = "# of Circles (3-12)"
default = 3
min = 3
max = 12
endparam
int param maxLevel
caption = "Recursion level"
default = 20
min = 0
max = 200
endparam
bool param showc
caption = "Show Center Circle"
default = true
endparam
bool param lace
caption = "Display as Lace"
default = false
visible = @ptype == "Inner Circle" && (@pert >=8) && @ncircle == 3
endparam
heading
text = "Perturbation of Inversion Circles \
by overlap."
visible = @ncircle == 3
endheading
param ptype
caption = "Perturb Type"
default = 0
enum = "None" "Outer Circles" "Inner Circle"
visible = @ncircle == 3
endparam
param pert
caption = "Perturb Level (1-10)"
default = 1
min = 1
max = 10
visible = @ptype != "None" && @ncircle == 3
endparam
float param xang
caption = "X Axis Rotation"
default = 0.0
endparam
float param yang
caption = "Y Axis Rotation"
default = 0.0
endparam
}