1

This question is in relation to the one I posted here. I have been trying to shade a rectangular prism so that the entire lower layer of the prism is red and the upper half layer is blue. I have the following code

\begin{tikzpicture}[join = round, xscale = 10.5, yscale = 6]

\colorlet{bcolor}{red!60}   
\colorlet{tcolor}{blue!100}
\colorlet{ttcolor}{blue!100}

\shadedraw[bottom color = bcolor, top color = tcolor]
(-1,-1) coordinate (A) rectangle (0,0);     
\shadedraw[xscale = 0.5, yslant = 0.5, bottom color = bcolor, top color = tcolor, shading angle = 25]
(0,-1) rectangle (1,0) 
(1,-1) coordinate (B)
(-1,0) coordinate (O);      
\draw[yscale = 0.5, xslant = 0.5, fill = ttcolor] (-1,0) rectangle (0,1) (-1,1) coordinate (C);

\draw[dashed, opacity = 0.7] (O)--(A) (O)--(B) (O)--(C);
\end{tikzpicture} 

which yields the following

enter image description here

This is very close to what I'm after, though it is clear on the face of the prism facing to the right that the top of face is somewhat red. As stated before, I want this region to be blue and to match the colour on the top face of the cube. No matter what I do, I haven't been able to figure out how to get the shading correct.

So, my first question is how to get the shading on the right most face to be blue on the upper half of the face, so that it matches the colour of the top of the prism and remains red down the bottom?

Secondly, I was hoping to superimpose some arrows vertically through the prism, that start slightly underneath the bottom face of the prism and have the arrow heads slightly above the top face of the prism. I haven't been able to figure this out at all. Is there a way to do this?

Thanks for your help.

EDIT:

Using the code below from the answer (after setting the preamble correctly)

\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords,line cap=round,line join=round,
fill opacity=0.8,scale=2]
\path foreach \X in {-1,1} {foreach \Y in {-1,1} 
{foreach \Z in {-1,1} {(\X,\Y,\Z) coordinate (p\X\Y\Z)}}};
\draw[dashed] (p-11-1) -- (p-1-1-1) edge (p-1-11) -- (p1-1-1);
\begin{scope}[canvas is xz plane at y=1]
\pgflowlevelsynccm
\draw[bottom color = red, top color = blue]  (-1,-1) rectangle (1,1);
\end{scope}
\begin{scope}[canvas is yz plane at x=1]
\pgflowlevelsynccm
\draw[bottom color = red, top color = blue]  (-1,-1) rectangle (1,1);
\end{scope}
\begin{scope}[canvas is xy plane at z=1]
\draw[fill=blue]  (-1,-1) rectangle (1,1);
\end{scope}
\end{tikzpicture}

yields

enter image description here

1
  • 1
    I suggest adding 'asymptote' tag, so you may get more attention from Asymptote users
    – Black Mild
    Feb 4 at 12:00
3

This is a version that transforms the shading. The key is \pgflowlevelsynccm, which gets employed by transform canvas, but unfortunately transform canvas adds something that is aimed at resetting the other transformations, which leads to problems in practice.

enter image description here

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords,line cap=round,line join=round,
    fill opacity=0.8,scale=2]
 \path foreach \X in {-1,1} {foreach \Y in {-1,1} 
 {foreach \Z in {-1,1} {(\X,\Y,\Z) coordinate (p\X\Y\Z)}}};
 \draw[dashed] (p-11-1) -- (p-1-1-1) edge (p-1-11) -- (p1-1-1);
 \begin{scope}[canvas is xz plane at y=1]
  \pgflowlevelsynccm
  \draw[bottom color = red, top color = blue]  (-1,-1) rectangle (1,1);
 \end{scope}
 \begin{scope}[canvas is yz plane at x=1]
  \pgflowlevelsynccm
  \draw[bottom color = red, top color = blue]  (-1,-1) rectangle (1,1);
 \end{scope}
 \begin{scope}[canvas is xy plane at z=1]
  \draw[fill=blue]  (-1,-1) rectangle (1,1);
 \end{scope}
\end{tikzpicture}
\end{document}
4
  • Thanks again for helping me. I copied your code exactly into my tex document and the top face/lid is sitting inside the prism, not on top. I'm not sure what is happening. I'll make an edit to my post to show you. Also, do you know how to get arrows superimposed through the prism?
    – mattos
    Feb 4 at 2:03
  • 1
    @mattos You have an ancient pgf installation. The canvas is xy plane at z key was originally screwed up but got fixed some time ago. If you do not want to update your TeX installation, you can use ``canvas is yx plane at z` instead, i.e. replace xy by yx.
    – user234180
    Feb 4 at 2:56
  • It worked, thanks again for your help. Is it possible to orient the prism so the face is facing the screen as opposed to being on a 45 degree angle? Like the prism in my post. And do you know the answer to my other question, how to get arrows threaded/superimposed through the prism?
    – mattos
    Feb 4 at 18:00
  • @mattos One can use the same machinery in your code. This is not an orthographic projection, i.e. if the xz plane precisely faces the viewer, you do not see the other plane in reality, and the orthographic projection in this code is rather close to realistic (but not fully, for that you would need the tpp library, but the projections there cannot currently be used for shadings). As for your question to add the arrows: since they seem to intersect with the boundary of the cuboid, you'd need to manually compute the intersections. This is very hard with your code since it is not a 3d projection
    – user234180
    Feb 4 at 18:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.