# Using Cylindrical coordinates with Graphics3D

I have:

Graphics3D[{
Arrow[{{0, 0, 0}, {2, 0, 0}}],
Arrow[{{0, 0, 0}, {0, 2, 0}}],
Arrow[{{0, 0, 0}, {0, 0, 2}}],
Blue, Thick,
Line[{{0, 0, 0}, {Sqrt[2], Sqrt[2], 0}}],
Line[{{Sqrt[2], Sqrt[2], 0}, {Sqrt[2], Sqrt[2], 1}}],
Red, PointSize[Large], Point[{Sqrt[2], Sqrt[2], 1}],
Arrow[Table[0.5 {Cos[t], Sin[t], 0}, {t, 0, Pi/4, Pi/24}]],
Text[Style["x", Black, 14], {2.1, 0, 0}],
Text[Style["y", Black, 14], {0, 2.1, 0}],
Text[Style["z", Black, 14], {0, 0, 2.1}],
Text[Style["\[Pi]/4", Black, 14], {0.6, 0.2, 0}],
Text[Style["2", Black, 14], {0.7, 0.9, 0}],
Text[Style["1", Black, 14], {1.6, 1.4, 0.5}],
Text[Style["(2, \[Pi]/4, 1)", Black, 14], {1.4, 1.4, 1.2}]
}]


Which produces this image:

Suppose that I wish to use cylindrical coordinates, for example, Line[{{0,0,0},{2,Pi/4,0}}] instead of Line[{{0,0,0},{Sqrt[2],Sqrt[2],0}}]. How would I go about that?

And, suppose I wanted to use cylindrical coordinates everywhere in my code. How would I go about that?

One easy solution is to write your graphics-primitives as usual but using cylindrical coordinates instead.

primitives = Table[
{Hue[z], Arrow[{{0, 0, 5 z}, {1, 2 Pi z, 5 z}}]}, {z, 0, 1, .05}
];


And before you display them inside a Graphics3D, you map all 3D points from cylindrical to Cartesian

mapping[{r_, theta_, z_}] := {r Cos[theta], r Sin[theta], z};
Graphics3D[primitives /. point : {_, _, _} :> mapping[point]]


### Edit

Davids comment:

Can you explain this line: Graphics3D[primitives /. point : {_, _, _} :> mapping[point]]? The part I don't understand is point : {_, _, _} :>

The primitives are all kind of graphic drawing commands and I assume that all 3d vectors like {1,Pi,2} are indeed points given in cylindrical coordinates. What I want to do is to replace every point by its Cartesian counterpart.

So what I tell Mathematica is to replace every point that has the form of a list with 3 elements. This is written as

point:{_,_,_}


If haven't seen the : operator then please read the documentation of Pattern.

The other operator that seems to confuse you is :>. Don't be afraid, it doesn't bite. It is just a normal rule that you can use for replacement of expressions and it is the good friend of the well known ->. The difference between them is very simple. When you write

expr /. lhs -> rhs


then rhs is evaluated before it is replaced. When you use :> instead, then rhs is not evaluated. Sounds complicated? Please study the following very simple example. Try to think about what you would expect as result before evaluating it. Tip: HoldForm will not evaluate something. Therefore HoldForm[1-1] will not be evaluated to 0.

HoldForm[a] /. a -> (a + 1 - 1)

HoldForm[a] /. a :> (a + 1 - 1)


Finally, in this specific example (and indeed in many other examples too), I could have used -> as well and the outcome would be the same. On the other hand, a very unexpected thing would have happened if you had defined

point = {0, 0, 0};


somewhere in your notebook. And to give you another reason to use :>, look at how beautifully green the last point is highlighted when you use it

• Can you explain this line: Graphics3D[primitives /. point : {_, _, _} :> mapping[point]]? The part I don't understand is point : {_, _, _} :>. Commented Jun 9, 2015 at 2:41
• For mapping you could also use: transform = CoordinateTransformData["Cylindrical" -> "Cartesian", "Mapping"]
– chuy
Commented Jun 9, 2015 at 13:31
• @chuy I explicitly didn't use it because I wouldn't have been able to explain why this doesn't work: CoordinateTransform["Cylindrical" -> "Cartesian", {0, 0, 0}]. My initial version contained CoordinateTransform and I was really surprised that it choked upon every point where r is zero. Any clues? Commented Jun 9, 2015 at 21:10
• @David See my edit at the end of the answer. I hope this helps. Commented Jun 9, 2015 at 21:10
• @halirutan Those are singular points. If you use the "Mapping" form it doesn't perform the check to see if the point obeys the coordinate range assumptions for that chart. Similarly CoordinateTransform["Spherical" -> "Cartesian", {r, 0, 0}] would give the same message.
– chuy
Commented Jun 9, 2015 at 21:25