Асимптота заполняет область между двумя контурами

Асимптота заполняет область между двумя контурами

Я использую Asymptoteдля создания графики. У меня есть две кривые, определенные как контуры C_1 и C_2. Я хочу заполнить область между двумя кривыми. Проблема в том, что contour возвращает структуру guide в Asymptote, а это не принимается командой to buildcycle. Может ли кто-нибудь сказать мне, как решить эту проблему? Спасибо. Это код, который я использую, и который создает две кривые, но не может заполнить область между ними.

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;

решение1

Работает при замене Cfи Cgна Cf[0][0]и Cg[0][0], что позволяет получить нужные (единичные) направляющие.

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

Обратите внимание, что я также немного изменил D1и D2: в ваших определениях D1, D2и ppсделалнетпересекаются в любом случае.

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

Для надлежащего объяснения того, как использовать contour, см. очень хорошо сделанный (увы, не полный)учебник по асимптотеЧарльз Стаатс, стр. 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));

введите описание изображения здесь

решение2

Просто для сравнения, вот версия Metapost. Нет поддержки неявных уравнений или чего-то столь же умного (или сложного), как contourвозможности Asymptote, поэтому я не мог избежать некоторой алгебры, чтобы получить "длинное выражение", чего OP с радостью избегал. И чтобы избежать переполнений, когда xблизко к нулю, я использую тот факт, что эти две кривые имеют симметрию относительно линии, проходящей через нее, (0,0)--(1,1)и что C1 проходит через нее, (9/16,9/16)в то время как C2 проходит через нее (3,3), — поэтому я использую цикл только для построения кривых справа от этих точек; затем я использую reflectedaboutмакрос MP для создания требуемых верхних половин.

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.

Если вы хотите нарисовать также и концы области, вы можете просто заменить my draw ff; draw gg;на draw A.

введите описание изображения здесь

Связанный контент