I'm trying to draw some simple 3D objects in TikZ. I can do spheres and cuboids okay, but I'm struggling with circular cylinders: When rotating the scene (I use `tikz-3dplot`

for this), the end faces have to be transformed from circles into ellipses. Using `\draw ... circle;`

doesn't work, because a path defined like that will always stay circular. If I use `\draw ... to ... to ...`

constructs with the `in`

and `out`

set to adequate values, I can "simulate" circles that transform slightly better: The "corner" points of the circle end up in the right place, but the `in`

and `out`

angles are not transformed appropriately.

What can I do to get "3D circles", i.e. circles that turn into ellipses when the 3D space is rotated?

Here's an example showing the problem:

```
\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{40}{20}
\noindent The vertical cylinder walls\\
are not aligned properly \ldots
\begin{tikzpicture}[tdplot_main_coords]
\draw (0,0) circle [radius=1cm];
\end{tikzpicture}
\begin{tikzpicture}[tdplot_main_coords]
\draw (1,0,2) -- (0,1,2) -- (-1,0,2) -- (0,-1,2) -- cycle
(-1,0,0) -- (0,-1,0) -- (0,-1,2) -- (-1,0,2) -- cycle
(1,0,2) -- (0,-1,2) -- (0,-1,0) -- (1,0,0) -- cycle;
\end{tikzpicture}
\begin{tikzpicture}[tdplot_main_coords]
\draw [in=225, out=-45, relative] (0.5,0.5,2) to (-0.5,0.5,2) to (-0.5,-0.5,2) to (0.5,-0.5,2) to (0.5,0.5,2)
(0.5,0.5,0) to (-0.5,0.5,0) to (-0.5,-0.5,0) to (0.5,-0.5,0) to (0.5,0.5,0)
(0.5,0.5,2) -- (0.5,0.5,0)
(-0.5,-0.5,2) -- (-0.5,-0.5,0);
\end{tikzpicture}
\tdplotsetrotatedcoords{40}{50}{-30}\vspace{0.5cm}
\noindent\ldots and the support points\\don't get transformed correctly
\begin{tikzpicture}[tdplot_rotated_coords]
\draw (0,0) circle [radius=1cm];
\end{tikzpicture}
\begin{tikzpicture}[tdplot_rotated_coords]
\draw (1,0,2) -- (0,1,2) -- (-1,0,2) -- (0,-1,2) -- cycle
(-1,0,0) -- (0,-1,0) -- (0,-1,2) -- (-1,0,2) -- cycle
(1,0,2) -- (0,-1,2) -- (0,-1,0) -- (1,0,0) -- cycle;
\end{tikzpicture}
\begin{tikzpicture}[tdplot_rotated_coords]
\draw [in=225, out=-45, relative] (0.5,0.5,2) to (-0.5,0.5,2) to (-0.5,-0.5,2) to (0.5,-0.5,2) to (0.5,0.5,2)
(0.5,0.5,0) to (-0.5,0.5,0) to (-0.5,-0.5,0) to (0.5,-0.5,0) to (0.5,0.5,0)
(0.5,-0.5,2) -- (0.5,-0.5,0)
(-0.5,0.5,2) -- (-0.5,0.5,0);
\end{tikzpicture}
\end{document}
```

## Best Answer

What a good question! I'm surprised that no-one's asked this before ...

There are two pieces to the puzzle here: getting the end circles right, and deciding where to draw the edges. The first turns out to actually be easy - if you know what to look for in the TikZ manual. The second takes a little bit of maths, but not too much.

Let's deal with the first. When you draw a "cicle" in TikZ, you are allowed to specify the radii. So you can say

`\draw (0,0) circle[x radius=2cm, y radius=3cm];`

. This will produce an ellipse with major axis straight up and minor axis in the horizontal. Now, in TikZ, you are allowed to specify dimensionless distances. Let's imagine the conversation ...You: Draw me a circle with x radius 2cm and y radius 3cm.TikZ: Yes, Sir! Rightaway, Sir!You: Draw me a circle with x radius 2 and y radius 3.TikZ: Yes, Sir! Righta ... hang on. "x radius 2"? 2 what? 2 apples? 2 oranges?You: 2 in the x direction.TikZ: (getting a bit querulous) Yes, but where's that?You: Thexdirection. Over that way.TikZ: Could you be more specific?You: Okay, let's say that the x direction is 1cm along and .5cm up. Will that do?TikZ: Yes.pauseNow, what about y?The point of that silliness is that when you specify a dimenionless length, TikZ interprets it as that number times the appropriate vector. So

`x radius=2`

means "set the x-axis of this ellipse to be twice the current`x`

vector". But we have complete control over what that`x`

vector is! So if we tell TikZ that`x`

means something else, it will use it.The great thing about this is that if you say that

`x={(1cm,1cm)}, y={(0cm,1cm)}`

then TikZ will draw something approximating (cos θ, cos θ + sin θ), which is exactly what you want if you happen to be looking at a circle in such a way that the x axis is lying actually along the diagonal.Compare and contrast:

The middle one is the right one here.

So for the ends of the cylinder, the trick is simple: draw your ends as honest circles using

dimensionlesslengths. Then adjust the`x`

and`y`

values to suit. (There is one warning here: if you use dimensionless lengths to set the`x`

and`y`

values then they are set in terms of thecurrent`x`

and`y`

. Although this might be what you want in theory, if you write`x={(1,1)}, y={(1,-1)}`

then the`x`

that is used to set the`y`

is the new one, not the old one.) With dimensionless radii, it is also possible to use transformations correctly.Now to the edges of the cylinder. The difficulty here is that the place to draw the edges is determined by their eventual location on the page. So to decide where to draw the edges we need to find out exactly where the cylinder ends will be drawn and find their extreme points. What we mean by "extreme" here is that we want to draw a tangent line along the direction of the cylinder. So we take the orthogonal direction to the direction of the cylinder

as rendered on the pageand look for the extreme points of the deformed circlesas rendered on the pagein that direction.Fortunately, this is quite easy. Our deformed circle has the equation cos θ x + sin θ y whether in 3D space or on the page. So we just need to work out what x and y are on the page. We can do that by "drawing" a vector of one unit in the x direction and recording the

actualcoordinates. To get the direction orthogonal to the direction of the cylinder, we "draw" a vector in the direction of the cylinder and record its coordinates as well. Let's call that one z. Then we take its orthogonal direction, say w. So now we examine the function cos θ w·x + sin θ w·y and look for its extreme values. Differentiating and setting equal to zero, we get -sin θ w·x + cos θ w·y = 0. Rearranging, we get tan θ = w·y/w·x. Since we only want sin θ and cos θ we don't actually need to work out θ itself (though we can do so if we need it for something else). Note that we use thesein the original coordinate system.Putting all that together, if we assume that our cylinder should go along the z-direction (whatever that happens to be) and the cross-section be in the x-y plane (again, whatever that happens to be) then working out the mathematics is the following code.

If this were in a macro, we could be a bit more efficient and use

`\tikz@scan@one@point`

instead of drawing a point and getting the last x-y values.Once we have those values, drawing the cylinder itself is quite easy. Here's an example.

This produces the following:

If we want to get a bit fancy, we can put some shading in the inside of the cylinder by filling it with successively darker colours. Simply put

before the line that starts

`\fill[red]`

. This produces:If we change the definition of the vectors, say to

`[x={(.7cm,.3cm)},z={(.5cm,-.5cm)}]`

, we find that it transforms as it should:The usual caveats about using TikZ to draw 3D drawings apply here: it's up to you, the user, to decide what gets drawn on top of what and to arrange your drawing appropriately.