如何在 TikZ 中创建美观的原子核?

如何在 TikZ 中创建美观的原子核?

在回应中在 TeX 中绘制带有电子壳层的玻尔原子模型?,原子的画得很漂亮。然而,原子核看起来不太吸引人,也不太逼真。

我想知道:有人能想到一种算法来(半)自动地(例如以随机方式)创建看起来更逼真的大核,例如附图中所示的?

在此处输入图片描述

关键似乎是球之间的间距足够大,并且球形外观需要更多居中的球位于顶部。我的代码无法满足这两个要求:

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\path (-2,-2) rectangle (2,2);
\pgfmathdeclarerandomlist{color}{{red}{white}}
\foreach \a in {1,...,200} {
    \pgfmathsetmacro{\r}{rnd}
    \pgfmathsetmacro{\a}{random(0,360)}
    \pgfmathrandomitem{\c}{color}
    \shade[ball color=\c] (\a:-\r) circle (5pt);
    }
\end{tikzpicture}
\end{document}

结果是: 在此处输入图片描述

编辑:

如果有人感兴趣的话,以下是让我非常高兴的事情:根据答案,我定义了三种不同大小的建议核的稍微修改版本,并可以选择喂养随机种子以获得不同的物种。

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
\tikzset{
    pics/proton/.style={code={\shade[ball color=red] circle (3pt);}},
    pics/neutron/.style={code={\shade[ball color=white] circle (3pt);}},
    pics/nucleussmall/.style={code={%
        \pgfmathdeclarerandomlist{nucleon}{{proton}{proton}{neutron}{neutron}{neutron}}
        \pgfmathsetseed{#1+1}
        \foreach \A/\R in {8/0.2, 5/0.13, 1/0}{
        \pgfmathsetmacro{\S}{360/\A}
            \foreach \B in {0,\S,...,360}{
                \pgfmathrandomitem{\C}{nucleon}
                \pic at ($(\B+2*\A+5*rnd:\R)$) {\C}; } }} },
    pics/nucleusbig/.style={code={%
        \pgfmathdeclarerandomlist{nucleon}{{proton}{proton}{neutron}{neutron}{neutron}}
        \pgfmathsetseed{#1+1}
        \foreach \A/\R in {24/0.4, 24/0.3, 24/0.2, 13/0.35, 11/0.27, 6/0.15, 1/0}{
        \pgfmathsetmacro{\S}{360/\A}
            \foreach \B in {0,\S,...,360}{
                \pgfmathrandomitem{\C}{nucleon}
                \pic at ($(\B+2*\A+5*rnd:\R)$) {\C}; } }} },
    pics/nucleusbiggest/.style={code={%
        \pgfmathdeclarerandomlist{nucleon}{{proton}{proton}{neutron}{neutron}{neutron}}
        \pgfmathsetseed{#1+1}
        \foreach \A/\R in {24/0.5, 24/0.4, 24/0.3, 24/0.2, 13/0.47, 15/0.44, 13/0.37, 11/0.27, 6/0.15, 1/0}{
        \pgfmathsetmacro{\S}{360/\A}
            \foreach \B in {0,\S,...,360}{
                \pgfmathrandomitem{\C}{nucleon}
                \pic at ($(\B+2*\A+5*rnd:\R)$) {\C}; } }} },
    }
\pic at (0,0) {nucleussmall};
\pic at (2,0) {nucleusbig=1};
\pic at (4,0) {nucleusbiggest=1};    
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案1

这里有一项建议,可以让原子核看起来更像一个紧凑的球。它的工作原理是从外向内构建圆形环。通过调整每个环中的质子/中子数量及其与中心的距离,可以创建球形效果。

在此处输入图片描述

\documentclass{standalone}
\usepackage{tikz}
\usepackage[version=4]{mhchem}
\begin{document}
\begin{tikzpicture}
\path (-2,-2) rectangle (2,2);
\pgfmathdeclarerandomlist{color}{{red}{white}}
\pgfmathsetseed{1}
\foreach \A/\R in {25/1,12/0.9,15/0.8,20/0.7,12/0.5,7/0.3,1/0}{
      \pgfmathsetmacro{\S}{360/\A}
           \foreach \B in {0,\S,...,360}{
               \pgfmathrandomitem{\C}{color}
               \shade[ball color=\C] (\B+\A:\R) circle (5pt);
           }
}
\node at (-1,1.3) {\ce{^{226}_{88}Ra}};
\end{tikzpicture}
\end{document}

答案2

根据您的代码,我首先按照圆形图案绘制质子/中子三次,半径分别为 1、0.5 和 0.2。我还在中间绘制随机质子/中子。

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\path (-2,-2) rectangle (2,2);
\pgfmathdeclarerandomlist{color}{{red}{white}}

\foreach \a in {0,10,...,360}{
    \pgfmathrandomitem{\c}{color}
    \shade[ball color=\c] (\a:1) circle (5pt);
}

\foreach \a in {0,20,...,360}{
    \pgfmathrandomitem{\c}{color}
    \shade[ball color=\c] (\a:0.5) circle (5pt);
}

\foreach \a in {1,...,350} {
    \pgfmathsetmacro{\r}{rnd}
    \pgfmathsetmacro{\a}{random(0,360)}
    \pgfmathrandomitem{\c}{color}
    \shade[ball color=\c] (\a:\r) circle (5pt);
    }

\foreach \a in {0,60,...,360} {
    \pgfmathrandomitem{\c}{color}
    \shade[ball color=\c] (\a:0.2) circle (5pt);
}
\end{tikzpicture}
\end{document}

结果是:

截屏

答案3

这是另一个版本,其中球体被放在 A_3 的根晶格上,并允许稍微摆动。更多解释可参见这里

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3d}
\tikzset{declare function={posx(\x,\y,\z)=\x-\y/2;
posy(\x,\y,\z)=\y/sqrt(2);
posz(\x,\y,\z)=-\y/2+\z;
}}
\newsavebox\Proton
\newsavebox\Neutron
\sbox\Proton{\tikz{\shade[ball color=red] circle({0.85/sqrt(2)});}}
\sbox\Neutron{\tikz{\shade[ball color=gray!20] circle({0.85/sqrt(2)});}}
\begin{document}
\xdef\Lst{{-1, 0, 2}, {-2, -1, 1}, 
 {0, 0, 2}, {-1, -1, 1}, 
 {-2, -2, 0}, {-1, 1, 2}, 
 {-2, 0, 1}, {1, 0, 2}, {0, -1, 1}, 
 {-1, -2, 0}, {-2, -3, -1}, 
 {0, 1, 2}, {-1, 0, 1}, 
 {-2, -1, 0}, {1, -1, 1}, 
 {0, -2, 0}, {-1, -3, -1}, 
 {1, 1, 2}, {0, 0, 1}, {-1, -1, 0}, 
 {-2, -2, -1}, {0, 2, 2}, 
 {-1, 1, 1}, {2, 1, 2}, {-2, 0, 0}, 
 {1, 0, 1}, {0, -1, 0}, 
 {-1, -2, -1}, {-2, -3, -2}, 
 {1, 2, 2}, {0, 1, 1}, {-1, 0, 0}, 
 {2, 0, 1}, {-2, -1, -1}, 
 {1, -1, 0}, {0, -2, -1}, 
 {-1, -3, -2}, {2, 2, 2}, 
 {1, 1, 1}, {0, 0, 0}, 
 {-1, -1, -1}, {-2, -2, -2}, 
 {1, 3, 2}, {0, 2, 1}, {-1, 1, 0}, 
 {2, 1, 1}, {-2, 0, -1}, {1, 0, 0}, 
 {0, -1, -1}, {-1, -2, -2}, 
 {2, 3, 2}, {1, 2, 1}, {0, 1, 0}, 
 {-1, 0, -1}, {2, 0, 0}, 
 {-2, -1, -2}, {1, -1, -1}, 
 {0, -2, -2}, {2, 2, 1}, {1, 1, 0}, 
 {0, 0, -1}, {-1, -1, -2}, 
 {1, 3, 1}, {0, 2, 0}, {-1, 1, -1}, 
 {2, 1, 0}, {1, 0, -1}, 
 {0, -1, -2}, {2, 3, 1}, {1, 2, 0}, 
 {0, 1, -1}, {-1, 0, -2}, 
 {2, 0, -1}, {1, -1, -2}, 
 {2, 2, 0}, {1, 1, -1}, {0, 0, -2}, 
 {2, 1, -1}, {1, 0, -2}}
\tdplotsetmaincoords{-90+109.471}{-90+70}
\foreach \X in {1,...,10}
{\begin{tikzpicture}
\path[use as bounding box] (-3.5,-3.5) rectangle (3.5,3.5);
\draw (0,0) circle ({1}); % /sqrt(2)
\begin{scope}[tdplot_main_coords]
 \draw[-latex] (0,0,0) coordinate (O) -- (1,0,0) node[right]{$\alpha_1$};
 \draw[-latex] (O) -- (-1/2,{1/sqrt(2)},-1/2) node[right]{$\alpha_2$};
 \draw[-latex] (O) -- (0,0,1) node[right]{$\alpha_3$};
 \draw[red,-latex] (O) -- (1/2,{1/sqrt(2)},1/2) node[right]{$-\theta$};
 \foreach \Z in \Lst
  {\pgfmathsetmacro{\myx}{{\Z}[0]}
  \pgfmathsetmacro{\myy}{{\Z}[1]}
  \pgfmathsetmacro{\myz}{{\Z}[2]}
  \pgfmathsetmacro{\mydeltax}{0.1*(rnd-0.5)}
  \pgfmathsetmacro{\mydeltay}{0.1*(rnd-0.5)}
  \pgfmathsetmacro{\mydeltaz}{0.1*(rnd-0.5)}
  \pgfmathtruncatemacro{\mycol}{int(2*rnd)}
  \ifnum\mycol=1
  \node at ({posx(\myx+\mydeltax,\myy+\mydeltay,\myz+\mydeltaz)},
  {posy(\myx+\mydeltax,\myy+\mydeltay,\myz+\mydeltaz)},
  {posz(\myx+\mydeltax,\myy+\mydeltay,\myz+\mydeltaz)}) {\usebox\Neutron};
  \else
  \node at ({posx(\myx+\mydeltax,\myy+\mydeltay,\myz+\mydeltaz)},
  {posy(\myx+\mydeltax,\myy+\mydeltay,\myz+\mydeltaz)},
  {posz(\myx+\mydeltax,\myy+\mydeltay,\myz+\mydeltaz)}) {\usebox\Proton};
  \fi}
\end{scope}
\end{tikzpicture}}
\end{document}

在此处输入图片描述

只是为了好玩:更多的核。不,它看起来不像球体,而像一组以最大密度堆积的球体。这当然不同于要求核填满一个球体。后者可能转化为距离总和最小化的要求或类似的东西,这显然与最大填充的要求不同。我不知道是否有一种简单的算法可以最小化距离总和,同时确保球体不重叠。

在此处输入图片描述

相关内容