1

I wonder if it is possible to obtain a gradient colour fill to replicate the light position by means of TikZ. For example in these images (taken by a book) it is evident, that the light effect from above makes the figures more 3D.

Image example 1 Image example 2

My best attempt until now is the following

\documentclass[tikz, border = 1cm]{standalone}
\usetikzlibrary{positioning,shadings}

\begin{document}
\begin{tikzpicture}
[x={(0.866025403cm,-0.5cm)}, y={(0cm,1cm)}, z={(-0.866025403*4cm,-0.5*4cm)}]
\newcommand{\f}{2}


\draw[domain = -pi/4:pi-pi/4, smooth, shading=axis, top color=red,bottom color=red,middle color=white, shading angle = 30]
plot({sin(\x r)},{cos(\x r)},{-\f/2}) -- (0.707106781,-0.707106781,-\f/2) -- (0.707106781,-0.707106781,\f/2) --
plot({cos(\x r)},{sin(\x r)},{\f/2}) -- cycle;
\draw[domain = 0:2*pi, smooth, shading=axis, top color=pink, bottom color=red, shading angle = -60]
plot({sin(\x r)},{cos(\x r)},{\f/2}) -- cycle;

\draw[domain = pi-pi/4:2*pi-pi/4, smooth, dashed]
plot({sin(\x r)},{cos(\x r)},{-\f/2});

\draw[densely dashdotted] (0,0,-\f/2) -- (0,0,\f/2);

\fill (0,0,-\f/2) circle [radius=0.5mm];
\fill (0,0,\f/2) circle [radius=0.5mm];
\end{tikzpicture}
\end{document}

Which after compilation results in

Image from attempt

Here the light effect does not seem really natural and I do not really know how to reach a sufficient result similar to the examples above 1 and 2.

5
  • No - it is not possible generally. It is called ray tracing en.wikipedia.org/wiki/Ray_tracing_(graphics). You place objects and light sources in 3D and a program calculates the pixel based output. Your example is sufficiently simple, that it is not problem to approximate in Tikz. Is this image what you wish to reproduce? You need to show what you have tried - draw the figure with a flat color. -and show compilable code. Jan 26 at 18:23
  • Gradients and shadings are no problem for TikZ see e.g. tex.stackexchange.com/questions/641981/… - but there is no concept of light sources. Jan 26 at 18:25
  • @hpekristiansen I added a minimal working example as requested and my best attempt. I found this in a book, so I wondered how to make something like this. Thank you for the link on question regarding the shading.
    – Richard
    Jan 26 at 19:04
  • Hi Richard. You can find a construction of 3D simple objects (say a cylinder or a cone) in the light in my answer to this question.
    – Daniel N
    Jan 26 at 21:27
  • 1
    Theoretically, it is possible to do this even in plain TeX since TeX is Turing complete. But theoretical possibility is one thing; practical sensibleness is another. These kinds of diagrams are best created in software designed to render 3D objects with light sources if you want something approaching realism. If you want to do it in PGF, you can define custom non-uniform shadings.
    – cfr
    Jan 27 at 3:04

1 Answer 1

3
\documentclass[tikz, border=1cm, svgnames]{standalone}
\begin{document}
\begin{tikzpicture}[ultra thick]
\pgfdeclareverticalshading{myshading}{50bp}{
color(0bp)=(pink);
color(15bp)=(HotPink!80!white);
color(30bp)=(pink);
color(40bp)=(white);
color(50bp)=(pink)
}
\begin{scope}[transform canvas={rotate=-30}]
\fill[shading=myshading] (-2,-2.5) arc[start angle=270, end angle=90, x radius=1, y radius=2.5] -- (0,2.5) -- (0,-2.5) --cycle;
\fill[HotPink!80!white] (0,0) circle[x radius=1, y radius=2.5];
\fill[HotPink!90!black] (-135:0.5 and 1) -- (-60:1 and 2.5) arc[start angle=-60, end angle=0, x radius=1, y radius=2.5];
\draw[white] (0,-2.5) arc[start angle=270, end angle=90, x radius=1, y radius=2.5];
\draw (0,2.5) arc[start angle=90, end angle=-90, x radius=1, y radius=2.5];
\draw (0,-2.5) -- (-2,-2.5) arc[start angle=270, end angle=90, x radius=1, y radius=2.5] -- (0,2.5);
\fill[shading=myshading] (0,-1) arc[start angle=270, end angle=90, x radius=0.5, y radius=1] -- (8,1) -- (8,-1) --cycle;
\fill[HotPink!80!white] (8,0) circle[x radius=0.5, y radius=1];
\draw[white] (8,-1) arc[start angle=270, end angle=90, x radius=0.5, y radius=1];
\draw (8,1) arc[start angle=90, end angle=-90, x radius=0.5, y radius=1];
\draw (8,-1) -- (0,-1) arc[start angle=270, end angle=90, x radius=0.5, y radius=1] -- (8,1);
\end{scope}
\useasboundingbox (-5,-5) rectangle (8,4);
\end{tikzpicture}
\end{document}

Two cylinders in different pink shadings

As I do not know how to handle custom shadings probably - or if it can be done, I have used transform canvas to rotate the picture. transform canvas is normally last resort to solve problems and can introduce other problems. Here the bounding box need to be set manually.

1
  • This looks really nice! Thank you
    – Richard
    Jan 28 at 13:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .