我正在尝试在 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}
一些解释:
- 由于表面需要绘制两次,因此我定义了一个宏来完成该绘制。
- 为了允许在不同位置绘制形状,有两种方法:
- 对角落使用绝对坐标,并将绘图包含在
scope
执行一些移动以将其放置在适当位置的图形中。 - 使用相对坐标来表示角点。我采用了这种方法。您必须首先定义坐标
surface center
,其余角点都相对于此坐标。
- 对角落使用绝对坐标,并将绘图包含在
- 对于弯曲的边缘,我使用了操作符,它允许您指定曲线离开( )和进入( )其端点
to
的角度。out
in
更新
如果线条的隐藏部分在视觉上必须有所不同,最简单的方法是绘制用白色填充的表面,不透明度为 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
方向使得两者的垂直投影A
与B
两个表面上的相同曲线相交;线与表面边缘以及表面本身的交点都经过明确计算。
标签名称、位置和相对位置收集在数组中。
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