I am trying to apply Tikz-dimline label position (Dimension lines) to a 3-dimensional drawing. This has worked well for me in 2D, so thought it would do so in 3D.
Thus, when in a 2D drawing I would use something like
\draw [postaction={indicate dimensions={$2$}}] (C) -- (G);
it should work in 3D when used as
\begin{scope}[canvas is xy plane at z=\Height]
\draw [postaction={indicate dimensions={$2$}}] (C) -- (G);
\end{scope}
However, the above two produce exactly the same results (black dimension lines in the figure). An approximation of the desired result is shown in red.
What is the simplest way to modify either the dimensionsing code from Tikz-dimline label position (Dimension lines), or how I am using it to work in 3D?
Notes:
I would highly prefer changing how I am invoking the code (instead of changing the existing
dimlinecode), as the existing code works well for the 2D case.The desired result in red is an approximation so as not clutter the figure posted here (The dimension arrow line was shifted away from the end of the dimension markers).
The code seems longer due mostly to the packaging of the grid and axis drawings. The relevant parts are really at the top (the dimension code) and at the end in the
canvas is xy plane at z=\Heightscope.
Code:
\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{3d}
\pagecolor{white}
%% ---------------------------------------------------------------------
%% https://tex.stackexchange.com/a/468144/4301
\usetikzlibrary{calc,decorations.pathreplacing,arrows.meta}
\newif\ifdrawdimlineleft
\newif\ifdrawdimlineright
\tikzset{dimlabel distance/.initial=5mm,
vertical lines extend/.initial=5mm,
vertical dim line/.style={gray,thin},
dim arrow line/.style={latex-latex,thin},
dim label/.style={},
left dimline/.is if=drawdimlineleft,
left dimline=true,
right dimline/.is if=drawdimlineright,
right dimline=true,
indicate dimensions/.style={decorate,decoration={
show path construction,
lineto code={
\draw[dim arrow line]
($ (\tikzinputsegmentfirst)!\pgfkeysvalueof{/tikz/dimlabel distance}!-90:(\tikzinputsegmentlast) $) -- ($ (\tikzinputsegmentlast)!\pgfkeysvalueof{/tikz/dimlabel distance}!90:(\tikzinputsegmentfirst) $)
\ifx#1\empty
\else
node[midway,sloped,fill=white,dim label]{#1}
\fi;
\ifdrawdimlineleft
\draw[vertical dim line] (\tikzinputsegmentfirst) --
($ (\tikzinputsegmentfirst)!\pgfkeysvalueof{/tikz/vertical lines
extend}!-90:(\tikzinputsegmentlast) $);
\fi
\ifdrawdimlineright
\draw[vertical dim line] (\tikzinputsegmentlast) --
($ (\tikzinputsegmentlast)!\pgfkeysvalueof{/tikz/vertical lines extend}!90:(\tikzinputsegmentfirst) $);
\fi
}}}}
%% ---------------------------------------------------------------------
\NewDocumentCommand{\DrawCoordinateGrid}{O{} m m m m m m}{%
\def\XGridMin{#2}
\def\XGridMax{#3}
\def\YGridMin{#4}
\def\YGridMax{#5}
\def\ZGridMin{#6}
\def\ZGridMax{#7}
%
\begin{scope}[canvas is xy plane at z=0, ultra thin, gray!75]
\draw [#1] (\XGridMin,\YGridMin) grid (\XGridMax,\YGridMax);
\end{scope}
\begin{scope}[canvas is yz plane at x=0, ultra thin, gray!75]
\draw [#1] (\YGridMin,\ZGridMin) grid (\YGridMax,\ZGridMax);
\end{scope}
\begin{scope}[canvas is xz plane at y=0, ultra thin, gray!75]
\draw [#1] (\XGridMin,\ZGridMin) grid (\XGridMax,\ZGridMax);
\end{scope}
}%
\NewDocumentCommand{\DrawCoordinateAxis}{O{} m m m m m m}{%
\def\XAxisMin{#2}
\def\XAxisMax{#3}
\def\YAxisMin{#4}
\def\YAxisMax{#5}
\def\ZAxisMin{#6}
\def\ZAxisMax{#7}
%
\begin{scope}[thin, gray, -latex]
\draw [#1] (\XAxisMin,0,0) -- (\XAxisMax,0,0) node [below left] {$x$};
\draw [#1] (0,\YAxisMin,0) -- (0,\YAxisMax,0) node [right] {$y$};
\draw [#1] (0,0,\ZAxisMin) -- (0,0,\ZAxisMax) node [above] {$z$};
\end{scope}
}%
\newcommand\Width{2.5}%
\newcommand\Depth{4.5}%
\newcommand*\Height{2.0}%
\tikzset{Line Style/.style={draw=brown, ultra thick, join=round}}
\begin{document}
\begin{tikzpicture}[
x={(-0.5cm,-0.5cm)},
y={(0.9659cm,-0.25882cm)},
z={(0cm,1cm)},
]
\coordinate (O) at (0,0,0);
%% ---------------------------------------------- yz plane at x=0
\coordinate (A) at (0,\Width,0);
\coordinate (B) at (0,\Width,\Height);
\coordinate (C) at (0,0,\Height);
%% ---------------------------------------------- yz plane at x=\Depth
\coordinate (D) at (\Depth,0,0);
\coordinate (E) at (\Depth,\Width,0);
\coordinate (F) at (\Depth,\Width,\Height);
\coordinate (G) at (\Depth,0,\Height);
\DrawCoordinateGrid{0}{6}{0}{4}{0}{3}
\DrawCoordinateAxis[thick, black]{0}{6.5}{0}{4.5}{0}{3.5}
%% ------------------------------------ Draw the rectangular prism
\draw [Line Style] (O) -- (A) -- (B) -- (C) -- cycle;% yz plane at x=0
\draw [Line Style] (D) -- (E) -- (F) -- (G) -- cycle;% yz plane at x=\Depth
\draw [Line Style] (O) -- (D) -- (G) -- (C) -- cycle;% xz plane at y=0
\draw [Line Style] (A) -- (E) -- (F) -- (B) -- cycle;% xz plane at y=\Width
%% This produces the same if it is within a "canvas is xy plane at z=\Height" scope
%\draw [postaction={indicate dimensions={$2$}}] (C) -- (G);
\begin{scope}[canvas is xy plane at z=\Height, inner sep=0pt]
\draw [postaction={indicate dimensions={$2$}}] (C) -- (G);
\end{scope}
%% This is what I expected from the above scope:
\begin{scope}[canvas is xy plane at z=\Height, transform shape, inner sep=2pt, red]
\draw (C) -- ([yshift=-5mm]C);
\draw (G) -- ([yshift=-5mm]G);
\draw [latex-latex] ([yshift=-3mm]C) -- ([yshift=-3mm]G)
node [pos=0.5, xscale=-1, yscale=-1, fill=white] {$2$};
\end{scope}
%% Following is for debugging purposes so you can see where the points are
%% These are last so that they show up on top
\foreach \xy in {O, A, B, C, D, E, F, G}{
\node at (\xy) {\tiny\xy};
}
\end{tikzpicture}
\end{document}



calcare perpendicular on the screen but not in 3D. So, in order to get what you want, you cannot rely on thecalcmethods. In 3d there are always two linearly independent directions that are perpendicular to a given direction. You want the result to be perpendicular in the ambient plane, right? – Mar 16 '21 at 00:27show path constructiondecoration. – Mar 16 '21 at 05:51