![Schließen Sie die Ecken eines Gitters (aus Rohren) auf einer Oberfläche in Asymptote](https://rvso.com/image/281492/Schlie%C3%9Fen%20Sie%20die%20Ecken%20eines%20Gitters%20(aus%20Rohren)%20auf%20einer%20Oberfl%C3%A4che%20in%20Asymptote.png)
Betrachten Sie die folgende einfache Zeichnung einer Satteloberfläche mitasymptote
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);
und schauen Sie sich den Schnappschuss der Ausgabe an:
Sie können wahrscheinlich die unschöne Art und Weise erkennen, wie die Rohre, die die Gitterlinien bilden, an den Ecken der Oberfläche zusammenlaufen. Als Workaround könnte ich wahrscheinlich manuell Kugeln mit dem richtigen Radius an den Ecken hinzufügen. Fügen Sie beispielsweise die folgende Zeile hinzu:
draw(shift(-2,-2,f((-2,-2)))*scale(0.05,0.05,0.05)*unitsphere,blue);
und erhalten Sie die folgende Verbesserung:
Ich frage mich, ob es einen besseren Weg gibt. Wie kann ich die Verbindungen der Gitterlinien (genauer gesagt der Röhren) sauber schließen?
Antwort1
Als allgemeine Regel settings.render=0
rate ich davon ab, die meshpen
Option beim Zeichnen einer Oberfläche zu verwenden, es sei denn, Sie verwenden . Das Zeichnen des Netzes selbst hat eine Reihe von Vorteilen; die Lösung Ihres Problems ist einer der am wenigsten bedeutenden dieser Vorteile.
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);
}
hat Ergebnis
Beachten Sie, dass ich im Allgemeinen viel dünnere Gitternetzlinien bevorzuge, diese jedoch dicker gemacht habe, damit Sie tatsächlich erkennen können, ob Ihr Problem auftritt.
Wenn Sie andererseits möchten, dass die Gitternetzlinien dick und schattiert wie Röhren sind, ist Ihre Lösung ziemlich gut; im Grunde fügen Sie den Linien runde Kappen hinzu (was automatisch geschieht, wenn Sie die Gitternetzlinien ohne Röhrenschattierung zeichnen). Wenn Sie röhrenförmige Pfade von Hand zeichnen möchten, sollten Sie sich die tube
Methode ansehen, die im Handbuchabschnitt des three
Moduls beschrieben wird (S. 134 im Handbuch für Asymptote 2.23). Eine Alternative zu diesem Ansatz wäre, (eine Röhre für) den zyklischen Pfad am Rand des Diagramms zu zeichnen, anstatt die Gitternetzlinien am Rand des Gitters zu zeichnen oder dies zusätzlich zu tun.
Update: So zeichnen Sie das Netz von Hand (mit Röhren und einem separaten Umriss). Ich habe den Namen des Stifts geändert, um Verwirrung zu vermeiden. Beachten Sie, dass der Operator &
zum Verketten zweier Pfade dient, die einen Endpunkt gemeinsam haben.
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);
Das Ergebnis:
Antwort2
Hier ist die Problemumgehung, die ich im OP erwähnt habe.
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));
Ich habe einige zusätzliche Parameter und eine Funktion definiert, die dabei helfen können, die Kugel an den richtigen Stellen zu zeichnen.