\documentclass[border=10pt]{standalone} \usepackage{asymptote} \begin{document} \begin{asy}[inline=true] import graph3; real w=9cm, h=1.618w; size(w,h); currentprojection=orthographic(camera=(-13,-8.6,59),up=Z,target=(0.5,0.5,3),zoom=1); import fontsize; defaultpen(fontsize(9pt)); texpreamble("\usepackage{siunitx}\usepackage{lmodern}"); pen linePen=darkblue+0.9bp; pen grayPen=gray(0.3)+0.8bp; pen dashPen=gray(0.3)+0.8bp+linetype(new real[] {5,5}); pen patchFillPen=paleblue; pen planeFillPen=deepgreen+opacity(0.3); triple[][] p={ // Bicubic Bezier patch control points {(1 ,0.3,0),(1 ,0.5,-1),(1 ,0.6,1),(1 ,1,0),}, {(0.6,0.25,0),(0.6,0.3,2) ,(0.6,0.6,2) ,(0.6,1,0.2),}, {(0.5,0.4,0),(0.3,0.3,2),(0.3,0.6,2) ,(0.3,1,2),}, {(0.3 ,0.4,0.2),(0 ,0.3,1.5) ,(0 ,0.6,2.3) ,(0 ,1,1),}, }; triple[][] planePatch(triple a,triple b,triple c){ // Builds a plane Bezier patch from 3 corner points triple[][] p=new triple[4][4]; p[0][0]=a; p[3][0]=b+b-a; p[1][0]=(2*p[0][0]+ p[3][0])/3; p[2][0]=( p[0][0]+2*p[3][0])/3; p[0][3]=c+c-a; p[0][1]=(2*p[0][0]+ p[0][3])/3; p[0][2]=( p[0][0]+2*p[0][3])/3; p[3][3]=p[0][0]+(p[3][0]-a)+(p[0][3]-a); p[1][3]=(2*p[0][3]+p[3][3])/3; p[2][3]=(p[0][3]+2*p[3][3])/3; p[3][1]=(2*p[3][0]+ p[3][3])/3; p[3][2]=( p[3][0]+2*p[3][3])/3; p[1][1]=(2*p[0][1]+ p[3][1])/3; p[2][1]=( p[0][1]+2*p[3][1])/3; p[1][2]=(2*p[0][2]+ p[3][2])/3; p[2][2]=( p[0][2]+2*p[3][2])/3; return p; } // support curves for ucurve and vcurve procedures guide3 gu0 =p[0][0]..controls p[1][0] and p[2][0]..p[3][0]; guide3 guc1=p[0][1]..controls p[1][1] and p[2][1]..p[3][1]; guide3 guc2=p[0][2]..controls p[1][2] and p[2][2]..p[3][2]; guide3 gu1 =p[0][3]..controls p[1][3] and p[2][3]..p[3][3]; guide3 gv0 =p[0][0]..controls p[0][1] and p[0][2]..p[0][3]; guide3 gvc1=p[1][0]..controls p[1][1] and p[1][2]..p[1][3]; guide3 gvc2=p[2][0]..controls p[2][1] and p[2][2]..p[2][3]; guide3 gv1 =p[3][0]..controls p[3][1] and p[3][2]..p[3][3]; guide3 patchBorder=gu0--gv1--reverse(gu1)--reverse(gv0)--cycle; guide3 ucurve(real u){ // builds a curve on a patch // that corresponds to a fixed value of the parameter u return point(gv0,u)..controls point(gvc1,u) and point(gvc2,u)..point(gv1,u); } guide3 vcurve(real v){ // builds a curve on a patch // that corresponds to a fixed value of the parameter v return point(gu0,v)..controls point(guc1,v) and point(guc2,v)..point(gu1,v); } triple Puv(real u, real v){ // return point on the surface of the patch at (u,v) return point(ucurve(u),v); } real u=0.618, v=0.582; // parametric coordinates of poi triple poi=Puv(u,v); // poi (point of interest) guide3 gammadot=poi--(poi-dir(ucurve(u),v)); guide3 Nxgamma=poi--(poi+0.5dir(vcurve(v),u)); guide3 gN=poi--(poi+0.8cross(dir(vcurve(v),u),dir(ucurve(u),v))); guide3 kappaN=subpath(gN,0,0.8); guide3 kappag=subpath(Nxgamma,0,0.4); guide3 gammaddot=poi--(poi+point(kappaN,1)-point(kappaN,0)+point(kappag,1)-point(kappag,0)); real r=0.2arclength(gN); guide3 psiarc=arcpoint(gN,r) ..arcpoint(poi--(poi+(point(gN,1)-poi)+(point(gammaddot,1)-poi)),1.2r) ..arcpoint(gammaddot,r); guide3 gammaarrow=(-0.04,0.4,1.7)..controls (0.02,0.4,1.7) and (0.06,0.5,1.7) ..(0.06,0.6,1.7); triple P,Q,R; // three points that define a tangent plane at poi real planeScaleU=0.6; real planeScaleV=0.8; P=poi-planeScaleU*(point(gammadot,1)-poi)-planeScaleV*(point(Nxgamma,1)-poi); Q=poi-planeScaleU*(point(gammadot,1)-poi); R=poi-planeScaleV*(point(Nxgamma,1)-poi); triple[][] plane=planePatch(P,Q,R); guide3 plane3d=plane[0][0]--plane[3][0]--plane[3][3]--plane[0][3]--cycle; guide plane2d=project(plane3d); guide p00p30=project(plane[0][0])--project(plane[3][0]); guide p30p33=project(plane[3][0])--project(plane[3][3]); guide p33p03=project(plane[3][3])--project(plane[0][3]); guide p03p00=project(plane[0][3])--project(plane[0][0]); fill(project(patchBorder),patchFillPen); fill(plane2d,planeFillPen); draw(project(gu0),linePen); draw(project(gv1),linePen); guide ucurve2d=project(ucurve(u)); real[] t=intersect(ucurve2d,p00p30); draw(subpath(ucurve2d,0,t[0]),dashPen); draw(subpath(ucurve2d,t[0],length(ucurve2d)),linePen); t=intersect(project(gu1),p00p30); draw(subpath(project(gu1),0,t[0]),dashPen); draw(subpath(project(gu1),t[0],length(project(gu1))),linePen); real[][] ta=intersections(project(gv0),p03p00); real[][] tb=intersections(project(gv0),p33p03); draw(subpath(project(gv0),0,ta[0][0]),linePen); draw(subpath(project(gv0),ta[0][0],tb[0][0]),dashPen); draw(subpath(project(gv0),tb[0][0],tb[1][0]),linePen); draw(subpath(project(gv0),tb[1][0],length(project(gv0))),dashPen); t=intersect(project(vcurve(v)),p03p00); draw(subpath(project(vcurve(v)),0,t[0]),linePen); draw(subpath(project(vcurve(v)),t[0],length(project(vcurve(v)))),dashPen); arrowbar arr=Arrow(HookHead,size=3); draw(project(gammadot),linePen,arr); draw(project(Nxgamma),linePen,arr); draw(project(gN),linePen,arr); draw(project(gammaddot),linePen,arr); draw(project(gammaarrow),linePen,arr); draw(project(point(kappaN,1)--point(gammaddot,1)),grayPen); draw(project(point(kappag,1)--point(gammaddot,1)),grayPen); draw(project(psiarc),grayPen); dot(project(poi),UnFill); void label2d(string s, triple loc, triple pos=(0,0,0)){ label("$"+s+"$",project(loc),project(pos)); } label2d("\sigma",Puv(0.9,0.9)); label2d("\gamma",(-0.07,0.4,1.8)); label2d("N",point(gN,1),-2Y); label2d("\dot{\gamma}",point(gammadot,1),2(point(gammadot,1)-poi)); label2d("N\times \dot{\gamma}",point(Nxgamma,1),2(point(Nxgamma,1)-poi)); label2d("\ddot{\gamma}",point(gammaddot,1),4(point(gammaddot,1)-poi)); label2d("\kappa_n",point(kappaN,0.618),2Y); label2d("\kappa_g",point(kappag,0.5),4Z+X); label2d("\psi",point(psiarc,1),8Z); \end{asy} \end{document}
Source: TeX.SE