圆柱上的螺旋线

圆柱上的螺旋线

我想在圆柱体上绘制测地线。这些是直线、圆或螺旋线。我可以绘制前两种,但我不知道如何绘制螺旋线。

准确地说,我想知道如何在这个圆柱体上画一个螺旋线(经过两个点 A 和 B,但这两点的位置无关紧要),TikZ只使用(可能使用pgfplots,但不使用pstricks):

在此处输入图片描述

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\begin{document}
\begin{tikzpicture}
\node [cylinder,rotate=90,draw,aspect=2,minimum width=2cm,minimum height=3.5cm](C){};
\draw[fill] (-0.5,-0.5) circle [radius=0.045]node[below]{$A$};
\draw[fill] (0.5,0.75) circle [radius=0.045]node[below]{$B$};
\end{tikzpicture}
\end{document}

答案1

我喜欢 @Gromolatto 的想法。但是我认为绘制数百个线段有点过头了。这是他/她使用“\pgfplotfunction”的代码,它简化了代码并提高了精度,因为所有点都按原样绘制,而无需定义数百个子线段。

我保留了原始代码并注释了被替换的行。

\documentclass{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usepackage{pgfplots}
\usetikzlibrary{shapes}
\tdplotsetmaincoords{60}{110}


\begin{document}
\begin{tikzpicture}[tdplot_main_coords]
  \node [cylinder,rotate=90,draw,aspect=2,minimum width=2cm,minimum height=3.5cm](C){};

  %\foreach \t in {-90,-75,...,0}{%
  %  \draw ({cos(\t)},{sin(\t)},{-0.25+\t/360})--({cos(\t+7)},{sin(\t +7)},{-0.23+\t/360});
  %}

  \begin{scope}[color=black, dashed]
  \pgfplothandlerlineto
  \pgfplotfunction{\t}{-90,-89,...,15}
       {\pgfpointxyz {cos(\t)}{sin(\t)}{-0.25+\t/360}} 
       \pgfusepath{stroke}
  \end{scope}

%  \foreach \t in {15,16,...,98}{%
%    \draw[line width=1.5pt,color=red] ({cos(\t)},{sin(\t)},{-0.25+\t/360})--({cos(\t+1)},{sin(\t +1)},{-0.22+\t/360});
%  }

  \begin{scope}[color=red]
  \pgfplothandlerlineto
  \pgfplotfunction{\t}{15,16,...,110}
       {\pgfpointxyz {cos(\t)}{sin(\t)}{-0.25+\t/360}} 
       \pgfusepath{stroke}
  \end{scope}



  %\foreach \t in {110,125,...,280}{%
  %  \draw[line width=1pt,color=red] ({cos(\t)},{sin(\t)},{-0.25+\t/360})--({cos(\t+7)},{sin(\t +7)},{-0.22+\t/360});
  %}


  \begin{scope}[color=red, dashed]
  \pgfplothandlerlineto
  \pgfplotfunction{\t}{110,111,...,303}
       {\pgfpointxyz {cos(\t)}{sin(\t)}{-0.25+\t/360}} 
       \pgfusepath{stroke}
  \end{scope}

 % \foreach \t in {303,304,...,340}{%
 %   \draw[line width=1.6pt,color=red] ({cos(\t)},{sin(\t)},{-0.25+\t/360})--({cos(\t+1)},{sin(\t +1)},{-0.19+\t/360});
 % }


  \begin{scope}[color=red]
  \pgfplothandlerlineto
  \pgfplotfunction{\t}{303,304,...,340}
       {\pgfpointxyz {cos(\t)}{sin(\t)}{-0.25+\t/360}} 
       \pgfusepath{stroke}
  \end{scope}

  %\foreach \t in {355,370}{%
  %  \draw ({cos(\t)},{sin(\t)},{-0.25+\t/360})--({cos(\t+7)},{sin(\t +7)},{-0.23+\t/360});
  %}


  \begin{scope}[color=black, dashed]
  \pgfplothandlerlineto
  \pgfplotfunction{\t}{340,341,...,370}
       {\pgfpointxyz {cos(\t)}{sin(\t)}{-0.25+\t/360}} 
       \pgfusepath{stroke}
  \end{scope}

  \def\ang{340}
  \pgfmathsetmacro\bx{cos(\ang)}
  \pgfmathsetmacro\by{sin(\ang)}
  \pgfmathsetmacro\bz{-0.24+ \ang/360}

  \coordinate (B) at (\bx,\by,\bz);



  \draw[fill] (0.9922,0.25,-0.2) circle [x=1cm,y=1cm,radius=0.045]node[below]{$A$};
  \draw[fill] (B) circle [x=1cm,y=1cm,radius=0.045]node[below]{$B$};
\end{tikzpicture}
\end{document}

得到的数据如下:

圆柱上的螺旋

如果您进行“放大”,您将看到这个图形如何提高精度。

答案2

这里有一个tikz-3dplot解决方案。如果人们有兴趣在圆柱体的两个点之间绘制更通用的螺旋线(而不仅仅是测地线),我添加了一个宏,用于\n指定圆柱体周围的额外圈数。

编辑:感谢 Qrrbrbirlbel 的非常有用的评论。

在此处输入图片描述

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{15}
\tikzset{every circle/.append style={x=1cm, y=1cm}}
\begin{tikzpicture}[tdplot_main_coords]

% --- Independent parameters ---
\def\h{3}                          % cylinder height
\pgfmathtruncatemacro\tA{350}      % A angle
\def\zA{1}                         % A applicate
\pgfmathtruncatemacro\tB{150}      % B angle
\def\zB{2}                         % B applicate
\pgfmathtruncatemacro\n{0}         % number of additional turns
\pgfmathtruncatemacro\NbPt{51}     % number of dots for drawing the helix portion
\def\rhelixdots{0.02}              % radius of dots forming helix
\def\rAB{0.05}                     % radius of A and B dots

% --- Draw cylinder ---
% peripheral spokes
\foreach \t in {20,40,...,360} 
{ 
    \draw[gray,very thin,dashed] ({cos(\t)},{sin(\t)},0)
        --({cos(\t)},{sin(\t)},\h);
}

% lower circle
\draw[black,very thin] (1,0,0) 
    \foreach \t in {2,3,...,360}
    {
        --({cos(\t)},{sin(\t)},0)
    }
    --cycle;

% upper circle
\draw[black,very thin] (1,0,\h) 
    \foreach \t in {2,4,...,360}
    {
        --({cos(\t)},{sin(\t)},\h)
    }
    --cycle;


% --- Draw helix ---
\pgfmathsetmacro\tone{\tA}
\pgfmathsetmacro\tlast{\tB+\n*360}
\pgfmathsetmacro\ttwo{\tone+(\tlast-\tone)/(\NbPt-1)}
\pgfmathsetmacro\p{360*(\zB-\zA)/(\tB-\tA+360*\n)}
\foreach \t in {\tone,\ttwo,...,\tlast}{%
    \fill[red] ({cos(\t)},{sin(\t)},{\p*(\t-\tA)/360+\zA}) circle[radius=\rhelixdots];
}

% --- Draw A and B ---
\fill[blue] ({cos(\tA)},{sin(\tA)},\zA) circle [radius=\rAB]node[right]{$A$};
\fill[blue] ({cos(\tB)},{sin(\tB)},\zB) circle [radius=\rAB]node[left]{$B$};

\end{tikzpicture}
\end{document}

答案3

以下是我完全想要的解决方案(它基于 Jubobs 和 Qrrbrbirlbel 的回复,但形式更简化)。根据颜色和线的类型(虚线或非虚线),有 5 个不同的扇区。计算点坐标,使它们位于螺旋线上:

使用 <code>TikZ</code> 和 <code>3dplot</code> 在圆柱体上绘制螺旋线

\documentclass{standalone}
\usepackage{tikz}
\usepackage{3dplot}
\usetikzlibrary{shapes.geometric}
\tdplotsetmaincoords{60}{110}
\begin{document}
\begin{tikzpicture}[tdplot_main_coords]
\node [cylinder,rotate=90,draw,aspect=2,minimum width=2cm,minimum height=3.5cm](C){};
\foreach \t in {-90,-75,...,0}{%
\draw ({cos(\t)},{sin(\t)},{-0.25+\t/360})--({cos(\t+7)},{sin(\t +7)},{-0.23+\t/360});
}
\foreach \t in {15,16,...,98}{%
\draw[line width=1.5pt,color=red] ({cos(\t)},{sin(\t)},{-0.25+\t/360})--({cos(\t+1)},{sin(\t +1)},{-0.22+\t/360});
}
\foreach \t in {110,125,...,280}{%
\draw[line width=1pt,color=red] ({cos(\t)},{sin(\t)},{-0.25+\t/360})--({cos(\t+7)},{sin(\t +7)},{-0.22+\t/360});
}
\foreach \t in {303,304,...,340}{%
\draw[line width=1.6pt,color=red] ({cos(\t)},{sin(\t)},{-0.25+\t/360})--({cos(\t+1)},{sin(\t +1)},{-0.19+\t/360});
}
\foreach \t in {355,370}{%
\draw ({cos(\t)},{sin(\t)},{-0.25+\t/360})--({cos(\t+7)},{sin(\t +7)},{-0.23+\t/360});
}
\draw[fill] (0.9922,0.25,-0.2) circle [x=1cm,y=1cm,radius=0.045]node[below]{$A$};
\draw[fill] (0.2739,-0.5,0.32) circle [x=1cm,y=1cm,radius=0.045]node[below]{$B$};
\end{tikzpicture}
\end{document}

转折点附近的线条密度存在一些问题,但这些问题可以轻松手动调整。打印后,这是可以的:

答案4

这只是提到了弗里茨的精彩回答也可以在这里使用。对于圆柱体来说,数学运算甚至更简单。这允许人们让 pgfplots 决定某些拉伸是在前面还是在后面,并且 pgfplots 还允许我们通过拨打适当的 来根据需要对事物进行阴影处理point meta

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{pgfplots} 
\pgfplotsset{compat=1.16} 
\begin{document}
% very much like https://tex.stackexchange.com/a/199715/121799
\pgfplotsset{visible stretch/.style={restrict expr to
domain={sin(atan2(rawy,rawx)-\pgfkeysvalueof{/pgfplots/view/az})}{-1.1:0}},hidden
stretch/.style={restrict expr to
domain={sin(atan2(rawy,rawx)-\pgfkeysvalueof{/pgfplots/view/az})}{0:1.1}}}
\def\addFGBGplot[#1]#2;{
    \addplot3[#1,hidden stretch, opacity=0.25] #2;
    \addplot3[#1,visible stretch] #2;
}
\begin{tikzpicture}[declare function={R=1;H=3;}]
\begin{axis}[hide axis]
 \addplot3[surf,shader=interp,domain y=0:H,opacity=0.5,domain=
 \pgfkeysvalueof{/pgfplots/view/az}:\pgfkeysvalueof{/pgfplots/view/az}-180,
 colormap/blackwhite,point meta={sin(atan2(y,x)+40)}] 
 ({R*cos(x)},
 {R*sin(x)},{y});
 \addplot3[samples y=0,domain=0:360,smooth,fill=gray!30,draw=black] ({R*cos(x)},{R*sin(x)},{H});
 \addFGBGplot[samples y=0,color=blue,domain=0:1440,smooth,samples=251]
 ({R*cos(x)},{R*sin(x)},{0.75*x/360});
 \addplot3[samples y=0,domain=\pgfkeysvalueof{/pgfplots/view/az}:\pgfkeysvalueof{/pgfplots/view/az}-180,smooth,color=black] 
 ({R*cos(x)},{R*sin(x)},{0});
 \draw  ({R*cos(\pgfkeysvalueof{/pgfplots/view/az})},{R*sin(\pgfkeysvalueof{/pgfplots/view/az})
 },{0}) -- ({R*cos(\pgfkeysvalueof{/pgfplots/view/az})},{R*sin(\pgfkeysvalueof{/pgfplots/view/az})},{H})
  ({R*cos(\pgfkeysvalueof{/pgfplots/view/az}-180)},{R*sin(\pgfkeysvalueof{/pgfplots/view/az}-180)
 },{0}) -- ({R*cos(\pgfkeysvalueof{/pgfplots/view/az}-180)},{R*sin(\pgfkeysvalueof{/pgfplots/view/az}-180)},{H});
\end{axis}
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容