# distance computation in tikz

I want to do a distance computation are mark only those points which satisfies the given condition. More specifically, let p=(1,1,1) and I want to put a solid circle at only those points (x,y,z) which satisfies |1-x| + |1-y| + |1-z| = 1.... I could do manually as well, but if a general method is available it is better to use. Here is the code I'm working on:

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usepackage{amssymb}
\usepackage{xifthen}

\begin{document}

\tdplotsetmaincoords{60}{125}
\tdplotsetrotatedcoords{0}{0}{0} %<- rotate around (z,y,z)

\begin{figure}
\begin{tikzpicture}[scale=2.0]

\foreach \x in {0,1,2}
\foreach \y in {0,1,2}
\foreach \z in {0,1,2}{
%#####################################################
\ifthenelse{  \lengthtest{\x pt < 2pt}  }
{
% True
\draw [black]   (\x,\y,\z) -- (\x+1,\y,\z);
}
{% False
}
%#####################################################
\ifthenelse{  \lengthtest{\y pt < 2pt}  }
{
% True
\draw [black]   (\x,\y,\z) -- (\x,\y+1,\z);
}
{% False
}
%#####################################################
\ifthenelse{  \lengthtest{\z pt < 2pt}  }
{
% True
\draw [black]   (\x,\y,\z) -- (\x,\y,\z+1);
}
{% False
}
\draw (\x,\y,\z) circle(2pt);

}

\filldraw[fill opacity=0.3, draw=gray, fill=gray!20]
(0,0,1)--(2,0,1)--(2,2,1)--(0,2,1)--cycle;

\fill[black] (1,1,2) circle(2pt);
\fill[black] (2,1,1) circle(2pt);
\fill[black] (1,1,0) circle(2pt);
\fill[black] (0,1,1) circle(2pt);

\filldraw[fill opacity=0.3, draw=gray, fill=gray!20]
(0,1,2)--(2,1,2)--(2,1,0)--(0,1,0)--cycle;

\fill[black] (1,0,1) circle(2pt);
\fill[black] (1,2,1) circle(2pt);

\node[below right] at (1,1,1){$p$};
\fill[black] (1,1,1) circle(1pt);

\end{tikzpicture}

\end{figure}

\end{document}


You can use \pgfmathparse{int(abs(1-\x)+abs(1-\y)+abs(1-\z))} to compute your distance and then \ifnum\pgfmathresult=1 to test for distance 1. Similarly, I'd use \ifnum\x<1 etc instead of \ifthenelse... just because is it shorter.

With these changes your MWE becomes marginally shorter:

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usepackage{amssymb}
\usepackage{xifthen}

\begin{document}

\tdplotsetmaincoords{60}{125}
\tdplotsetrotatedcoords{0}{0}{0} %<- rotate around (z,y,z)

\begin{figure}
\begin{tikzpicture}[scale=2.0]

\foreach \x in {0,1,2}
\foreach \y in {0,1,2}
\foreach \z in {0,1,2}{i
\pgfmathparse{int(abs(1-\x)+abs(1-\y)+abs(1-\z))}
\ifnum\pgfmathresult=1
\fill[black] (\x,\y,\z) circle(2pt);
\else
\draw (\x,\y,\z) circle(2pt);
\fi
%#####################################################
\ifnum\x<2
\draw [black]   (\x,\y,\z) -- (\x+1,\y,\z);
\fi
%#####################################################
\ifnum\y<2
\draw [black]   (\x,\y,\z) -- (\x,\y+1,\z);
\fi
%#####################################################
\ifnum\z<2
\draw [black]   (\x,\y,\z) -- (\x,\y,\z+1);
\fi
}

\filldraw[fill opacity=0.3, draw=gray, fill=gray!20]
(0,0,1)--(2,0,1)--(2,2,1)--(0,2,1)--cycle;

\filldraw[fill opacity=0.3, draw=gray, fill=gray!20]
(0,1,2)--(2,1,2)--(2,1,0)--(0,1,0)--cycle;

\node[below right] at (1,1,1){$p$};
\fill[black] (1,1,1) circle(1pt);

\end{tikzpicture}

\end{figure}

\end{document}


The output is the same.

This solution is very similar to Andrew's solution, i also used \ifnum instead of \ifthenelse and the computation is quite the same.

But i added two variables \newcommand\MaxSize{CubeSize} and \def\P{{P_x,P_y,P_z}} to define the cube size and the point P to. Also some code is added to have a more general method to create the gray plains or the point P.

Example with \def\P{{1,1,1}} and MaxSize =1,...,3(see first for loop): distance-computation:

\pgfmathparse{abs(\P-\x)+abs(\P-\y)+abs(\P-\z)-1}
\ifcase\pgfmathresult
\draw[fill] (\x,\y,\z) circle(2pt);
\else
\draw (\x,\y,\z) circle(2pt);
\fi

• ifcase: those points (x,y,z) which satisfy|1-x| + |1-y| + |1-z| -1= 0=> filled
• else: those points (x,y,z) which satisfy|1-x| + |1-y| + |1-z| -1~= 0 => not filled

MWE:

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usepackage{xifthen}

\newcommand\MaxSize{2}
\def\P{{1,1,1}}

\begin{document}
\tdplotsetmaincoords{60}{125}
\tdplotsetrotatedcoords{0}{0}{0}

\foreach \size in {1,...,3}{

\renewcommand\MaxSize{\size}

\begin{tikzpicture}[scale=1.5]
\foreach \x in {0,1,...,\MaxSize}
\foreach \y in {0,1,...,\MaxSize}
\foreach \z in {0,1,...,\MaxSize}{

\ifnum\x<\MaxSize
\draw [black]   (\x,\y,\z) -- (\x+1,\y,\z);
\fi

\ifnum\y<\MaxSize
\draw [black]   (\x,\y,\z) -- (\x,\y+1,\z);
\fi

\ifnum\z<\MaxSize
\draw [black]   (\x,\y,\z) -- (\x,\y,\z+1);
\fi

\pgfmathparse{abs(\P-\x)+abs(\P-\y)+abs(\P-\z)-1}
\ifcase\pgfmathresult
\draw[fill] (\x,\y,\z) circle(2pt);
\else
\draw (\x,\y,\z) circle(2pt);
\fi

}

\filldraw[fill opacity=0.3, draw=red, fill=gray!20](0,0,\P)--(\MaxSize,0,\P)--(\MaxSize,\MaxSize,\P)--(0,\MaxSize,\P)--cycle;

\filldraw[fill opacity=0.3, draw=red, fill=gray!20] (0,\P,\MaxSize)--(\MaxSize,\P,\MaxSize)--(\MaxSize,\P,0)--(0,\P,0)--cycle;

%Point P
\node[below right,green] at (\P,\P,\P){$p$};
\fill[green] (\P,\P,\P) circle(1pt);
\end{tikzpicture}

}

\end{document}

• +1 for the \P[i]. I didn't know that this was possible! – Andrew Jul 18 '17 at 11:17