9

I am trying to get the union of four circles in asymptote:

unitsize(1mm);
import graph;
pair o1 = (0, 0);
pair o2 = (10, 0);
pair o3 = (10, 10);
pair o4 = (0, 10);
path c1 = Circle(o1, 10);
path c2 = Circle(o2, 10);
path c3 = Circle(o3, 10);
path c4 = Circle(o4, 10);
draw(c1^^c2^^c3^^c4, black);

Apparently this is not the right way:

enter image description here

Using inkscape I can get the desired effect:

enter image description here

@g.kov 's answer partially solves the problem, but if the paths are not consecutively intersecting, then buildcycle will not work:

unitsize(1mm);
import graph;
pair o1 = (0, 0);
pair o2 = (10, 0);
pair o3 = (10, 10);
pair o4 = (0, 10);
path c1 = Circle(o1, 8);
path c2 = Circle(o2, 8);
path c3 = Circle(o3, 1);
path c4 = Circle(o4, 1);

guide[] gg=c1^^c2^^c3^^c4;
guide g=gg[0];
for(int i=1;i<gg.length;++i){
  g=buildcycle(g,gg[i]);
}

draw(g,black);

This outputs nothing, while what I wanted is this (output from inkscape):

enter image description here

The reason I am checking out asymptote is that it's a programming language and should be much more powerful when the number of paths increase to a higher order.

6
  • I do not have the answer but relevant examples can be found here: asy.gmaths.net/forum/demandes-d-aide-f15/… It looks to me that you should have a look at the following asymptote commands: buildcycle and intersection
    – pluton
    Oct 28, 2013 at 21:51
  • Documentation on intersection: Return all (unless there are infinitely many) intersection times of paths p and q as a sorted array of real arrays of length 2, what is intersection times?
    – qed
    Oct 28, 2013 at 22:40
  • What exactly you think is wrong with your second picture? It still shows the outline of the four circles, three big and one small.
    – g.kov
    Oct 28, 2013 at 22:42
  • You mean the third picture? I have removed it. Yeah, it's actually ok because I still got four circles consecutively intersecting. I have changed the code, you can try it, it outputs nothing at all.
    – qed
    Oct 28, 2013 at 22:47
  • @g.kov I have edited the post and added a picture from inkscape
    – qed
    Oct 28, 2013 at 22:55

1 Answer 1

9

Consequent buildcycle commands can be used in this case:

unitsize(1mm);
import graph;
pair o1 = (0, 0);
pair o2 = (10, 0);
pair o3 = (10, 10);
pair o4 = (0, 10);
path c1 = Circle(o1, 10);
path c2 = Circle(o2, 10);
path c3 = Circle(o3, 10);
path c4 = Circle(o4, 10);

guide[] gg=c1^^c2^^c3^^c4;
guide g=gg[0];
for(int i=1;i<gg.length;++i){
  g=buildcycle(g,gg[i]);
}

filldraw(g,palegreen,deepblue);

enter image description here

Edit:

Well, the second case is a little more complicated than the original one. This modified code seems to work in this case:

unitsize(1mm);
import graph;
pair o1 = (0, 0);
pair o2 = (10, 0);
pair o3 = (10, 10);
pair o4 = (0, 10);

path c1 = Circle(o1, 8);
path c2 = Circle(o2, 8);
path c3 = Circle(o3, 1);
path c4 = Circle(o4, 1);

guide[] gg=c1^^c2^^c3^^c4;
int[] ind2del;
int j=0;
bool flag=true;
while(flag){
  flag=false;
  ind2del.delete();
  for(int i=j+1;i<gg.length;++i){
    if(intersect(gg[j],gg[i]).length>0){
      gg[j]=buildcycle(gg[j],gg[i]);
      ind2del.push(i);
      flag=true;
    }
  }
  for(int i=ind2del.length-1;i>=0;--i)gg.delete(ind2del[i]);
  ++j;
  if(j<gg.length){
    flag=true;
  }else{
    j=0;
  }
}

filldraw(gg,palegreen,deepblue);

enter image description here

7
  • According to the documentation: This returns the path surrounding a region bounded by a list of two or more consecutively intersecting paths, following the behaviour of the MetaPost buildcycle command. What if they are not consecutively intersecting?
    – qed
    Oct 28, 2013 at 22:24
  • @qed: see edited code
    – g.kov
    Oct 28, 2013 at 23:52
  • What exactly does the ^^ operator do?
    – qed
    Oct 29, 2013 at 17:39
  • 1
    @qed: From the docs: The ^^ binary operator, which requests that the pen be moved (without drawing or affecting endpoint curvatures) from the final point of the left-hand path to the initial point of the right-hand path, may be used to group several Asymptote paths into a path[] array (equivalent to a PostScript path)
    – g.kov
    Oct 29, 2013 at 18:59
  • Cool. I have look all over the site and didn't find this one. Could you please post the link to that page? Also, suppose I have 1000 paths, how can I group them into an array? i.e. p1^^p2^^...^^p1000 .
    – qed
    Oct 30, 2013 at 9:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .