如何为立方体中的几个透明平面着色?

如何为立方体中的几个透明平面着色?

我正在尝试在 TikZ 中重现以下两个图形。

图。1 图 2

我尝试的图 1 代码是

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
    \draw [fill=black, ultra thick, red]  (0.0,0.0) -- (0.5, 0.5) -- (0.5, 1.5) -- (0.0, 1.0) -- cycle;
    \draw [fill=black, ultra thick, blue] (1.0,0.0) -- (1.5, 0.5)-- (1.5, 1.5)--(1.0, 1.0)--cycle;
    \draw  (0.0,0.0)  -- (1.0, 0.0)-- (1.5, 0.5)--(0.5, 0.5)--cycle;
    \draw  (0.0,1.0) -- (1.0, 1.0)-- (1.5, 1.5)--(0.5, 1.5)--cycle;
    \end{tikzpicture}
\end{document}

我的图 1

对于第二幅图,代码是

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
    \draw [fill=black, ultra thick, red]  (1.0,0.0) -- (1.0, 1.0) -- (0.5, 1.5) -- (0.5, 0.5) -- cycle;
    \draw [fill=black, ultra thick, blue] (0.0,0.0) -- (0.0, 1.0)-- (1.5, 1.5)--(1.5, 0.5)--cycle;
    \draw  (0.0,0.0)  -- (1.0, 0.0)-- (1.5, 0.5)--(0.5, 0.5)--cycle;
    \draw  (0.0,1.0) -- (1.0, 1.0)-- (1.5, 1.5)--(0.5, 1.5)--cycle;
    \draw  (1.0, 0.0) -- (1.0, 1.0)  (0.5, 0.5) -- (0.5, 1.5);
    \end{tikzpicture}
\end{document}

我的图 2

我是 TikZ 新手,很难用更高效的代码生成完全相同的图形。我在叠加和精确坐标方面遇到了问题。如果您能帮助我解决这些问题并使用更强大的代码获得类似的图形,我将不胜感激。

答案1

人们经常忘记 tikZ 也有一个xyz坐标系。我认为它能让你以更自然的方式表达坐标。(我还添加了圆圈。)

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

\begin{document}
    \begin{tikzpicture}[scale=4,fill opacity=0.4,thick,
                        line cap=round,line join=round]
    %% Define coordinate labels.
    % t(op) and b(ottom) layers
    \path \foreach \layer/\direction in {b/{0,0,0},t/{0,1,0}} {
        (\direction)
        \foreach \point/\label in {{0,0,0}/ll,{1,0,0}/lr,{1,0,-1}/ur,{0,0,-1}/ul} {
            +(\point) coordinate (\layer\label)
        }
        ($(\layer ll)!0.5!(\layer ur)$) coordinate (\layer md)
    };

    % Put text next to the labels as requested.
    % Funilly enough we need to set fill opacity to 1.
    \draw \foreach \text/\label/\anchor in {%
        one/bll/east,
        two/bul/east,
        three/tll/east,
        four/tul/east,
        five/blr/west,
        six/bur/west,
        seven/tlr/west,
        eight/tur/west} {
        (\label) node[anchor=\anchor,fill opacity=1] {\text}
    };

    % Draw left cube.
    \fill (0,0,-1) circle (0.5pt);
    \foreach \direction in {(0,0,1),(0,1,0),(1,0,0)} {
        \draw[dashed,black] (bul) -- + \direction;
    }
    \fill[blue!60] (bmd) -- (bur) -- (tur) -- (tmd);
    \fill[red!60]  (blr) -- (tlr) -- (tul) -- (bul);
    \fill[blue!60] (bll) -- (bmd) -- (tmd) -- (tll);
    \draw (bll) -- (blr) -- (tlr) -- (tll) -- cycle;
    \draw (blr) -- (bur) -- (tur) -- (tlr) -- cycle;
    \draw (tll) -- (tlr) -- (tur) -- (tul) -- cycle;
    \foreach \point in {bll,blr,bur,tll,tlr,tul,tur} {
        \fill[fill opacity=1] (\point) circle (0.75pt);
    }

    % Draw right cube.
    \path (blr) + (0.65,0) coordinate (pos);
    \foreach \direction in {(0,0,1),(0,1,0),(1,0,0)} {
        \draw[dashed] (pos) ++ (bul) -- + \direction;
    }
    \fill[blue!60] (pos) +(blr) -- +(bur) -- +(tur) -- +(tlr);
    \fill[red!60]  (pos) +(bll) -- +(bul) -- +(tul) -- +(tll);
    \draw (pos) +(tll) -- +(tlr) -- +(tur) -- +(tul) -- cycle
                +(tll) -- +(bll) -- +(blr) -- +(bur) -- +(tur)
                +(blr) -- +(tlr);
    \end{tikzpicture}
\end{document}

侧面有阴影的立方体

答案2

您的选项不太好。当您写入 时\draw[fill=black, ultra thick, red],如您所见,fill=black它不起作用。您的最后一个选项red用于绘图和填充。要用红色填充并用黑色绘制,您需要写入\draw[color=black,fill=red, ultra thick]。表面和线条为红色,线条宽度很重要,因此结果并不好。现在,第一次,您可以分别使用\draw\fill。顺序很重要,因为某些选项会对第一幅图产生影响。还有其他方法(方式)可以创建此图片,但我稍后会给您代码。对于每个顶点的圆,使用变量而不是“原始”坐标很有趣,您可以使用\foreach。注释在代码中。

数字

在此处输入图片描述

我的代码更新

我保留初始代码来显示什么是错的,什么是正确的

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

 \tikzset{vertex/.style={shape=circle, % style for a vertex
                    minimum size=3pt,
                    fill=black,
                    inner sep = 0pt}}
\begin{tikzpicture}[scale=4] 
  % define the points  
 \path  (0,0)     coordinate (A)  (1,0)     coordinate (B) % bottom
        (1.5,0.5) coordinate (C)  (0.5,0.5) coordinate (D)
        (0,1)     coordinate (E)  (1,1)     coordinate (F) % top  add 1 for y
        (1.5,1.5) coordinate (G)  (0.5,1.5) coordinate (H)
        ($(A)!0.5!(C)$) coordinate (O)   % middle of A--C
        ($(E)!0.5!(G)$) coordinate (P);%   

    \draw (A) -- (E) (B) -- (F) (C) -- (G) ; % lateral 
    \draw[gray,dashed]  (D) -- (H) (D) -- (C) (D) -- (A) (D) -- (B) (A) -- (C);   
    \fill [blue!50,fill opacity=.5] (P) -- (O) -- (C) -- (G) -- cycle;
    \fill [red!50, fill opacity=.5] (H) -- (D) -- (B) -- (F) -- cycle;
    \fill [blue!50,fill opacity=.5] (A) -- (O) -- (P) -- (E) -- cycle;
    \draw (A) -- (B) -- (C) (F) -- (H); % bottom 
    \draw (E) -- (F) -- (G) -- (H) -- (E) -- (G); % top
    % vertex 
    \foreach \vertex in {A,...,C} {\node[vertex] at (\vertex) {};}
    \foreach \vertex in {E,...,H} {\node[vertex] at (\vertex) {};}
    \node[vertex,fill=gray] at (D) {};       
  \end{tikzpicture} 
  \end{document}   

版本 3D

我认为这是更好的方法。有了canvas is xy plane at z=0,你就有了平面图(xy)。我使用了一些负值来尊重我的第一个解决方案并使用相同的代码。只有正值的代码看起来更好。要使用另一侧,你只需要写下例如,canvas is xz plane at y=0你就会得到一个平面图(横向)轴是 x 和 z。结果完全相同,你不需要微积分,但你需要一些空间方向!

我添加了黄色来展示如何使用其他计划小心,我使用了 canvas is yx plane而不是canvas is xy plane

在此处输入图片描述

\documentclass[12pt,a4paper]{article}
\usepackage{tikz}     
\usetikzlibrary{calc,3d}

\begin{document}
\thispagestyle{empty} 

 \tikzset{vertex/.style={shape=circle, % style for a vertex
                        minimum size=3pt,
                        fill=gray,
                        inner sep = 0pt}}  

  \begin{tikzpicture}
    [x={(-0.5cm,-0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)}, scale=4]  
    \draw[thick](0,0,0)--(1.2,0,0) node[below right]{x} ;
    \draw[thick](0,0,0)--(0,1.2,0) node[below right]{y} ;
    \draw[thick](0,0,0)--(0,0,1.2) node[below right]{z} ;
  % face  bottom
   \begin{scope}[canvas is xy plane at z=0,very thin]
       \coordinate  (A) at (0,0);   \coordinate (C) at (-1,1);
       \coordinate  (B) at (-1,0);  \coordinate  (D) at (0,1); 
        \coordinate (O) at  ($(A)!0.5!(C)$); % middle of A--C   
   \end{scope}  
     % face  top
    \begin{scope}[canvas is xy plane at z=1,very thin]
        \coordinate  (E) at (0,0);  \coordinate (G) at (-1,1);     
        \coordinate  (F) at (-1,0); \coordinate (H) at (0,1);
        \coordinate (P) at  ($(E)!0.5!(G)$); % middle of A--C     
    \end{scope} 

    \begin{scope}[canvas is yx plane at z=0]
      \path[fill = yellow] (0,0) rectangle (1,-1);
    \end{scope} 

     \foreach \vertex in {A,...,H} {\node[vertex] at (\vertex) {};}
        \draw (A) -- (B) -- (C) -- (D) -- cycle; % bottom
        \draw (E) -- (F) -- (G) -- (H) -- cycle; % top 
        \draw (A) -- (E) (B) -- (F) (C) -- (G) (D)--(H); % lateral  
        \fill [blue!50,fill opacity=.5] (P) -- (O) -- (C) -- (G) -- cycle;
        \fill [red!50, fill opacity=.5] (H) -- (D) -- (B) -- (F) -- cycle;
        \fill [blue!50,fill opacity=.5] (A) -- (O) -- (P) -- (E) -- cycle;     
\end{tikzpicture}
\end{document}

为了娱乐

我想避免最大坐标

\documentclass[12pt,a4paper]{article}
\usepackage{tikz}     
\usetikzlibrary{calc,3d}

\begin{document}
\thispagestyle{empty} 

 \tikzset{vertex/.style={shape=circle, % style for a vertex
                        minimum size=8pt,
                        ball color=gray,
                        inner sep = 0pt}}  

\begin{tikzpicture}
    [x={(-0.5cm,-0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)}, scale=4]
\foreach \z in {0,1}  \foreach \y in {0,1}  \foreach  \x in {0,1}   
    {\coordinate (\x\y\z) at  (\x,\y,\z) ;} 

         \coordinate (O) at  ($(000)!0.5!(110)$);
         \coordinate (P) at  ($(001)!0.5!(111)$);

\fill[fill opacity=.5,blue!30] (O) 
    \foreach \pt in {P,011,010}{--(\pt.center)}--cycle;% 

\fill[fill opacity=.5,red!30] (000) 
    \foreach \pt in {110,111,001}{--(\pt.center)}--cycle;% 

\fill[fill opacity=.5,blue!30] (O) 
    \foreach \pt in {P,101,100}{--(\pt.center)}--cycle;% 

\draw[thick,double] (000.center)
    \foreach \pt in {010,011,001}{--(\pt.center)}--cycle;%

\foreach \y in {0,1}  \foreach  \z in {0,1}    
    {\node[vertex] (0\y\z) at  (0\y\z) {};}

\draw[thick,double] (100.center)
    \foreach \pt in {110,111,101}{--(\pt.center)}--cycle;%  

 \foreach \y in {0,1}  \foreach  \z in {0,1}    
    {\draw[thick,double] (0\y\z) -- (1\y\z);
     \node[vertex] (1\y\z) at  (1\y\z) {};}
\end{tikzpicture} 
\end{document}

在此处输入图片描述

答案3

只是为了好玩:一个以 3D 顺序绘制平面的版本,即最后绘制前景中的平面。这是这个答案。在这两篇文章中,排序相当简单,因为所有平面的法向量都位于一个平面上。因此,只需要区分 4 种情况(最多)。

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{calc}
\newcommand{\DrawRectangularPlane}[4][]{\draw[#1] 
#2 -- ++  #3 --++ #4 -- ++ ($-1*#3$) -- cycle;}
\newcommand{\DrawSinglePlane}[2][]{\ifcase#2
\or % 1 xz plane at y=-1 
\DrawRectangularPlane[fill=red,#1]{({-2*cos(45)*\PlaneScale},{-2*sin(45)*\PlaneScale},-\PlaneScale)}
{(2*\PlaneScale,0,0)}{(0,0,2*\PlaneScale)} 
\or% 2 xz plane at y=1
\DrawRectangularPlane[fill=blue,#1]{({-2*cos(45)*\PlaneScale},{2*sin(45)*\PlaneScale},-\PlaneScale)}
{(2*\PlaneScale,0,0)}{(0,0,2*\PlaneScale)} 
\or% 3 yz plane at x=-1
\DrawRectangularPlane[fill=red,#1]{({-2*cos(45)*\PlaneScale},{-2*sin(45)*\PlaneScale},-\PlaneScale)}
{(0,2*\PlaneScale,0)}{(0,0,2*\PlaneScale)} %
\or% 4 yz plane at x=1
\DrawRectangularPlane[fill=blue,#1]{({2*cos(45)*\PlaneScale},{-2*sin(45)*\PlaneScale},-\PlaneScale)}
{(0,2*\PlaneScale,0)}{(0,0,2*\PlaneScale)} % 
\or% 5 diagonal upper right quadrant
\DrawRectangularPlane[fill=blue,#1]{({2*cos(45)*\PlaneScale},{2*sin(45)*\PlaneScale},-\PlaneScale)}
{({-2*cos(45)*\PlaneScale},{-2*sin(45)*\PlaneScale},0)}{(0,0,2*\PlaneScale)} 
\or% 6 diagonal upper left quadrant
\DrawRectangularPlane[fill=red,#1]{({-2*cos(45)*\PlaneScale},{2*sin(45)*\PlaneScale},-\PlaneScale)}
{({2*cos(45)*\PlaneScale},{-2*sin(45)*\PlaneScale},0)}{(0,0,2*\PlaneScale)} 
\or% 7 diagonal lower right quadrant
\DrawRectangularPlane[fill=red,#1]{({2*cos(45)*\PlaneScale},{-2*sin(45)*\PlaneScale},-\PlaneScale)}
{({-2*cos(45)*\PlaneScale},{2*sin(45)*\PlaneScale},0)}{(0,0,2*\PlaneScale)} 
\or %d iagonal lower left quadrant
\DrawRectangularPlane[fill=blue,#1]{({-2*cos(45)*\PlaneScale},{-2*sin(45)*\PlaneScale},-\PlaneScale)}
{({2*cos(45)*\PlaneScale},{2*sin(45)*\PlaneScale},0)}{(0,0,2*\PlaneScale)} 
\fi
} 
\begin{document}
\foreach \X in {0,5,...,355} % {70}
{\tdplotsetmaincoords{90+40*sin(\X)}{\X} % the first argument cannot be larger than 90
\pgfmathsetmacro{\PlaneScale}{1}
\begin{tikzpicture}
\path[use as bounding box] (-4*\PlaneScale,-4*\PlaneScale) rectangle (4*\PlaneScale,4*\PlaneScale);
\begin{scope}[tdplot_main_coords]
\pgfmathtruncatemacro{\xproj}{sign(cos(\tdplotmainphi-45))}
\pgfmathtruncatemacro{\zproj}{sign(sin(\tdplotmainphi-45))}
\ifnum\xproj=1
  \ifnum\zproj=1
   \foreach \X in {5,6,7,8}
    {\DrawSinglePlane{\X}}
  \else
   \foreach \X in {8,6,7,5}
    {\DrawSinglePlane{\X}}
  \fi  
\else
  \ifnum\zproj=1
   \foreach \X in {5,7,6,8}
    {\DrawSinglePlane{\X}}
  \else
   \foreach \X in {6,5,8,7}
    {\DrawSinglePlane{\X}}
  \fi  
\fi  
% \draw[thick,->] (0,0,0) -- (2,0,0) node[anchor=north east]{$x$};
% \draw[thick,->] (0,0,0) -- (0,2,0) node[anchor=north west]{$y$};
% \draw[thick,->] (0,0,0) -- (0,0,1.5) node[anchor=south]{$z$};
\end{scope}
\end{tikzpicture}}
\end{document}

在此处输入图片描述

两个平行平面的情况就更简单了。可以用以下方式进行排序

\pgfmathtruncatemacro{\xproj}{sign(sin(\tdplotmainphi))}
%\node[anchor=north west] at (current bounding box.north west) {\tdplotmainphi,\xproj};
\ifnum\xproj=1
   \foreach \X in {3,4}
    {\DrawSinglePlane{\X}}
\else
   \foreach \X in {4,3}
    {\DrawSinglePlane{\X}}
\fi  

在此处输入图片描述

相关内容