4

I need to draw several similar shapes like this:

enter image description here

My code:

\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}

I'm wondering if there is another better way to achieve this, by using simpler or more readable code. In particular:

  • Is there any path command like the 2d 'rectangle' to use on a 3d picture? It would be desirable.
  • Is there another way to deal with coordinates to avoid redundant information?

Any improvement will be welcome.

3
  • In the cases where the canvas is parallel to the coordinate system, you can use 2D commands with e.g. the option canvas is xy plane at z=1 See: tex.stackexchange.com/a/629795/8650 May 30, 2022 at 16:30
  • For this figure only, a quick way is 2D with TikZ. For several shapes, what do you mean by "several"? Several viewpoints? Several similar shapes? Uploading more images maybe a good description
    – Black Mild
    May 30, 2022 at 16:46
  • @BlackMild, What I mean is shapes made up of rectangles (of arbitrary slope).
    – e_moro
    May 30, 2022 at 18:06

2 Answers 2

7

A very quick and fake3D: plain TikZ. The fill option

[top color=inside,bottom color=inside!30!black]

makes the box a bit darker inside to mimic the 3D light effect.

enter image description here

\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}

In case you want several 3D rectangle shapes with some 3D geometric transform, then 3D Asymptote is a nice choice.

2
  • The front two flaps look great but the back two don't look as good. I wonder why.
    – Simd
    May 31, 2022 at 8:38
  • 1
    In visible inside upper surfaces, Just adjust as you wish via angles
    – Black Mild
    May 31, 2022 at 15:08
6

I am not sure it helps as it is only for cases where the rectangle is parallel to the coordinate system:

\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}

Diagram of a open box in 3D

Edit:

You can define your rectangle and then shift and rotate the coordinate system like this:

\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}

Open box with colored flaps

1
  • Yes, I know this particular case. But I am looking for a general solution.
    – e_moro
    May 30, 2022 at 18:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .