//rekursive Soddykreise
procedure rekursivsoddy;
var a,b,c,ax,bx,cx,ra,rb,rc:real;
//apollonische kreise
procedure apoll(ax,ay,ar,bx,by,br,cx,cy,cr:extended;tiefe:integer);
var seitea,seiteb,seitec,
alpha,beta,gamma,
talpha,tbeta,tgamma,
dx,dy,dr:extended;
ddx,ddy,w5:real;
begin
if tiefe>8 then exit;
//Kreisradius berechnen
w5:=(br*cr+ar*(br+cr)+2*sqrtx(ar*br*cr*(ar+br+cr)));
if w5=0 then exit;
dr:= ar*br*cr/w5;
//Abstände der berührenden Kreise berechnen
seitea:=sqrtx(sqr(bx-cx)+sqr(by-cy));
seiteb:=sqrtx(sqr(ax-cx)+sqr(ay-cy));
seitec:=sqrtx(sqr(bx-ax)+sqr(by-ay));
if (seiteb*seitec*seitea<>0) then
begin
//Innenwinkel berechnen
alpha:=(seitea*seitea-seiteb*seiteb-seitec*seitec)/(-2*seiteb*seitec);
beta:=(seiteb*seiteb-seitea*seitea-seitec*seitec)/(-2*seitea*seitec);
gamma:=(seitec*seitec-seiteb*seiteb-seitea*seitea)/(-2*seiteb*seitea);
beta:=sqrtx((1+beta)/2);
gamma:=sqrtx((1+gamma)/2);
alpha:=sqrtx((1+alpha)/2);
if alpha*beta*gamma<>0 then
begin
//Parameter der trilinearen Koordinaten ermitteln
talpha:=1+beta*gamma/alpha;
tbeta:=1+alpha*gamma/beta;
tgamma:=1+alpha*beta/gamma;
//trilineare Koordinaten des Kreismittelpunktes ermitteln
trilinear(ax,ay,bx,by,cx,cy,talpha,tbeta,tgamma,ddx,ddy);
dx:=ddx;
dy:=ddy;
xkreis(dx,dy,dr);
//Ausgabe in Berechnungsliste
if pan10 then
begin
lb1.items.add('Rekursiver Soddy-Kreis'#9'M ('+_strkomma((dx-pw2)/100,1,3)+
'|'+_strkomma((-dy+ph2)/100,1,3)+'), r = '+_strkomma(dr/100,1,3));
end;
//rekursiver Aufruf weiterer Kreise
if dr>1 then
begin
apoll(ax,ay,ar,bx,by,br,dx,dy,dr,tiefe+1);
apoll(ax,ay,ar,cx,cy,cr,dx,dy,dr,tiefe+1);
apoll(bx,by,br,cx,cy,cr,dx,dy,dr,tiefe+1);
end;
end;
end;
end;
begin
//Übergeben werden die Seitenlängen sxa, sxb, sxc
//und die Innenwinkel wxa, wxb, wxg des Dreiecks
if (sxa+sxb+sxc<>0) and (cos(wxa/2)*cos(wxb/2)*cos(wxg/2)<>0) then
begin
//1.Soddy-Kreisradien berechnen
ra:=0.5*(-sxa+sxb+sxc);
rb:=0.5*(sxa-sxb+sxc);
rc:=0.5*(sxa+sxb-sxc);
can.pen.color:=clnavy;
//erster Apollonius-Kreis
apoll(punkte[1].x,punkte[1].y,ra,
punkte[2].x,punkte[2].y,rb,
punkte[3].x,punkte[3].y,rc,1);
end;
end;