
Ich habe eine parametrische Oberfläche, die definiert ist in Bezug auf dieLambert W-Funktionund die ich mit Asymptote darstellen möchte. Dafür wurde die Lambert-W-Funktion mit dem Newton-Verfahren implementiert und die ursprüngliche (geschlossene) Oberfläche musste in zwei offene Oberflächen aufgeteilt werden, um Probleme mit der Division durch Null zu vermeiden. Hier ist das MWE:
settings.render=8;
settings.prc=false;
settings.outformat="pdf";
import graph3;
size(200);
currentprojection=orthographic(40,10,10);
// contour value
real c = 0.006;
// parameter ranges
real umin = asin(1.5*exp(1)*sqrt(c*(sqrt(2*pi))));
real umax = pi-asin(1.5*exp(1)*sqrt(c*(sqrt(2*pi))));
real vmin = 0;
real vmax = 1;
// Lambert W function
real w1(real w, real z, int i){return z<-1/exp(1) - 0.00001 ? 1/0 : z<-1/exp(1) ? -1 : i>0 && abs((w*exp(w)-z)/(exp(w)+w*exp(w))) > 1e-7 ? w1(w-(w*exp(w)-z)/(exp(w)+w*exp(w)),z,i-1) : w-(w*exp(w)-z)/(exp(w)+w*exp(w));};
// auxiliary functions
real y5(real h, real p){return (1/4.)*sqrt(15./pi) * sin(2*p) * sin(h)**2;};
real r1(real y){return -6*w1(-2,-sqrt(c*9*sqrt(30)/abs(y))/4,200);};
real r2(real y){return -6*w1(1,-sqrt(c*9*sqrt(30)/abs(y))/4,200);};
// x, y, and z coordinates of the surfaces
real x11(real u, real v){return r1(y5(u,v*pi/2+(0.5-v)*asin(exp(1)**2*9.*c*sqrt(2.*pi)/(4.*sin(u)**2))))*sin(u)*cos(v*pi/2+(0.5-v)*asin(exp(1)**2*9.*c*sqrt(2.*pi)/(4.*sin(u)**2)));};
real y11(real u, real v){return r1(y5(u,v*pi/2+(0.5-v)*asin(exp(1)**2*9.*c*sqrt(2.*pi)/(4.*sin(u)**2))))*sin(u)*sin(v*pi/2+(0.5-v)*asin(exp(1)**2*9.*c*sqrt(2.*pi)/(4.*sin(u)**2)));};
real z11(real u, real v){return r1(y5(u,v*pi/2+(0.5-v)*asin(exp(1)**2*9.*c*sqrt(2.*pi)/(4.*sin(u)**2)) ))*cos(u);};
real x12(real u, real v){return r2(y5(u,v*pi/2+(0.5-v)*asin(exp(1)**2*9.*c*sqrt(2.*pi)/(4.*sin(u)**2))))*sin(u)*cos(v*pi/2+(0.5-v)*asin(exp(1)**2*9.*c*sqrt(2.*pi)/(4.*sin(u)**2)));};
real y12(real u, real v){return r2(y5(u,v*pi/2+(0.5-v)*asin(exp(1)**2*9.*c*sqrt(2.*pi)/(4.*sin(u)**2))))*sin(u)*sin(v*pi/2+(0.5-v)*asin(exp(1)**2*9.*c*sqrt(2.*pi)/(4.*sin(u)**2)));};
real z12(real u, real v){return r2(y5(u,v*pi/2+(0.5-v)*asin(exp(1)**2*9.*c*sqrt(2.*pi)/(4.*sin(u)**2)) ))*cos(u);};
triple f11(pair p){return (x11(p.x,p.y),y11(p.x,p.y),z11(p.x,p.y));};
triple f12(pair p){return (x12(p.x,p.y),y12(p.x,p.y),z12(p.x,p.y));};
surface s11 = surface(f=f11,a=(umin, vmin),b=(umax,vmax)); // this works
surface s12 = surface(f=f12,a=(umin, vmin),b=(umax,vmax)); // this works
// surface s11 = surface(f=f11,a=(umin, vmin),b=(umax,vmax),Spline); // this doesn't work
// surface s12 = surface(f=f12,a=(umin, vmin),b=(umax,vmax),Spline); // this doesn't work
draw(s11, red+opacity(0.5));
draw(s12, red+opacity(0.5));
Wenn ich die Spline
Anweisung hinzufüge, die Oberfläche glatt aussehen zu lassen, stürzt Asymptote mit dem Fehler ab . Ich habe versucht herauszufinden, was in und some path/graph_splinetype.asy: 89.10: function values are not periodic
schiefgelaufen ist , aber leider bin ich nicht kompetent genug, um erfolgreich zu sein. Meine Frage ist also:graph_splinetype.asy
graph3.asy
Gibt es eine Möglichkeit, Spline
mit dieser parametrischen Oberfläche zu arbeiten, oder vielleicht eine andere Möglichkeit, ihr ein glattes Aussehen zu verleihen?
Was es noch rätselhafter macht, ist, dass Spline
es für eine ähnliche parametrische Oberfläche genauso gut funktioniert (obwohl diese eine Rotationssymmetrie um die z-Achse aufweist, was wichtig sein könnte), nämlich diese:
settings.render=8;
settings.prc=false;
settings.outformat="pdf";
import graph3;
size(200);
currentprojection=orthographic(40,10,10);
// contour value
real c = 0.006;
// parameter ranges
real umin = 0;
real umax = acos(2*exp(1)*c*sqrt(2*pi))-0.0000001;
real vmin = 0;
real vmax = 2*pi;
// Lambert W function
real w1(real w, real z, int i){return z<-1/exp(1) - 0.00001 ? 1/0 : z<-1/exp(1) ? -1 : i>0 && abs((w*exp(w)-z)/(exp(w)+w*exp(w))) > 1e-7 ? w1(w-(w*exp(w)-z)/(exp(w)+w*exp(w)),z,i-1) : w-(w*exp(w)-z)/(exp(w)+w*exp(w));};
// auxiliary functions
real y1(real h){return sqrt(3./pi)/2.*cos(h);};
real r1(real y){return -2*w1(-2,-c*sqrt(6)/abs(y),200);};
real r2(real y){return -2*w1(1,-c*sqrt(6)/abs(y),200);};
// x, y, and z coordinates of the surfaces
real x11(real u, real v){return r1(y1(u))*sin(u)*cos(v);};
real y11(real u, real v){return r1(y1(u))*sin(u)*sin(v);};
real z11(real u, real v){return r1(y1(u))*cos(u);};
real x12(real u, real v){return r2(y1(u))*sin(u)*cos(v);};
real y12(real u, real v){return r2(y1(u))*sin(u)*sin(v);};
real z12(real u, real v){return r2(y1(u))*cos(u);};
triple f11(pair p){return (x11(p.x,p.y),y11(p.x,p.y),z11(p.x,p.y));};
triple f12(pair p){return (x12(p.x,p.y),y12(p.x,p.y),z12(p.x,p.y));};
surface s11 = surface(f11,(umin,vmin),(umax,vmax),50,Spline);
surface s12 = surface(f12,(umin,vmin),(umax,vmax),50,Spline);
draw(s11, red+opacity(0.5));
draw(s12, red+opacity(0.5));
Antwort1
Könnten Sie Ihr System und Ihre Asymptote-Version präzisieren? Auf meinem Computer (Linux 64 Bit, Sid, Asymptote svn) habe ich kein Problem und Ihr Code erzeugt eine glatte Oberfläche.
Da die Wahl zwischen periodischem oder nicht-knotenförmigem Spline in der Oberflächenroutine implementiert ist, scheint sie weniger restriktiv zu sein als die endgültige parametrische Splineroutine (ich habe vor langer Zeit einen Teil dieser glatten Oberflächenroutine geschrieben). Mit dem folgenden Code ist es möglich, eine „kein Knoten“-Wahl zu erzwingen
splinetype[] Notaknot={notaknot,notaknot,notaknot};
surface s11 = surface(f=f11,a=(umin,vmin),b=(umax,vmax),8,16,Notaknot,Notaknot);
surface s12 = surface(f=f12,a=(umin,vmin),b=(umax,vmax),8,16,Notaknot,Notaknot);
Ich hoffe, es funktioniert auf Ihrem System.
OG