# [Tex/LaTex] Tikz : how to control length in 3D pictures

3dtikz-pgf

I tried to draw a sphere with tikz with isometric projection or oblique projection (perpective cavalière in french).

For oblique projection you have to put a scaling factor (scal < 1) for distance on the x axes. But if I want my sphere to look like a not distorted sphere, I have to put a scaling of zero. Thus, I obtain a projection in (yz) plane. Hereafter is my tikz source code, you can easily switch between isometric and oblique projection :

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{}

\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{2mm}

\tikzstyle{cavaliere} = [x={(-0.866cm,-0.5cm)},y={(1cm,0cm)},z={(0cm,1cm)}]
\tikzstyle{isometrique} = [x={(-0.866cm,-0.5cm)},y={(0.866cm,-0.5cm)},z={(0cm,1cm)}]
\tikzstyle{mesh} = [color=gray, opacity=0.4]

\begin{document}

%
% norm selection :
%
%   if(isometrique)
%
\begin{tikzpicture}[isometrique]
\def\scal{1.}

%   else if(cavaliere)
%
%\begin{tikzpicture}[cavaliere]
%       \def\scal{0.3}
%

\coordinate (O) at (0,0,0);
\draw[->] (O) -- ({\scal * 3},0,0) node[below] {x};
\draw[->] (O) -- (0,3,0) node[below] {y};
\draw[->] (O) -- (0,0,3) node[right] {z};

\def\r{2.}

% meridiens
% \rho joue le role de theta
\foreach \phi in {0,10,...,170} {
\draw[mesh] ({\scal * \r * cos(\phi)}, {\r * sin(\phi)}, 0)
\foreach \rho in {5,10,...,360} {
--({\scal * \r * cos(\phi) * cos(\rho)}, {\r * sin(\phi) * cos(\rho)}, {\r * sin(\rho)})
} -- cycle;
}

% parallels
\foreach \rho in {-60, -40, -19.57, 0, 19.57, 40, 60} {
\draw[mesh] ({\scal * \r * cos(\rho)}, 0, {\r * sin(\rho)})
\foreach \phi in {5,10,...,360} {
-- ({\scal * \r * cos(\rho) * cos(\phi)}, {\r * cos(\rho) * sin(\phi)}, {\r * sin(\rho)})
} -- cycle;
}
\end{tikzpicture}

\end{document}


Do you know how to draw a correct sphere in oblique projection. I prefer that one because the view of what I put into the sphere is better than in isometric projection.

Thanks

EDIT : axes z vertical

\begin{tikzpicture}[x={(-0.385cm,-0.385cm)},y={(1cm,0cm)},z={(0cm,1cm)},scale=4]

\coordinate (O) at (0,0,0);
\draw[->] (O) -- (2,0,0) node[below] {x};
\draw[->] (O) -- (0,2,0) node[below] {y};
\draw[->] (O) -- (0,0,2) node[right] {z};

\foreach \z in {-0.98,-0.96,...,0.98}  {%
\begin{scope}[canvas is xy plane at z=\z]
\draw[gray] (0,0) circle ({sqrt(1-\z*\z)});
\end{scope}}

\begin{scope}[canvas is zy plane at x=0]
\draw (0,0) circle (1cm);
\draw (-1,0) -- (1,0) (0,-1) -- (0,1);
\end{scope}

\begin{scope}[canvas is zx plane at y=0]
\draw (0,0) circle (1cm);
\draw (-1,0) -- (1,0) (0,-1) -- (0,1);
\end{scope}

\begin{scope}[canvas is xy plane at z=0]
\draw (0,0) circle (1cm);
\draw (-1,0) -- (1,0) (0,-1) -- (0,1);
\end{scope}

\end{tikzpicture}


Thus I obtained

Simple code, it's better to use arc and to determine the visible part.

I think the result is something like that :

  \documentclass{article}
\usepackage{tikz}
\usetikzlibrary{3D}

\pagestyle{empty}

\begin{document}
\begin{tikzpicture}[scale=4]

\foreach \z in {-0.98,-0.96,...,0.98}  {%
\begin{scope}[canvas is xy plane at z=\z]
\draw[gray] (0,0) circle ({sqrt(1-\z*\z)});
\end{scope}}

\begin{scope}[canvas is zy plane at x=0]
\draw (0,0) circle (1cm);
\draw (-1,0) -- (1,0) (0,-1) -- (0,1);
\end{scope}

\begin{scope}[canvas is zx plane at y=0]
\draw (0,0) circle (1cm);
\draw (-1,0) -- (1,0) (0,-1) -- (0,1);
\end{scope}

\begin{scope}[canvas is xy plane at z=0]
\draw (0,0) circle (1cm);
\draw (-1,0) -- (1,0) (0,-1) -- (0,1);
\end{scope}

\end{tikzpicture}
\end{document}


How to change axes

if the plane facing the viewer is yz , and the receding axis is x, then a point is projected like this:

 y'= y + 1/2  cos(a) x
z'= z + 1/2  sin(a) x


You need to change the system like this, if you want k=0.5 and a=45° :

                   x = { ({-0.5*cos(45)},{-0.5*sin(45)})},
y = { (1cm,0cm)},
z = { (0cm,1cm)}


So x =(-0.35355,-0.35355). I don't why in pgf z =(-0.385,-0.385).

It's possible to try a=30 degrees or a=60 degrees.

  \documentclass{article}
\usepackage{tikz}
\usetikzlibrary{3D}

\pagestyle{empty}

\begin{document}
\begin{tikzpicture}[x = { ({-0.5*cos(45)},{-0.5*sin(45)})},
y = { (1cm,0cm)},
z = { (0cm,1cm)},
scale = 4]

\foreach \x in {-0.98,-0.96,...,0.98}  {%
\begin{scope}[canvas is zy plane at x=\x]
\draw[gray] (0,0) circle ({sqrt(1-\x*\x)});
\end{scope}}

\begin{scope}[canvas is zy plane at x=0]
\draw (0,0) circle (1cm);
\draw (-1,0) -- (1,0) (0,-1) -- (0,1);
\end{scope}

\begin{scope}[canvas is zx plane at y=0]
\draw (0,0) circle (1cm);
\draw (-1,0) -- (1,0) (0,-1) -- (0,1);
\end{scope}

\begin{scope}[canvas is xy plane at z=0]
\draw (0,0) circle (1cm);
\draw (-1,0) -- (1,0) (0,-1) -- (0,1);
\end{scope}

\end{tikzpicture}

\end{document}