digraphIFS = {
let g = transform.g;
let fs = IFS.IFS.affine_function_list;
let f_invs = fs.map((af) => af.invert());
let pts = fs.map((af) => af.fixed_point);
let P0 = new Flatten.Polygon(pts.map((xy) => Flatten.point(xy)));
let C = [g];
let S = [g];
while (S.length > 0) {
S = step1(S).filter(test);
let test2 = (f) => C.map((F) => F.equal(f)).indexOf(true) > -1;
S = S.filter((f) => !test2(f));
let S_new = [];
S.forEach(function (f) {
let is_in = S_new.map((F) => f.equal(F)).indexOf(true) > -1;
if (!is_in) {
S_new.push(f);
}
});
S = S_new;
C = C.concat(S);
}
let edges = [];
for (let i = 0; i < C.length; i++) {
for (let j = 0; j < C.length; j++) {
fs.forEach(function (fi, k) {
fs.forEach(function (fj) {
let g = C[i];
let h = C[j];
let fi_inv = f_invs[k];
if (fi_inv.compose(g).compose(fj).equal(h)) {
edges.push({
source: i,
target: j,
f: fi
});
}
});
});
}
}
let digraphIFS = new DigraphIFS(edges);
digraphIFS.C = C;
return digraphIFS;
function test(af) {
let P = new Flatten.Polygon(pts.map((xy) => Flatten.point(af.f(xy))));
return P0.intersect(P).length > 0;
}
function step1(S) {
return f_invs
.map((F) => S.map((g) => fs.map((f) => F.compose(g).compose(f))))
.flat(2);
}
}