5

I use Asymptote to make the graphics. I have two curves defined as contours C_1 and C_2. I want to fill the area between the two curves. The problem is that contour returns a guide structure in Asymptote, and this is not accepted to to buildcycle command. Can anyone tell me how to solve this problem ? Thanks. This is the code I use and which produces the two curves, but fails to fill area between these.

import graph;
import patterns;
import contour; 

usepackage("mathrsfs");

size(8cm);

real eps=0.001;
real xmax=5.5,ymax=5.5;
pair af,ag;

real f(real x, real y) {return sqrt(1+x)-sqrt(x)+sqrt(1+y)-sqrt(y);}
real g(real x, real y) {return 1/sqrt(1+x)+1/sqrt(1+y);}

guide[][] Cf=contour(f,(eps,eps),(xmax,ymax),new real[] {1});
guide[][] Cg=contour(g,(eps,eps),(xmax,ymax),new real[] {1});

//these two lines are used to find intersection points
path D1=(0,ymax)--(xmax+eps,ymax);
path D2=(xmax,0)--(xmax,ymax+eps); 

draw(Cf);
draw(Cg);

//path pp=buildcycle(Cf,D1,Cg,D2);
// the preceding line produces and error if commented

xaxis(Label(scale(0.75)*"$x$"),xmax=6,Arrow);
yaxis(Label(rotate(90)*scale(0.75)*"$y$"),ymax=6,Arrow);

label("$\mathscr{C}_{1}$",(xmax,0.2));
label("$\mathscr{C}_{2}$",(xmax,1.9));
label("I"  ,(.2,.2));
label("II" ,(1.,1.));
label("III",(3.5,3.5));

end;
2
  • Is there some reason why you are using contour to produce the lines? It seems a rather complicated way to produce a single curve.
    – Thruston
    May 1 '15 at 9:26
  • Using f to write y = function (x) lead to a long expression. Around zero it requires large precision for fine tuned draw. Contour allows easier control over the drawing box.
    – Moez K
    May 1 '15 at 22:10
6

It works when replacing Cf and Cg by Cf[0][0] and Cg[0][0], which allows to obtain the desired (single) guides.

path pp=buildcycle(Cf[0][0],D1,Cg[0][0],D2);

Note that I've also slightly modified D1 and D2: in your definitions, D1, D2 and pp did not intersect anyway.

path D1=(0,ymax-eps)--(xmax+eps,ymax-eps);
path D2=(xmax-eps,0)--(xmax-eps,ymax+eps);

For proper explanations about how to use contour, see the very well-made (alas not complete) tutorial on Asymptote by Charles Staats, p. 32.

import graph;
import patterns;
import contour; 

usepackage("mathrsfs");

size(8cm);

real eps=0.001;
real xmax=5.5,ymax=5.5;
pair af,ag;

real f(real x, real y) {return sqrt(1+x)-sqrt(x)+sqrt(1+y)-sqrt(y);}
real g(real x, real y) {return 1/sqrt(1+x)+1/sqrt(1+y);}

guide[][] Cf=contour(f,(eps,eps),(xmax,ymax),new real[] {1});
guide[][] Cg=contour(g,(eps,eps),(xmax,ymax),new real[] {1});

//these two lines are used to find intersection points
path D1=(0,ymax-eps)--(xmax+eps,ymax-eps);
path D2=(xmax-eps,0)--(xmax-eps,ymax+eps);

path pp=buildcycle(Cf[0][0],D1,Cg[0][0],D2); 
fill(pp,.8white); draw(pp);

xaxis(Label(scale(0.75)*"$x$"),xmax=6,Arrow);
yaxis(Label(rotate(90)*scale(0.75)*"$y$"),ymax=6,Arrow);

label("$\mathscr{C}_{1}$",(xmax,0.2));
label("$\mathscr{C}_{2}$",(xmax,1.9));
label("I"  ,(.2,.2));
label("II" ,(1.,1.));
label("III",(3.5,3.5));

enter image description here

1
  • Great, it works fine ! thank a lot fpast, for the answer and for the suggestions.
    – Moez K
    Apr 30 '15 at 18:41
3

Just for comparison, here is a Metapost version. There's no support for implicit equations or anything so clever (or complex) as Asymptote's contour facility, so I could not avoid some algebra to get the "long expression" that the OP was happy to avoid. And to avoid overflows when x is near zero, I'm exploiting the facts that these two curves have a symmetry about the line through (0,0)--(1,1) and that C1 goes through (9/16,9/16) while C2 goes through (3,3) -- I therefore only use a loop to construct the curves to the right of these points; I then use MP's reflectedabout macro to create the required upper halves.

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);
u := 1cm;
path xx, yy, ff, gg;
xx = (1/2 left -- 6 right) scaled u;
yy = xx rotated 90;
drawarrow xx; drawarrow yy;

vardef f(expr x) = 
  save s; numeric s;
  s = (1+sqrt(x)-sqrt(1+x))**2;
  (1-2s+s**2)/(4s)
  enddef;

vardef g(expr x) = 
   (1+x)/(2+x-2*sqrt(1+x))-1
   enddef;

s = 0.05;
ff = ((9/16,9/16) for x = 9/16+s step s until 5.5: -- (x,f(x)) endfor) scaled u;
gg = ((3,3)       for x =    3+s step s until 5.5: -- (x,g(x)) endfor) scaled u;

ff := reverse ff reflectedabout(origin,(1,1)) & ff;
gg := reverse gg reflectedabout(origin,(1,1)) & gg;

path A;
A = ff -- reverse gg -- cycle;
fill A withcolor .9[blue,white];
draw ff;
draw gg;

string s; s = "";
for $=0,9/16u,3u:
  s := s & "I";
  label.urt(s,($,$));
  endfor

label.urt(btex ${\cal C}_1$ etex, point infinity of ff);
label.urt(btex ${\cal C}_2$ etex, point infinity of gg);

label.bot(btex $x$ etex, point 1 of xx);
label.lft(btex $y$ etex, point 1 of yy);

endfig;
end.

If you wanted to draw the ends of the area as well you could just replace my draw ff; draw gg; with draw A.

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.