
나는 다음과 같이 정의된 파라메트릭 표면을 가지고 있습니다.램버트 W 함수점근선으로 표시하고 싶습니다. 이를 위해 Lambert W 함수는 Newton의 방법을 사용하여 구현되었으며 원래(닫힌) 표면은 0으로 나누는 문제를 피하기 위해 두 개의 열린 표면으로 분할되어야 했습니다. 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));
Spline
표면을 매끄럽게 보이도록 지시문 을 추가하면 Asymptote가 오류와 함께 충돌합니다 some path/graph_splinetype.asy: 89.10: function values are not periodic
. 나는 무엇이 잘못되었는지 이해하려고 노력했지만 graph_splinetype.asy
불행히도 graph3.asy
성공할 만큼 능숙하지 않습니다. 그래서 내 질문은 다음과 같습니다이 파라메트릭 표면으로 작업 할 기회가 있나요? Spline
아니면 매끄럽게 보이도록 만드는 다른 방법이 있을까요?
더욱 수수께끼로 만드는 것은 Spline
유사한 파라메트릭 표면에 대해 잘 작동한다는 것입니다(이 표면은 중요할 수 있는 z축 주위의 회전 대칭을 가지고 있지만). 즉, 다음과 같습니다.
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));
답변1
귀하의 시스템과 점근선 버전을 정확하게 알려주실 수 있습니까? 내 컴퓨터(Linux 64비트, Sid, Asymptote svn)에서는 문제가 없으며 코드가 매끄러운 표면을 생성합니다.
주기적 또는 not_a_knot 스플라인 사이의 선택이 표면 루틴에서 구현되므로 최종 파라메트릭 스플라인 루틴보다 덜 제한적인 것 같습니다(나는 오래 전에 이 매끄러운 표면 루틴의 일부를 작성했습니다). 다음 코드를 사용하면 "매듭이 아님" 선택을 강제할 수 있습니다.
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);
귀하의 시스템에서 작동하기를 바랍니다.
OG