我需要绘制几个类似的形状,如下所示:
我的代码:
\documentclass[tikz,border=1mm]{standalone}
\usetikzlibrary{perspective}
\def\r{0.5}
\def\ri{\r*0.5}
\def\rii{\r*sqrt(2)/2}
\def\riii{\r*sqrt(3)/2}
\begin{document}
\begin{tikzpicture}[3d view={120}{20},fill=gray!20]
% box
\draw[fill] (1,0,0) -- (0,0,0)-- (0,0,1) -- (1,0,1) -- cycle;
\draw[fill] (0,0,0) -- (0,1,0)-- (0,1,1) -- (0,0,1) -- cycle;
\draw[fill] (1,0,0) -- (1,1,0)-- (1,1,1) -- (1,0,1) -- cycle;
\draw[fill] (1,1,0) -- (0,1,0)-- (0,1,1) -- (1,1,1) -- cycle;
% flaps
\draw[fill] (1,0,1) -- ({1+\rii},0,{1-\rii}) -- ({1+\rii},1,{1-\rii}) -- (1,1,1) -- cycle;
\draw[fill] (0,0,1) -- ({0-\rii},0,{1+\rii}) -- ({0-\rii},1,{1+\rii}) -- (0,1,1) -- cycle;
\draw[fill] (1,1,1) -- (1,{1+\ri},{1-\riii}) -- (0,{1+\ri},{1-\riii}) -- (0,1,1) -- cycle;
\draw[fill] (1,0,1) -- (1,{0-\ri},{1+\riii}) -- (0,{0-\ri},{1+\riii}) -- (0,0,1) -- cycle;
\end{tikzpicture}
\end{document}
我想知道是否有其他更好的方法来实现这一点,即使用更简单或更易读的代码。特别是:
- 是否有任何类似 2d“矩形”的路径命令可用于 3d 图片?这将是理想的。
- 是否有其他方法处理坐标以避免冗余信息?
任何改进都将受到欢迎。
答案1
一个非常快速的 fake3D:纯 TikZ。填充选项
[top color=inside,bottom color=inside!30!black]
使盒子内部稍微暗一些,以模拟 3D 灯光效果。
\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[declare function={a=2.5;}]
\colorlet{inside}{orange!50}
\colorlet{outside}{gray!50}
\path
(0,0) coordinate (A) +(90:a) coordinate (At)
(-1.5,-1) coordinate (B) +(90:a) coordinate (Bt)
(2.5,-.5) coordinate (D) +(90:a) coordinate (Dt)
($(B)+(D)-(A)$) coordinate (C) +(90:a) coordinate (Ct)
;
% visible inside surfaces
\draw[top color=inside,bottom color=inside!30!black] % a bit dark ^^
(A)--(D)--(Dt)--(At)--cycle
(A)--(B)--(Bt)--(At)--cycle
;
% visible outside surfaces
\draw[fill=outside]
(C)--(B)--(Bt)--(Ct)--cycle
(C)--(D)--(Dt)--(Ct)--cycle
;
% visible inside upper surfaces
\draw[fill=inside!80]
(At)--(Bt)--([turn]-100:1.2) coordinate (Bs)--($(Bs)+(At)-(Bt)$)--cycle
(Bt)--(Ct)--([turn]-100:1.2) coordinate (Cs)--($(Cs)+(Bt)-(Ct)$)--cycle
(Ct)--(Dt)--([turn]-105:1.3) coordinate (Ds)--($(Ds)+(Ct)-(Dt)$)--cycle
(Dt)--(At)--([turn]-110:1.3) coordinate (As)--($(As)+(Dt)-(At)$)--cycle
;
\end{tikzpicture}
\end{document}
如果你想要几个带有一些 3D 几何变换的 3D 矩形形状,那么 3D渐近线是一个不错的选择。
答案2
我不确定它是否有帮助,因为它只适用于矩形与坐标系平行的情况:
\documentclass[tikz,border=1mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{perspective}
\def\r{0.5}
\def\ri{\r*0.5}
\def\rii{\r*sqrt(2)/2}
\def\riii{\r*sqrt(3)/2}
\begin{document}
\begin{tikzpicture}[3d view={120}{20}, fill=black!10!white]
% box
\filldraw[canvas is xz plane at y=0] (0,0) rectangle (1,1);
\filldraw[canvas is yz plane at x=0] (0,0) rectangle (1,1);
\filldraw[canvas is yz plane at x=1] (0,0) rectangle (1,1);
\filldraw[canvas is xz plane at y=1] (0,0) rectangle (1,1);
% flaps
\filldraw (1,0,1) -- ({1+\rii},0,{1-\rii}) -- ({1+\rii},1,{1-\rii}) -- (1,1,1) -- cycle;
\filldraw (0,0,1) -- ({0-\rii},0,{1+\rii}) -- ({0-\rii},1,{1+\rii}) -- (0,1,1) -- cycle;
\filldraw (1,1,1) -- (1,{1+\ri},{1-\riii}) -- (0,{1+\ri},{1-\riii}) -- (0,1,1) -- cycle;
\filldraw (1,0,1) -- (1,{0-\ri},{1+\riii}) -- (0,{0-\ri},{1+\riii}) -- (0,0,1) -- cycle;
\end{tikzpicture}
\end{document}
编辑:
您可以定义矩形,然后像这样移动和旋转坐标系:
\documentclass[tikz, border=1cm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{perspective}
\tdplotsetmaincoords{70}{120}
\begin{document}
\begin{tikzpicture}[3d view={120}{20}, fill=black!10!white]
\newcommand{\rect}{(0,0,0) -- (0.5,0,0) -- (0.5,1,0) -- (0,1,0) -- cycle}
% box
\filldraw[canvas is xz plane at y=0] (0,0) rectangle (1,1);
\filldraw[canvas is yz plane at x=0] (0,0) rectangle (1,1);
\filldraw[canvas is yz plane at x=1] (0,0) rectangle (1,1);
\filldraw[canvas is xz plane at y=1] (0,0) rectangle (1,1);
%flaps
\coordinate (Shift) at (0,0,1);
\tdplotsetrotatedcoordsorigin{(Shift)}
\tdplotsetrotatedcoords{90}{60}{180}
\filldraw[draw=cyan, tdplot_rotated_coords] \rect;
\coordinate (Shift) at (1,0,1);
\tdplotsetrotatedcoordsorigin{(Shift)}
\tdplotsetrotatedcoords{0}{45}{0}
\filldraw[draw=orange, tdplot_rotated_coords] \rect;
\coordinate (Shift) at (0,1,1);
\tdplotsetrotatedcoordsorigin{(Shift)}
\tdplotsetrotatedcoords{90}{240}{180}
\filldraw[draw=red, tdplot_rotated_coords] \rect;
\coordinate (Shift) at (0,0,1);
\tdplotsetrotatedcoordsorigin{(Shift)}
\tdplotsetrotatedcoords{0}{-135}{0}
\filldraw[draw=magenta, tdplot_rotated_coords] \rect;
\end{tikzpicture}
\end{document}