![Feche os cantos de uma grade (de tubos) em uma superfície em assíntota](https://rvso.com/image/281492/Feche%20os%20cantos%20de%20uma%20grade%20(de%20tubos)%20em%20uma%20superf%C3%ADcie%20em%20ass%C3%ADntota.png)
Considere o seguinte desenho simples de uma superfície de sela usandoasymptote
import graph3;
real f (pair p) {
real x = p.x;
real y = p.y;
return 0.5*(x^2-y^2);
}
surface saddle=surface(f,(-2,-2),(2,2),nx=5,Spline);
draw(saddle,gray,0.1+blue);
e dê uma olhada no instantâneo da saída:
Você provavelmente pode ver a maneira desagradável com que os tubos, que formam as linhas da grade, se unem nos cantos da superfície. Eu provavelmente poderia adicionar, manualmente, bolas com o raio certo nos cantos como solução alternativa. Por exemplo, adicione a seguinte linha:
draw(shift(-2,-2,f((-2,-2)))*scale(0.05,0.05,0.05)*unitsphere,blue);
e obtenha a seguinte melhoria:
Eu me pergunto se existe uma maneira melhor? Como devo fechar bem as conexões das linhas de grade (tubos, para ser mais preciso)?
Responder1
Como regra geral, a menos que use settings.render=0
, não recomendo usar a meshpen
opção ao desenhar uma superfície. Desenhar você mesmo a malha tem várias vantagens; resolver seu problema é uma das vantagens menos significativas.
settings.outformat="png";
settings.render=8;
unitsize(1cm);
import graph3;
currentprojection=perspective(5,5,5);
pen meshpen = 2pt + 0.7blue + 0.1green;
real f (pair p) {
real x = p.x;
real y = p.y;
return 0.5*(x^2-y^2);
}
surface saddle=surface(f,(-2,-2),(2,2),nx=5,Spline);
draw(saddle, surfacepen=gray);
for(int x = -2; x <= 2; ++x) {
draw(graph(new triple(real y) {return (x,y,f((x,y)) );}, -2, 2), meshpen);
}
for (int y = -2; y <= 2; ++y) {
draw(graph(new triple(real x) {return (x,y,f((x,y)) );}, -2, 2), meshpen);
}
tem resultado
Observe que geralmente prefiro linhas de grade muito mais finas, mas as tornei mais grossas para que você possa realmente ver se o seu problema aparece.
Por outro lado, se você realmente deseja que as linhas de grade sejam grossas e sombreadas como tubos, então sua solução é muito boa; basicamente, você está adicionando tampas redondas às linhas (o que é feito automaticamente quando você desenha as linhas de grade sem sombreamento de tubo). Se você quiser desenhar caminhos tubulares manualmente, você deve verificar o tube
método, que está descrito na seção do manual do three
módulo (p. 134 no manual do Assíntota 2.23). Uma alternativa para usar esta abordagem seria desenhar (um tubo para) o caminho cíclico na borda do gráfico, em vez de desenhar as linhas de grade na borda da grade.
Atualização: Veja como desenhar a malha à mão (com tubos e contorno separado). Mudei o nome da caneta para evitar confusão. Observe que o operador &
serve para concatenar dois caminhos que compartilham um ponto final.
settings.outformat="png";
settings.render=8;
unitsize(1cm);
import graph3;
surface operator cast(tube t) {
return t.s;
}
currentprojection=perspective(5,5,5);
pen gridpen = blue;
real f (pair p) {
real x = p.x;
real y = p.y;
return 0.5*(x^2-y^2);
}
int xmin = -2, xmax=2, ymin=-2, ymax=2;
surface saddle=surface(f,(xmin,ymin),(xmax,ymax),nx=5,Spline);
draw(saddle, surfacepen=gray);
int nx=5, ny=5;
path3 x_equals(real x) {
return graph(new triple(real y) {return (x,y,f((x,y)));}, ymin, ymax);
}
path3 y_equals(real y) {
return graph(new triple(real x) {return (x,y,f((x,y)));}, xmin, xmax);
}
real tubewidth = 0.1;
for(int i = 1; i < nx; ++i) {
real x = (xmax-xmin)*(i/nx) + xmin;
surface todraw = tube(x_equals(x), width=tubewidth);
draw(todraw, gridpen);
}
for (int i = 1; i < ny; ++i) {
real y = (ymax-ymin)*(i/ny) + ymin;
surface todraw = tube(y_equals(y), width=tubewidth);
draw(todraw, gridpen);
}
path3 outline = x_equals(xmin) & y_equals(ymax) & reverse(x_equals(xmax)) & reverse(y_equals(ymin)) & cycle;
draw(tube(outline,width=tubewidth), gridpen);
O resultado:
Responder2
Aqui está a solução alternativa que mencionei no OP.
import graph3;
real gridWidth=0.05;
pen gridPen=blue;
real f (pair p) {
real x = p.x;
real y = p.y;
return 0.5*(x^2-y^2);
}
void fillGap (pair p) {
real width=0.5*gridWidth;
draw(shift(p.x,p.y,f(p))*scale(width,width,width)*unitsphere,gridPen);
}
real minVal = -2;
real maxVal = -minVal;
surface saddle=surface(f,(minVal,minVal),(maxVal,maxVal),nx=5,Spline);
draw(saddle,gray+opacity(0.95),gridWidth+gridPen);
fillGap((minVal,minVal));
fillGap((minVal,maxVal));
fillGap((maxVal,minVal));
fillGap((maxVal,maxVal));
Defini alguns parâmetros extras e uma função que pode ajudar a desenhar a esfera nos lugares certos.