// Comme la fonction buildcycle a un fonctionnement assez particulier (qui dépend
// de la définition des paths utilisés), on peut préférer procéder par "clipping".
size(7cm,0);
real r=4, R=r*1.25;
pair pC=(0,-r), pA=pC*dir(-120), pB=pC*dir(120);
path EnsA=circle(pA,R), EnsB=circle(pB,R), EnsC=circle(pC,R);
pen coulA=red, coulB=green, coulC=blue;
fill(EnsA,coulA); // On dessine EnsA,
fill(EnsB,coulB); // recouvert en partie par EnsB,
fill(EnsC,coulC); // qui lui-même est recouvert en partie par EnsC.
// Dans une image AiB, on dessine EnsA
// puis on enlève la partie qui n'est pas dans EnsB.
picture AiB; fill(AiB,EnsA,coulA+coulB); clip(AiB,EnsB);
// Dans une image AiC, on dessine EnsA
// puis on enlève la partie qui n'est pas dans EnsC.
picture AiC; fill(AiC,EnsA,coulA+coulC); clip(AiC,EnsC);
// Dans une image AiB, on dessine EnsB
// puis on enlève la partie qui n'est pas dans EnsC.
picture BiC; fill(BiC,EnsB,coulB+coulC); clip(BiC,EnsC);
// Dans une image AiBiC, on dessine EnsA
// puis on enlève les parties qui ne sont pas dans EnsB et EnsC.
picture AiBiC; fill(AiBiC,EnsA,coulA+coulB+coulC);
clip(AiBiC,EnsB); clip(AiBiC,EnsC);
// Dans l'image courante qui va être affichée, on vient
// superposer (dans un ordre réfléchi) les images précédentes.
add(AiB); add(AiC); add(BiC); add(AiBiC);
// On ajoute les contours et les étiquettes.
draw(EnsA^^EnsB^^EnsC);
transform t=scale((R+r)/r);
draw("$A$",e=ellipse,xmargin=.1cm,t*pA,p=1bp+coulA,FillDraw(coulA+white));
draw("$B$",e=ellipse,xmargin=.1cm,t*pB,p=1bp+coulB,FillDraw(coulB+white));
draw("$C$",e=ellipse,xmargin=.1cm,t*pC,p=1bp+coulC,FillDraw(coulC+white));
shipout(bbox(2mm,white));