Parametrised surface

Parametrised surface

\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

Author: g.kov (License)