漸近線:參數曲面不適用於樣條內插值

漸近線:參數曲面不適用於樣條內插值

我有一個參數化曲面,其定義為朗伯W函數我想用 Asymptote 顯示它。為此,蘭伯特 W 函數是使用牛頓方法實現的,並且原始(閉合)曲面必須分成兩個開放曲面以避免被零除的問題。這是 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.asygraph3.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

可以具體說明一下你的系統和Asymptote版本嗎?在我的電腦(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);

我希望它適用於您的系統。

奧格

相關內容