我正在尝试在 TikZ 中重现以下两个图形。
我尝试的图 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}
对于第二幅图,代码是
\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}
我是 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