更新

更新

我正在尝试在 tikz 中绘制下面的图片,但是我做不到。 在此处输入图片描述

关于如何在 TikZ 或其他地方完成此操作有什么建议吗?

答案1

我同意 Sean Allred 的评论。这个图形并不复杂,除了曲面。因此,为了帮助您入门,以下是该部分的一个可能解决方案:

\def\surface{
\draw (surface center)
  ++(-2,-1) to[out=20,in=-170] ++(4,0.2) --
  ++(1,0.7) to[out=190,in=15] ++(-4,-0.3) --
  cycle;
}

\begin{tikzpicture}
\coordinate (surface center) at (0,0.7);
\surface
\coordinate (surface center) at (0,-0.7);
\surface
\end{tikzpicture}

结果

一些解释:

  • 由于表面需要绘制两次,因此我定义了一个宏来完成该绘制。
  • 为了允许在不同位置绘制形状,有两种方法:
    1. 对角落使用绝对坐标,并将绘图包含在scope执行一些移动以将其放置在适当位置的图形中。
    2. 使用相对坐标来表示角点。我采用了这种方法。您必须首先定义坐标surface center,其余角点都相对于此坐标。
  • 对于弯曲的边缘,我使用了操作符,它允许您指定曲线离开( )和进入( )其端点to的角度。outin

更新

如果线条的隐藏部分在视觉上必须有所不同,最简单的方法是绘制用白色填充的表面,不透明度为 80%,如下面的概念证明所示:

\def\surface{
\draw[fill=white, fill opacity=.70] (surface center)
  ++(-2,-1) to[out=20,in=-170] ++(4,0.2) --
  ++(1,0.7) to[out=190,in=15] ++(-4,-0.3) --
  cycle;
}

\begin{tikzpicture}
\coordinate (surface center) at (0,-0.7);
\surface
\draw[->] (0.5, -1.2) -- +(0, 1.5);
\coordinate (surface center) at (0,0.7);
\surface
\end{tikzpicture}

结果

答案2

使用 PSTricks。

在此处输入图片描述

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-node}
\newcommand\surface[4][]{%
    \pnode(2,0.75){#2}
    \pnode(5,1.25){#3}
    \pscustom[linejoin=1,#1]
    {
        \psline(1,2)(0,0)
        \pscurve(2,0.25)(4,-0.25)(6,0)
        \psline(7,2)
        \pscurve(5,1.75)(3,2.25)(1,2)
        \closepath
    }
    \rput(1,0.5){$\displaystyle#4$}%
}
\begin{document}
\begin{pspicture}(7,5.5)
    \rput(0,3){\surface{A}{B}{}}
    \rput(0,0.5){\surface{C}{D}{\Sigma_f}}
    \pcline[linestyle=dashed](D)(B)
    \pcline{->}(C)(A)\naput[npos=0.675,labelsep=0pt]{$N_n^0$}
    \pcline{->}(C)(B)\nbput[npos=0.4,labelsep=0pt]{$f^0$}
    \pcline{->}(C)(D)\nbput[labelsep=0pt]{$N^0$}
    \rput(0,3){\surface[fillstyle=solid,fillcolor=yellow,opacity=0.75]{A}{B}{\Sigma_{f+\Delta f}}}
\end{pspicture}
\end{document}

答案3

在此处输入图片描述

这不是伪造的草图,而是用 Asymptote 制作的 3D 表面的真实投影。关键点如下:

  • 每个表面表示为具有 16 个控制点的双三次贝塞尔曲面片;

  • 为了使拦截更容易,水平线的AB方向使得两者的垂直投影AB两个表面上的相同曲线相交;

  • 线与表面边缘以及表面本身的交点都经过明确计算。

  • 标签名称、位置和相对位置收集在数组中。

bpatch.asy

import graph3;
size(300);
size3(100,40,50,IgnoreAspect);

currentprojection=orthographic(camera=(5,-4,12), up=(0,0,1), target=(6,6,4.5), zoom=1);

triple bCurve(real t,triple a,triple b,triple c,triple d){
  return a*(1-t)^3+3b*(1-t)^2*t+3c*(1-t)*t^2+d*t^3;
}

guide3 uCurve(real u,triple[][] p){
  triple a,b,c,d;
  a=bCurve(u,p[0][0],p[0][1],p[0][2],p[0][3]);
  b=bCurve(u,p[1][0],p[1][1],p[1][2],p[1][3]);
  c=bCurve(u,p[2][0],p[2][1],p[2][2],p[2][3]);
  d=bCurve(u,p[3][0],p[3][1],p[3][2],p[3][3]);
  return a..controls b and c ..d;
};

guide3 vCurve(real v,triple[][] p){
  triple a,b,c,d;
  a=bCurve(v,p[0][0],p[1][0],p[2][0],p[3][0]);
  b=bCurve(v,p[0][1],p[1][1],p[2][1],p[3][1]);
  c=bCurve(v,p[0][2],p[1][2],p[2][2],p[3][2]);
  d=bCurve(v,p[0][3],p[1][3],p[2][3],p[3][3]);
  return a..controls b and c ..d;
};

triple bPatch(real u, real v, triple[][] p){
  triple a,b,c,d;
  a=bCurve(u,p[0][0],p[0][1],p[0][2],p[0][3]);
  b=bCurve(u,p[1][0],p[1][1],p[1][2],p[1][3]);
  c=bCurve(u,p[2][0],p[2][1],p[2][2],p[2][3]);
  d=bCurve(u,p[3][0],p[3][1],p[3][2],p[3][3]);
  return bCurve(v,a,b,c,d);
}

triple[][] p={ // control poits of  bicubic Bezier patch
  {(0,12,0),(4,12,10),(8,12,6),(12,12,6)},
  {(0, 8,0),(4, 8,10),(8, 8,6),(12, 8,1.5)},
  {(0, 4,0),(4, 4,10),(8, 4,6),(12, 4,5)},
  {(0, 0,0),(4, 0,10),(8, 0,6),(12, 0,5)},
};


real w=1.2pt;

transform3 t=shift(0,0,14); // shift up

guide[] g={
  project(uCurve(0,p)),
  project(uCurve(1,p)),
  project(vCurve(0,p)),
  project(vCurve(1,p)),

  project(t*uCurve(0,p)),
  project(t*uCurve(1,p)),
  project(t*vCurve(0,p)),
  project(t*vCurve(1,p)),
};

// edge curves of the bottom patch
draw(g[0],red+w);
draw(g[1],green+w);
draw(g[2],blue+w);
draw(g[3],orange+w);

// edge curves of the top patch
draw(g[4],red+w);
draw(g[5],green+w);
draw(g[6],blue+w);
draw(g[7],orange+w);

real u=0.6, v=0.25;
draw(project(vCurve(v,p)),green+w);
draw(project(t*vCurve(v,p)),green+w);


triple A,B,C,D,Q,R;
A=bPatch(u,v,p);
B=t*A; 
Q=bPatch(u+0.3,v,p);
C=(Q.x,Q.y,A.z);
D=t*C;

pair Ap,Bp,Cp,Dp,Rp;
Ap=project(A);
Bp=project(B);
Cp=project(C);
Dp=project(D);

draw((Ap--Cp),darkblue+1.2pt,Arrow(size=5pt));

pair xAB=intersectionpoint(project(t*vCurve(1,p)), (Ap--Bp));
pair xCD=intersectionpoint(project(t*vCurve(1,p)), (Cp--Dp));
pair xCD2=intersectionpoint(project(t*vCurve(v,p)), (Cp--Dp));
pair xAD=intersectionpoint(project(t*vCurve(1,p)), (Ap--Dp));
pair xAD2=intersectionpoint(project(t*vCurve(v,p)), (Ap--Dp));

pen dashed=linetype(new real[] {4,3}); // set up dashed pattern

pen linePen=darkblue+1.2pt;

draw((Ap--xAB),linePen);
draw((xAB--Bp),darkblue+dashed+1.2pt,Arrow(size=5pt));

draw((Cp--xCD),linePen);
draw((xCD--xCD2),darkblue+dashed+1.2pt);
draw((xCD2--Dp),linePen);

draw((Ap--xAD),linePen);
draw((xAD--xAD2),darkblue+dashed+1.2pt);
draw((xAD2--Dp),linePen,Arrow(size=5pt));

draw((Bp--Dp),linePen,Arrow(size=5pt));

string[] L={
  "\Sigma_t",
  "\Sigma_{t+\Delta  t}",
  "Nn^\alpha",
  "N^\alpha",
  "t^\alpha",
};

pair O=N-N;
pair[] relPos={O,O,W,S,SE};

pair[] Pos={
  project(bPatch(0.7u,1.4v,p)),
  project(t*bPatch(0.7u,1.4v,p)),
  point(Ap--Bp,0.4),  
  point(Ap--Cp,0.5),  
  point(Ap--Dp,0.5),  
};

for(int i=0;i<L.length;++i){
  label("$"+L[i]+"$",Pos[i],relPos[i]);
}

dotfactor=5;
dot(Ap,linePen,UnFill);

pen fillPen=lightblue+opacity(0.2);
fill(g[0]--g[1]--g[2]--g[3]--cycle,fillPen);
fill(g[4]--g[5]--g[6]--g[7]--cycle,fillPen);

要处理,请运行asy -f pdf bpatch.asy

相关内容