垂直螺旋:从老式到 tikz

垂直螺旋:从老式到 tikz

我正在尝试在 tikz 中绘制以下取自一本旧书的图形:在此处输入图片描述

我尝试使用标准螺旋,如如何使用 TiKZ 绘制垂直螺旋?但结果并不令人满意。你能帮我创建一个忠实的 tikz 版本吗?非常感谢 :D

编辑:

\begin{tikzpicture}
    \begin{axis} [
        view={0}{75},
        axis lines=none,
        ymin=-2,
        ymax=5,
        xmin=-2,
        xmax=2]
        \addplot3 [domain=3.1*pi:5.5*pi, samples = 50, samples y=0]
        ({.5*sin(deg(-x))}, {.3*cos(deg(-x))+1}, {8*x*x*x});
    \end{axis}
\end{tikzpicture}

\begin{tikzpicture}
    \begin{axis}[
        view={60}{30},
        axis lines=center,axis on top,
        xlabel=$x$,ylabel=$y$,zlabel=$z$,
        ticks=none,
        no marks,axis line style={draw=none}
        ]
        \addplot3+[no markers, variable=\t,domain=0:4*pi,
        mesh,samples= 50, black]
        ({sin(\t r)}, {cos(\t r)}, \t);
    \end{axis}
\end{tikzpicture}

答案1

我发现另一种方法相当吸引人。要把线圈弄好有点棘手,但如果螺旋的确切位置不是太重要,这可能是一个可行的解决方案:

\documentclass[border=1mm, tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}

\begin{document}

\begin{tikzpicture}
% base
\draw (-4,-1) node[shift={(.5,.25)}] {$\alpha$} -- (-2,1) -- 
      (4,1) -- (2,-1) -- cycle;

% cylinder
\draw (0,0) ellipse (2cm and .5cm);
\draw (0,5) ellipse (2cm and .5cm);
\draw (-2,0) -- (-2,5) (2,0) -- (2,5);

% axes
\draw[dashed] (0,0) node[above left] {$0$} -- (0,5);
\draw[->] (0,5) -- (0,6) node[right] {$x^3 = a$};;
\draw[->] (0,0) -- (2.25,0) node[right] {$x^2$};
\draw[->] (0,0) -- (-.75,-.75) node[left] {$x^1$};

% spiral
\begin{scope}
\clip (-2,0) rectangle (2,5);
\draw[decoration={coil, aspect=.55, segment length=50mm, amplitude=20mm}, decorate] (0,7.5) -- (0,-2.5);
\end{scope}

\end{tikzpicture}

\end{document}

在此处输入图片描述


编辑

我又试了一次,这次没有使用装饰线圈,而是用曲线画出近似的螺旋线。实际上应该可以用这种方式画出精确的螺旋线,但我不知道背后的数学原理,所以我就这样画了。我最终使用了intersectioncalc库来计算不同线相交的坐标。

\documentclass[border=1mm, tikz]{standalone}
\usepackage{tikz}

\usetikzlibrary{intersections, calc}

\begin{document}

\begin{tikzpicture}[coord/.style={fill, circle, inner sep=1pt}]
% base
\draw (-4,-1) -- (-2,1) -- (4,1) -- (2,-1) -- cycle;

% cylinder
\draw[name path=cylinderbase] (-2,0) arc (180:360:2cm and .5cm);
\draw[dashed] (2,0) arc (0:180:2cm and .5cm);
\draw[name path=cylindertop] (0,5) ellipse (2cm and .5cm);
\draw (-2,0) -- (-2,5) (2,0) -- (2,5);

% axes
\draw[dashed] (0,0) node[coord, label=above left:$0$] (null) {} -- (0,5) node[coord] {};
\draw[->] (0,5) -- (0,6) node[right] {$x^3 = a$};
\draw[->] (0,0) -- (2.25,0) node[right] {$x^2$};
\draw[->] (0,0) -- (-.75,-.75) node[left] {$x^1$};

% spiral
\begin{scope}
\clip (-2,0) -- (-2,5) arc (180:360:2cm and .5cm) -- (2,0) arc (360:180:2cm and .5cm) -- cycle;
\draw[name path global=spiralstart] (2,5.175) to[controls=+(270:2) and +(270:.5)] (-2,3.175);
\draw[dashed] (-2,3.175) to[controls=+(90:.5) and +(90:2)] (2,1.175);
\draw[name path global=spiralend] (2,1.175) to[controls=+(270:2) and +(270:.5)] (-2,-.175);
\end{scope}

% nodes
\path[name path=temp1] (null) -- ++(4.5,-1);
\path[name intersections={of=temp1 and cylinderbase}];
\node[coord, label=below:$P_1$] (p1) at (intersection-1) {};

\path[name path=temp2] (p1) -- ++(0,5);
\path[name intersections={of=temp2 and spiralend}];
\node[coord, label=above left:$P$] (p) at (intersection-1) {};

\path[name intersections={of=temp2 and spiralstart}];
\node[coord, label=above:$\bar P$] (pbar) at (intersection-1) {};

\draw[dashed] (null) -- (p1);
\draw[dashed] (p1) -- (pbar);
\draw[dashed] (p) -- +($(null)-(p1)$) node[coord, label=above left:$P_2$] {};

% labels
\node at (-3.45,-.75) {$\alpha$};
\node at (-1,0) {$\gamma$};
\node at (.125,-.25) {$\varphi$};
\end{tikzpicture}

\end{document}

在此处输入图片描述

答案2

在等待 Tikz 的回答时,可以看看渐近线

编译于http://asymptote.ualberta.ca/

我不知道这\alpha是什么\gamma意思!

settings.render=8;
import solids;
import graph3;
usepackage("newtxmath");
size(200,400);
real r=3;
real h=2.5pi;

currentprojection=orthographic(8,2,4);

revolution R=cylinder(O,r,h);

// The circular helix
triple f(real t){
  real a=r*cos(t);
  real b=r*sin(t);
  real c=t;
  return (a,b,c);
}

real k=7;
path3 plane=(k,k,0)--(k,-k,0)--(-k,-k,0)--(-k,k,0)--cycle;
draw(plane);
label("$\alpha$",(k,-k,0),2dir(20));

draw(surface(R),lightgreen+opacity(0.5),render(compression=Low));
draw(surface(circle((0,0,h),r)),lightgreen+opacity(0.5),render(compression=Low));
draw(O--(0,0,h)^^O--(0,r,0)^^O--(r,0,0),dashed);
dot(scale(.7)*"$O$",(0,0,0),dir(165));
dot((0,0,h));

guide3 g=graph(f,0,h,150);
draw(Label("$\varphi$",Relative(.05)),g);
draw(Label("$\varphi$",Relative(.05)),g);

triple P=f(1),overP=f(1+2pi);
triple P1=(P.x,P.y,0),P2=(0,0,P.z);

draw(overP--P1);
draw(P2--P^^O--P1,dashed);

dot(scale(.7)*"$P$",P,2dir(120));
dot(scale(.7)*"$\overline{P}$",overP,dir(-20));
dot(scale(.7)*"$P_1$",P1,dir(-90));
dot(scale(.7)*"$P_2$",P2,dir(150));

xaxis3(Label("$x^1$",Relative(.5),2LeftSide),r,6,Arrow3);
yaxis3(Label("$x^2$",Relative(.5),4dir(20)),r,6,Arrow3);
zaxis3(Label("$x^3=$ a",Relative(.6),2RightSide),h,h+4,Arrow3);

在此处输入图片描述

答案3

这是另一个非 TikZ 的努力,这次是在元帖子。MP 中没有内置对 3D 绘图或透明度的支持,因此这种类型的绘图可能很难正确完成,并且需要一些耐心。

在此处输入图片描述

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);

    path plane, base, cap;
    plane = unitsquare shifted -(1/2, 1/2) xscaled 300 yscaled 120 slanted 1/2;
    base = fullcircle xscaled 100 yscaled 42;
    cap = base shifted 144 up;

    path xx[];
    xx1 = origin -- 3/4 point 1/2 of plane;
    xx2 = origin -- 3/4 point 3/2 of plane;
    xx3 = origin -- 200 up;

    path spiral;
    (a, b) = base intersectiontimes xx1;
    n = 64;
    r = (16 - a) / n;
    spiral = point 0 of cap 
        for i=1 upto n:
            .. (i/n)[point 8-i*r of cap, point 8-i*r of base]
        endfor;

    path pole;
    pole = point 7 of base -- point 7 of cap cutafter subpath (0, n/2) of spiral;
    pair P;
    P = pole intersectionpoint subpath (50, 64) of spiral;

    def hidden_axis = dashed withdots scaled 1/2 withcolor 1/4 enddef;
    def hidden_line = dashed evenly withpen pencircle scaled 1/4 withcolor 1/2 enddef;

    fill plane withcolor 7/8;
    draw plane;

    fill cap withcolor 7/8;
    fill subpath (4,8) of base -- subpath (8, 4) of cap -- cycle
        withcolor 3/4;

    draw xx1 cutafter base hidden_axis;
    draw xx2 cutafter base hidden_axis;
    draw center base -- center cap hidden_axis;
    
    draw subpath(0, 4) of base hidden_line;
    draw point 4 of cap -- subpath (4, 8) of base -- point 0 of cap;
    draw cap;

    draw subpath(24, 50) of spiral hidden_line;
    draw subpath(0, 24) of spiral;
    draw subpath(50, infinity) of spiral;

    draw pole;

    ahangle := 30;
    drawarrow xx1 cutbefore base; label.llft("$x_1$", point 1 of xx1);
    drawarrow xx2 cutbefore base; label.urt ("$x_2$", point 1 of xx2);
    drawarrow center cap -- point 1 of xx3; label.rt("$x_3=a$", point 1 of xx3 shifted 8 down);

    draw center cap withpen pencircle scaled dotlabeldiam yscaled .4;

    label.urt("$\alpha$", point 0 of plane shifted (16, 8));

    draw origin -- point 0 of pole hidden_axis;
    draw P -- P - point 0 of pole hidden_axis;
    dotlabeldiam := 3/4 dotlabeldiam;
    dotlabel.lft("$O$", origin);
    dotlabel.ulft("$P$", P);
    dotlabel.lrt("$P_1$", point 0 of pole);
    dotlabel.ulft("$P_2$", P - point 0 of pole);
    dotlabel.lrt("$\bar{P}$", point 1 of pole);

endfig;
\end{mplibcode}
\end{document}

这包含在内,luamplib因此您需要使用 进行编译lualatex。请点击顶部的链接了解有关 MP 的更多详细信息。

答案4

又一个非 tikz 版本。希望你能忍受。我使用 MetaPost/MetaFun(参见https://www.pragma-ade.com/general/manuals/metafun-p.pdf),但与 Thruston 的可爱回答略有不同。我认为是 Troy Henderson 教了我使用 MetaPost 中的 rgb 颜色来绘制 3D 的技巧。

该文件是用 编译的context

装饰过的圆柱体

\starttext
\startMPpage[offset=3bp]
path p[];
u:=1in;% overall unit
a:=4;% height of cylinder (radius=1)
tp:=40;% azimuthal angle for the points P
maxt:=450;% max parameter for the spiral

% (theta,phi) spherical coordinates for viewpoint direction
theta:=10;
phi:=25;

% scalar product
primarydef u cdotprod v =
    redpart u*redpart v + greenpart u*greenpart v + bluepart u*bluepart v
enddef;

% Projection from 3D to 2D
vardef P primary x =
    save ct,st,sp;
    ct:=cosd(theta);
    st:=sind(theta);
    sp:=sind(phi);
    (x cdotprod (-st,ct,0),x cdotprod (-ct*sp,-st*sp,cosd(phi)))
enddef;


path axis[],alpha,basecircle,topcircle, leftline,rightline,spiral;
pair ip[],pts[];

axis[1]=(origin--P(1.75,0,0)) scaled u;
axis[2]=(origin--P(0,1.75,0)) scaled u;
axis[3]=(origin--P(0,0,4.75)) scaled u;

alpha = (P(-2.5,-2.5,0)--P(2.5,-2.5,0)--P(2.5,2.5,0)--P(-2.5,2.5,0)--cycle) scaled u;
basecircle = (for t=0 step 10 until 360: P(cosd(t),sind(t),0) .. endfor cycle) 
scaled u; 
topcircle = (for t=0 step 10 until 360: P(cosd(t),sind(t),a) .. endfor cycle) 
scaled u;
leftline = (directionpoint down of basecircle) -- (directionpoint down of topcircle);
rightline = (directionpoint up of basecircle) -- (directionpoint up of topcircle);
spiral = (P(1,0,0) for t=0 step 10 until maxt: .. P(cosd(t),sind(t),a*t/maxt) endfor) scaled u;

% points where spiral meet vertical lines
ip[1]=spiral intersectionpoint rightline;
ip[2]=spiral intersectionpoint leftline;

% the P points
pts[0]=P(cosd(tp),sind(tp),0) scaled u;
pts[1]=P(cosd(tp),sind(tp),a*tp/maxt) scaled u;
pts[2]=P(cosd(tp),sind(tp),a*(tp+360)/maxt) scaled u;
pts[3]=P(0,0,a*tp/maxt) scaled u;

%drawing time!
draw alpha;
draw axis[1] cutafter (axis[1] intersectionpoint basecircle) dashed evenly;
drawarrow axis[1] cutbefore (axis[1] intersectionpoint basecircle);
draw axis[2] cutafter (axis[2] intersectionpoint basecircle) dashed evenly;
drawarrow axis[2] cutbefore (axis[2] intersectionpoint basecircle);
draw axis[3] cutafter (P(0,0,a) scaled u) dashed evenly;
drawarrow axis[3] cutbefore (P(0,0,a) scaled u);


draw basecircle cutafter point 0 of rightline;
draw basecircle cutbefore point 0 of leftline;
draw basecircle cutbefore point 0 of rightline cutafter point 0 of leftline dashed evenly;
draw topcircle;

draw leftline;
draw rightline;
draw spiral cutafter ip[1];
draw spiral cutbefore ip[1] cutafter ip[2] dashed evenly;
draw spiral cutbefore ip[2];

draw P(0,0,0)--pts[0]--pts[2] dashed evenly;
draw pts[1]--pts[3] dashed evenly;

drawpoints P(0,0,0);
drawpoints P(0,0,a) scaled u;

for i=0 upto 3:
  drawpoints pts[i];
endfor;

label.ulft("$x^1$",point 1 along axis[1]);
label.bot("$x^2$",point 1 along axis[2]);
label.rt("$x^3=a$",P(0,0,a) scaled u);
label.urt("$\alpha$",P(2,-2,0) scaled u);
label.lrt("$P_1$",pts[0]);
label.lrt("$P$",pts[1]);
label.lrt("$\bar{P}$",pts[2]);
label.lft("$P_2$",pts[3]);
label("$\gamma$",0.25[point 0 of leftline,P(0,0,0)]);
\stopMPpage
\stoptext

相关内容