3D 管内的水

3D 管内的水

内部有水分子的管子

我如何使用 TikZ 生成上述图像。管内的椭圆代表水,箭头表示水的偶极子方向。我目前能够得到的结果粘贴在下面。

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
%%%<
\usepackage{verbatim}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}%
%%%>


\begin{document}
\tdplotsetmaincoords{30}{10}
\tikzset{every circle/.append style={x=1cm, y=1cm}}
\begin{tikzpicture}[tdplot_main_coords, rotate=90]

% --- Independent parameters ---
\pgfmathtruncatemacro\tA{3600}      % 10 turns 360 degree x 10=3600
\def\zA{1}                         % A begin point, define the length of cylinder 
\pgfmathtruncatemacro\tB{30}      % tB end of turn 
\def\zB{5}                         % B end point
\pgfmathtruncatemacro\NbPt{130}     % number of circles for drawing the helix portion 13 times 10 turns =130
\def\rhelixdots{0.14}              % radius of circles  forming helix

 % --- Draw helix ---
\pgfmathsetmacro\tone{\tA}
\pgfmathsetmacro\tlast{\tB}
\pgfmathsetmacro\ttwo{\tone+(\tlast-\tone)/(\NbPt-1)}
\pgfmathsetmacro\p{360*(\zB-\zA)/(\tB-\tA)}

\foreach \t in {\tone,\ttwo,...,\tlast}{%
\pgfmathtruncatemacro{\shadingcolor}{40*sin(\t+180)+80}
\shade[ball color=blue!\shadingcolor] ({0.7*cos(\t)},{0.7*sin(\t)},{\p*(\t-\tA)/360+\zA}) circle[radius=\rhelixdots];
\shade[ball color=red!\shadingcolor] ({0.7*cos(\t)},{0.7*sin(\t)},{\p*(\t-\tA)/360+\zA+0.2}) circle[radius=\rhelixdots];
}

\end{tikzpicture}
\end{document}

在此处输入图片描述

寻求帮助,请同时查看此帖子改变视角会扭曲 3D 管图像

答案1

按照正确的顺序绘制所有内容比使用 3d 坐标(或图层)要容易得多。

关键的是最后十几行:

\documentclass{standalone}
\usepackage{xifthen}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}

\newdimen\r
\newdimen\R
\newcount\n

\tikzmath{
  \n = 19;                            % Molecules per winding
  \R = 100pt;                         % Tube radius
  \e = 0.9;                           % Eccentricity
  \t = 1.15;                          % Tightening factor
  \F = floor(\n/2);                   % Crucial to perform the clever cycles
  \G = \n-\F;                         %   (see the interesting part)
  \r = \R*sin(180/\n)*\t;             % 1/2 side of regular n-polygon, times t
}

% ##################################################### START OF BORING PART #

% These are the basic styles.
\tikzset{
  spirals/.cd,
    0/.style={draw, fill=white!70!black}, % {shade, ball color=white}
    1/.style={draw, fill=white!90!black}, % {shade, ball color=gray}
    8/.style={draw, fill=white!20!black}, % {shade, ball color=black}
    9/.style={opacity=0}
}

% Shaping the border. Boring.
\newcommand\ifisborderthen[4]{
  \ifthenelse{
        \(#2=0 \AND #3=0\)
    \OR \(#1=16 \AND #2<5\)
    \OR \(#1=3 \AND #2<1\)
    \OR \( #1=1  \AND \( #2<7 \OR \(#2<8 \AND #3=0\) \) \)
    \OR \( \(#1=17 \OR #1=2 \) \AND \(#2<5 \OR \(#2<6 \AND #3=0\)\) \)
    \OR \( \(#1=18 \OR #1=19\) \AND \(#2<6 \OR \(#2<7 \AND #3=0\)\) \)
  }{#4}{}}

% Shaping the hole. Boring.
\newcommand\ifisholethen[4]{
  \ifthenelse{
        \( #2<4 \AND \(2>#1 \OR #1>16\) \)
    \OR \(#1=1 \AND #2<5\)
    \OR \(#1=2 \AND #2<1 \AND #3=0\)
    \OR \(#1=19 \AND #2<6\)
    \OR \(#1=18 \AND #2<5\)
    \OR \(#1=17 \AND #2<5 \AND #3=0\)
  }{#4}{}}

% ################################################# START OF INTERESTING PART #

% We define a parametric key to apply the styles in a convenient way
\tikzset{
  molecule/.code args={#1in winding #2of spiral #3}{ % <-- HOCKETY POCKETY
    \tikzset{spirals/#3}                             % Draw everything.
    \ifisborderthen{#1}{#2}{#3}{\tikzset{spirals/8}} % Mark Borders.
    \ifisholethen{#1}{#2}{#3}{\tikzset{spirals/9}}}} % Punch holes.

\foreach \a [evaluate = \a using int(\a)]        % We cross (nearing viewer)
         in { \F, ..., 1                         %   first the lower side and
            , \F+1, \F+2, \F+..., \F+\G }        %   then the upper side
\foreach \z in {0, ..., 9}                       %     of ten windings
\foreach \h in {0, 1}                            %       of two spirals.
\path [molecule = \a in winding \z of spiral \h] % <--- HIGITUS FIGITUS
      ( {sqrt(1-\e^2)*\R*cos(-\a*360/\n)}        % This is the parametrization
      , {             \R*sin(-\a*360/\n)} )      %   of an ellipse.
        ++ ({\a*2*2*\r/\n}, 0)                   % We cut them open and
        ++ ({\z*2*2*\r}   , 0)                   % join them. Hence, spirals
        ++ ({\h*2*\r}     , 0)                   % that we intertwine.
        ++ (rand*360:rand*\r/20)                 % Some wobblyness.
      circle (\r);

\end{tikzpicture}
\end{document}

结果如下:

不错的版本

我没有画里面的东西,因为我看不懂。我没有使用仿 3D 球,因为我觉得它们太丑了。

深度多雾路段效果(或球)很容易添加,而且您已经知道如何添加。我专注于重现给定的图片。


更新!!它是 3D 的!

糟糕的版本

新的样式在里面的评论中spirals


更新2!!这是 3D 版本!

有趣的是,阴影仅占用第一个坐标。例如,比较上一个图(其中阴影仅使用沿椭圆的坐标计算)与下图(其中使用圆的完整坐标,但抖动校正除外):

\path [molecule = \a in winding \z of spiral \h] % <--- HIGITUS FIGITUS
      ( {sqrt(1-\e^2)*\R*cos(-\a*360/\n)         % Ellipses parametrized.
           + \a*2*2*\r/\n                        % We cut them open and
           + \z*2*2*\r                           % join them. Hence, spirals
           + \h*2*\r                    }        % that we intertwine.
      , {             \R*sin(-\a*360/\n)} )
        ++ (rand*360:rand*\r/20)                 % Some wobblyness.
      circle (\r);

最恐怖的版本

我一开始没有意识到,但这允许一些技巧。例如,考虑这个简单的排列:

\path [molecule = \a in winding \z of spiral \h]
           ({\a*2*2*\r/\n}, 0)
        ++ ({\z*2*2*\r}   , 0)
        ++ ({\h*2*\r}     , 0)
        ++ (rand*360:rand*\r/20)
        ++( {sqrt(1-\e^2)*\R*cos(-\a*360/\n)}
          , {             \R*sin(-\a*360/\n)} )
      circle (\r);

酷版

看起来就像管子里面的一个点光源。太棒了!

相关内容