具有表面的 3d 立方体

具有表面的 3d 立方体

我想绘制一个单位壳层来显示原子的排列,如下图所示。(Zumdahl,《化学原理》,第 5 版,霍顿·米夫林,第 773 页。)

我想出了以下代码来绘制原子面(上面的立方体)。它采用了只需定义一次立方体面的想法:然后可以倾斜它来绘制其他面。但是,我不知道如何(从数学上)绘制阴影(剪裁球体)。有什么建议吗?

如果可能的话,使用只定义一个隔间面的想法。这非常方便,因为我必须绘制上述所有示例,甚至更多(我在示例中添加了两个面)。但是,如果这不可能,其他解决方案是值得赞赏的。不能旋转解决方案。

\documentclass{minimal}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}
\pgfmathsetmacro{\D}{4}
\pgfmathsetmacro{\halfD}{\D/2}

\newcommand{\mycubicleface}{
    \pgfmathsetmacro{\R}{\D/2}
    \draw [fill=blue!30] (0,\R) arc [start angle=90, end angle=0, radius=\R] -- +(-\R,0);
    \draw [fill=blue!30] (0,\R) arc [start angle=-90, end angle=0, radius=\R] -- +(-\R,0);
    \draw [fill=blue!30] (\D,\R) arc [start angle=-90, end angle=-180, radius=\R] -- +(\R,0);
    \draw [fill=blue!30] (\D,\R) arc [start angle=90, end angle=180, radius=\R] -- +(\R,0);
    \draw (0,0) rectangle +(\D,\D);
}

%\newcommand{\mycubicleface}{
%   \pgfmathsetmacro{\R}{\D/sqrt(8)}    
%   \draw [fill=blue!30] (\D/2,\D/2) circle [radius=\R];
%   \draw [fill=blue!30] (0,\R) arc [start angle=90, end angle=0, radius=\R] -- +(-\R,0);
%   \draw [fill=blue!30] (0,\D - \R) arc [start angle=-90, end angle=0, radius=\R] -- +(-\R,0);
%   \draw [fill=blue!30] (\D,\D - \R) arc [start angle=-90, end angle=-180, radius=\R] -- +(\R,0);
%   \draw [fill=blue!30] (\D,\R) arc [start angle=90, end angle=180, radius=\R] -- +(\R,0);
%   \draw (0,0) rectangle +(\D,\D);
%}

\begin{scope}[yslant=-.5]
    \mycubicleface
\end{scope}
\begin{scope}[xshift=\D cm, yshift=-\halfD cm, yslant=.5]
    \mycubicleface
\end{scope}
\begin{scope}[xshift=\D cm, yshift=\halfD cm, yslant=.5, xslant=-1]
    \mycubicleface
\end{scope}

\end{tikzpicture}
\end{document}

答案1

这是您结果的对应部分。

这个想法来自于这个例子在球体上绘制一些经线/纬度圆。我没有绘制这些圆弧,而是将它们用作剪切路径。部分作品需要将弧连接在一起。

\documentclass[tikz]{standalone} 
\usepackage{tikz,spath}
    \usetikzlibrary{calc,fadings}

\newcommand\pgfmathsinandcos[3]{
    \pgfmathsetmacro#1{sin(#3)}\pgfmathsetmacro#2{cos(#3)}}

\newcommand\LongitudePlane[3][current plane]{
    \pgfmathsinandcos\sinEl\cosEl{#2}\pgfmathsinandcos\sint\cost{#3}
    \tikzset{#1/.style={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}}

\newcommand\LatitudePlane[3][current plane]{%
    \pgfmathsinandcos\sinEl\cosEl{#2}\pgfmathsinandcos\sint\cost{#3}
    \pgfmathsetmacro\yshift{\cosEl*\sint}
    \tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}}}

\newcommand\ClipLongitudeCircle[2]{
    \LongitudePlane\angEl{#1}
    \pgfmathsetmacro\angVis{atan(sin(#1)*cos(\angEl)/sin(\angEl))}
    \path[save path=\tmppath,current plane](\angVis:\R)arc(\angVis:\angVis+180:\R);
    \pgfoonew\patha=new spath(\tmppath)
    \pgfmathsetmacro\angVis{-atan(sin(\angEl)*cos(#1)/sin(#1))}
    \path[save path=\tmppath](-90+\angVis:\R)arc(-90+\angVis:#2180-90+\angVis:\R);
    \pgfoonew\pathb=new spath(\tmppath)
    \patha.concatenate with lineto(,\pathb)\patha.close()\patha.use path with tikz(clip)}

\newcommand\ClipLatitudeCircle[2]{
    \LatitudePlane{\angEl}{#1}
    \path[save path=\tmppath,current plane](-180:\R)arc(-180:0:\R);
    \pgfoonew\patha=new spath(\tmppath)
    \path[save path=\tmppath](0:\R)arc(0:#2180:\R);
    \pgfoonew\pathb=new spath(\tmppath)
    \patha.concatenate with lineto(,\pathb)\patha.close()\patha.use path with tikz(clip)}

\newcommand\EighthSphere[3]{
    \ClipLongitudeCircle{45-\angPh}{#1}
    \ClipLongitudeCircle{135-\angPh}{#2}
    \ClipLatitudeCircle{0}{#3}
    \fill[ball color=white](0,0)circle(\R);}

\begin{document}
\def\R{6} % sphere radius
\def\angEl{20} % elevation angle in interval [1,89]
\def\angPh{10} % phase angle in interval [-44,44]
\pgfmathsetmacro\uofx{cos(-135-\angPh)}
\pgfmathsetmacro\vofx{sin(-135-\angPh)*sin(\angEl)}
\pgfmathsetmacro\uofy{cos(-45-\angPh)}
\pgfmathsetmacro\vofy{sin(-45-\angPh)*sin(\angEl)}
\pgfmathsetmacro\uofz{0}
\pgfmathsetmacro\vofz{cos(\angEl)}
\begin{tikzpicture}
    \begin{scope}[x={(\uofx cm,\vofx cm)},y={(\uofy cm,\vofy cm)},z={(\uofz cm,\vofz cm)}]
        \path(-6,-6,-6)coordinate(A){}(6,6,6)coordinate(B){};
        \path(6,-6,-6)coordinate(P){}(6,6,-6)coordinate(Q){}(-6,6,-6)coordinate(R){}
             (-6,6,6)coordinate(S){}(-6,-6,6)coordinate(T){}(6,-6,6)coordinate(U){};
    \end{scope}
    \path(-12,-12)(12,12);
    \draw(P)--(Q)--(R)--(S)--(T)--(U)--cycle;
    \clip(P)--(Q)--(R)--(S)--(T)--(U)--cycle;
    \begin{scope}[transform canvas={shift=(A)}]
        \EighthSphere{+}{-}{+}
    \end{scope}
    \begin{scope}[transform canvas={shift=(P)}]
        \EighthSphere{+}{+}{+}
    \end{scope}
    \begin{scope}[transform canvas={shift=(R)}]
        \EighthSphere{-}{-}{+}
    \end{scope}
    \begin{scope}[transform canvas={shift=(T)}]
        \EighthSphere{+}{-}{-}
    \end{scope}
    \begin{scope}[transform canvas={shift=(Q)}]
        \EighthSphere{-}{+}{+}
    \end{scope}
    \begin{scope}[transform canvas={shift=(S)}]
        \EighthSphere{-}{-}{-}
    \end{scope}
    \begin{scope}[transform canvas={shift=(U)}]
        \EighthSphere{+}{+}{-}
    \end{scope}
\end{tikzpicture}
\end{document}

答案2

终于到了!您可以通过注释和取消注释以下代码来生成所有三个立方体。

答案基本上是符号 1 的答案,仅修改。请注意,您需要spath手动安装包正如这里所告知的

代码中的注释部分用于调试(绘制要剪切的路径)。

最终结果令人满意。但是,请注意最中间图像中两个半球的堆叠和阴影不正确。

在此处输入图片描述

\documentclass[tikz]{standalone} 
\usepackage{spath}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{fadings}

\begin{document}

% Source: LaTeX-Community.org 
%         <http://www.latex-community.org/viewtopic.php?f=4&t=2111>
\begin{tikzpicture}
\newcommand\pgfmathsinandcos[3]{%
  \pgfmathsetmacro#1{sin(#3)}%
  \pgfmathsetmacro#2{cos(#3)}%
}
\newcommand\LongitudePlane[3][current plane]{%
  \pgfmathsinandcos\sinEl\cosEl{#2} % elevation
  \pgfmathsinandcos\sint\cost{#3} % azimuth
  \tikzset{#1/.style={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
}
\newcommand\LatitudePlane[3][current plane]{%
  \pgfmathsinandcos\sinEl\cosEl{#2} % elevation
  \pgfmathsinandcos\sint\cost{#3} % latitude
  \pgfmathsetmacro\yshift{\cosEl*\sint}
  \tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}}
}

%\newcommand\DrawLongitudeCircle[2][4]{
%  \LongitudePlane{\angEl}{#2}
%%  \tikzset{current plane/.prefix style={scale=#1}}
%   % angle of "visibility"
%  \pgfmathsetmacro\angVis{atan(sin(#2)*cos(\angEl)/sin(\angEl))}
%  \draw[current plane, blue] (\angVis:\R) arc (\angVis:\angVis+180:\R);
%  \draw[current plane, blue] (\angVis-180:\R) arc (\angVis-180:\angVis:\R);
%}

%\newcommand\DrawLatitudeCircle[2][5]{
%  \LatitudePlane{\angEl}{#2}
%%  \tikzset{current plane/.prefix style={scale=#1}}
%%  \pgfmathsetmacro\sinVis{sin(#2)/cos(#2)*sin(\angEl)/cos(\angEl)}
%%  % angle of "visibility"
%%  \pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
%  \draw[current plane, red] (\angVis:\R) arc (\angVis:-\angVis-180:\R);
%  \draw[current plane, red] (180-\angVis:\R) arc (180-\angVis:\angVis:\R);
%}

\newcommand\ClipLongitudeCircle[2]{
    \LongitudePlane{\angEl}{#1}
    \pgfmathsetmacro\angVis{atan(sin(#1)*cos(\angEl)/sin(\angEl))}
    \path[save path=\tmppath, current plane] (\angVis:\R) arc (\angVis:\angVis+180:\R); % current plane transformation
    \pgfoonew\patha=new spath(\tmppath)
    \pgfmathsetmacro\angVis{-atan(sin(\angEl)*cos(#1)/sin(#1))}
    \path[save path=\tmppath] (-90+\angVis:\R) arc (-90+\angVis:#2 180-90+\angVis:\R); % no coordinate transform (no current plane)
    \pgfoonew\pathb=new spath(\tmppath)
    \patha.concatenate with lineto(,\pathb)
    \patha.close()
    \patha.use path with tikz(clip)
%   \patha.use path with tikz(fill=magenta, opacity=.2)
%   \patha.use path with tikz(draw=magenta, very thick)
}

\newcommand\ClipLatitudeCircle[2]{
    \LatitudePlane{\angEl}{#1}
    \path[save path=\tmppath,current plane] (-180:\R) arc (-180:0:\R);
    \pgfoonew\patha=new spath(\tmppath)
    \path[save path=\tmppath] (0:\R) arc (0:#2 180:\R);
    \pgfoonew\pathb=new spath(\tmppath)
    \patha.concatenate with lineto(,\pathb)
    \patha.close()
    \patha.use path with tikz(clip)
%   \patha.use path with tikz(fill=cyan, opacity=.2)
%   \patha.use path with tikz(draw=cyan, very thick)
}

\newcommand\ClippedEightSphere[4]{
\begin{scope}[transform canvas={shift=(#4)}]
    \ClipLongitudeCircle{45-\angPh}{#1}
    \ClipLongitudeCircle{135-\angPh}{#2}
    \ClipLatitudeCircle{0}{#3}
    \fill[ball color=white] (0,0) circle (\R);
\end{scope}}

\newcommand\ClippedLatitudeSphere[3]{
\begin{scope}[transform canvas={shift=(#1)}]
    \LatitudePlane{\angEl}{#2}
    \ClipLatitudeCircle{0}{#3}
    \fill[ball color=white] (0,0) circle [radius=\R];
\end{scope}}

\newcommand\ClippedLongitudeSphere[3]{
\begin{scope}[transform canvas={shift=(#1)}]
    \LongitudePlane{\angEl}{#2}
    \ClipLongitudeCircle{#2}{#3}
    \fill[ball color=white] (0,0) circle [radius=\R];
\end{scope}}

\newcommand\DrawLongitudeArc[4]{
    \LongitudePlane{\angEl}{#2}
    \begin{scope}[current plane, transform canvas={shift=(#1)}]
    \fill [cyan] (0,0) -- ++(#3:\R) arc [start angle=#3, delta angle=#4, radius=\R] -- cycle;
    \draw ++(#3:\R) arc [start angle=#3, delta angle=#4, radius=\R];
    \end{scope}}

\newcommand\DrawLatitudeArc[4]{
    \LatitudePlane{\angEl}{#2}
    \begin{scope}[current plane, transform canvas={shift=(#1)}]
    \fill [cyan] (0,0) -- ++(#3:\R) arc [start angle=#3, delta angle=#4, radius=\R] -- cycle;
    \draw ++(#3:\R) arc [start angle=#3, delta angle=#4, radius=\R];
    \end{scope}}



    \def\D{8} % cubic side length
%   \pgfmathsetmacro\R{\D/2} % sphere radius
    \pgfmathsetmacro\R{sqrt(2)/4*\D} % sphere radius
%   \pgfmathsetmacro\R{sqrt(3)/4*\D} % sphere radius
    \def\angEl{20} % elevation angle in interval [1,89]
    \def\angPh{10} % phase angle in interval [-44,44]
    \pgfmathsetmacro\uofx{cos(-135-\angPh)}
    \pgfmathsetmacro\vofx{sin(-135-\angPh)*sin(\angEl)}
    \pgfmathsetmacro\uofy{cos(-45-\angPh)}
    \pgfmathsetmacro\vofy{sin(-45-\angPh)*sin(\angEl)}
    \pgfmathsetmacro\uofz{0}
    \pgfmathsetmacro\vofz{cos(\angEl)}

    % The coordinates of the cube
    \begin{scope}[x={(\uofx cm,\vofx cm)}, y={(\uofy cm,\vofy cm)}, z={(\uofz cm,\vofz cm)}]
    \coordinate (C1) at (\D,0,0);
    \coordinate (C2) at (\D,0,\D);
    \coordinate (C3) at (0,0,\D);
    \coordinate (C4) at (0,\D,\D);
    \coordinate (C5) at (0,\D,0);
    \coordinate (C6) at (\D,\D,0);
    \coordinate (C7) at (0,0,0);
    \coordinate (C8) at (\D,\D,\D);
%    \foreach \n in {1,2,...,8} \node at (C\n) {C\n};

    \coordinate (C0) at ($(C2)!.5!(C5)$);
    \coordinate (S1) at ($(C2)!.5!(C6)$);
    \coordinate (S2) at ($(C2)!.5!(C4)$);
    \coordinate (S3) at ($(C8)!.5!(C5)$);
    \coordinate (S4) at ($(C6)!.5!(C7)$);
    \coordinate (S5) at ($(C1)!.5!(C3)$);
    \coordinate (S6) at ($(C5)!.5!(C3)$);
    \end{scope}

    % Draw the clipped spheres
    \ClippedEightSphere{+}{-}{+}{C7}
    \ClippedLongitudeSphere{S5}{45-\angPh}{+}
    \ClippedLongitudeSphere{S6}{135-\angPh}{-}
    \ClippedLatitudeSphere{S4}{0}{+}

    \ClippedEightSphere{-}{+}{-}{C8}
    \ClippedEightSphere{+}{-}{-}{C3}
    \ClippedEightSphere{+}{+}{-}{C2}
%   \fill[ball color=white] (C0) circle [radius=\R];
    \ClippedEightSphere{-}{-}{-}{C4}
    \ClippedEightSphere{+}{+}{+}{C1}
    \ClippedEightSphere{-}{-}{+}{C5}
    \ClippedEightSphere{-}{+}{+}{C6}

    % Draw the half spheres
    \ClippedLatitudeSphere{S2}{0}{-}
    \ClippedLongitudeSphere{S3}{45-\angPh}{-}
    \ClippedLongitudeSphere{S1}{135-\angPh}{+}
    \DrawLatitudeArc{S2}{0}{0}{360}
    \DrawLongitudeArc{S1}{135-\angPh}{0}{360}
    \DrawLongitudeArc{S3}{45-\angPh}{0}{360}

    % Draw the Arcs
    \DrawLongitudeArc{C1}{135-\angPh}{90}{90}
    \DrawLongitudeArc{C2}{135-\angPh}{-90}{-90}
    \DrawLongitudeArc{C4}{45-\angPh}{-90}{-90}
    \DrawLongitudeArc{C5}{45-\angPh}{90}{90}
    \DrawLongitudeArc{C6}{135-\angPh}{90}{-90}
    \DrawLongitudeArc{C6}{45-\angPh}{90}{-90}
    \DrawLongitudeArc{C8}{135-\angPh}{-90}{90}
    \DrawLongitudeArc{C8}{45-\angPh}{-90}{90}
    \DrawLatitudeArc{C2}{0}{45-\angPh}{-90}
    \DrawLatitudeArc{C3}{0}{-45-\angPh}{-90}
    \DrawLatitudeArc{C4}{0}{135-\angPh}{90}
    \DrawLatitudeArc{C8}{0}{135-\angPh}{-90}

    % Draw the cube
    \draw (C1)--(C2)--(C3)--(C4)--(C5)--(C6)--cycle;
    \draw (C2)--(C8)--(C6);
    \draw (C8)--(C4);

    % Radius node
    \coordinate (r) at ($(C2) - (\R/10,0)$);
    \LongitudePlane{\angEl}{135-\angPh}
    \draw [<->, current plane] (r) -- node [left] {$r$} +(-90:\R);

\end{tikzpicture}

相关内容