Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am drawing the cartesian coordinate system in XYZ coordinate system and would like to illustrate a point in the 3d space by drawing the projections on each plane. A simple version would be as follows: A point and its `projections' obtained with this code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

%: isometric  South West (-150): Y , East : X , North : Z
\tikzset{isometricYXZ/.style={x={(1cm,0cm)}, y={(-1.299cm,-0.75cm)}, z={(0cm,1cm)}}}

\begin{document}
 \begin{tikzpicture}[inner sep=0.2cm]
  \def \radi{3}
  \def \x{2}
  \def \y{2}
  \def \z{2}

  \begin{scope}[isometricYXZ]
   % the grid
   \begin{scope}[color=gray!50, thin]
    \foreach \xi in {0,...,\radi}{ \draw (\xi,\radi,0) -- (\xi,0,0) -- (\xi,0,\radi); }%
    \foreach \yi in {1,...,\radi}{ \draw (0,\yi,\radi) -- (0,\yi,0) -- (\radi,\yi,0); }%
    \foreach \zi in {0,...,\radi}{ \draw (0,\radi,\zi) -- (0,0,\zi) -- (\radi,0,\zi); }%
   \end{scope}

   \draw[-latex, ultra thick, color=blue] (0,0,0) -- (4,0,0) node[anchor=west] {X};%
   \draw[-latex, ultra thick, color=red] (0,0,0) -- (0,4,0) node[anchor=north] {Y};%
   \draw[-latex, ultra thick, color=green] (0,0,0) -- (0,0,4) node[anchor=east] {Z};%

   \fill[color=magenta, opacity=0.2] (0,0,0) -- (\x,0,0) -- (\x,\y,0) -- (0,\y,0) -- cycle; %
   \fill[color=yellow, opacity=0.2] (0,0,0) -- (0,0,\z) -- (0,\y,\z) -- (0,\y,0) -- cycle; %
   \fill[color=cyan, opacity=0.2] (0,0,0) -- (\x,0,0) -- (\x,0,\z) -- (0,0,\z) -- cycle;

   \draw[color=gray, thick]%
   (0,\y,\z) -- (\x,\y,\z) -- (\x,\y,0) (\x,\y,\z) -- (\x,0,\z);%
  \end{scope}

  \shade[ball color=yellow] ($\y*(-1.299cm,-0.75cm)+(\x,\z)$) circle (0.1);%
 \end{tikzpicture}
\end{document}

To make the drawing nicer, I want to shade these projections, what I managed to do for the XZ plane: with XZ shading

This is the code for the shaded part:

\begin{scope}[isometricYXZ]
  \def \h{{0.5*sqrt(\x*\x + \z*\z)}}
  \clip (0,0,0) -- (\x,0,0) -- (\x,0,\z) -- (0,0,\z) -- cycle; %
  \begin{scope}[transform canvas={shift={(\x/2,0,\z/2)}, rotate=45}]
    \fill[top color=green!30, bottom color=blue!30]
    (-\x,0,-\h) -- (\x,0,-\h) -- (\x,0,\h) -- (-\x,0,\h) -- cycle;
  \end{scope}
\end{scope}

Now, when I am trying to do the same for the other planes, it does not work, as it seems that rotate always rotates as usually in the 2-dimensional case (in my case around the Y axis, in the XZ plane). This is the code:

\begin{scope}
  \def \h{{0.5*sqrt(\x*\x + \y*\y)}}
  \clip (0,0,0) -- (\x,0,0) -- (\x,\y,0) -- (0,\y,0) -- cycle; %
  \begin{scope}[transform canvas={shift={(\x/2,\y/2,0)}, rotate=-45}]
    \fill[top color=blue!30, bottom color=red!30]
    (-\x,-\h,0) -- (\x,-\h,0) -- (\x,\h,0) -- (-\x,\h,0) -- cycle;
  \end{scope}
\end{scope}

And the result: rotate in XY plane

So, my question is whether it is possible and if yes, then how to tell Tikz to rotate around an arbitrary axis? Or in my case, in the XY and YZ planes?

A solution with fading which does not require rotating would be also fine.

In the end, I guess I could translate everything to 2d and get what I want, but may be there is a cleaner solution to this.

share|improve this question

1 Answer 1

In my opinion, you are using a too powerful tool for a relatively simpler task. The canvas transformations simply don't care about any other settings like bounding boxes or any other high level constraints. They just happen. Instead, you can modify the default vertical shadings such that they obey the shading angle option. I've randomly rotated the shading below with 45, 120, and -45 degrees hoping that it was the reason for the question :)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
\tikzoption{top color}{%
  \pgfutil@colorlet{tikz@axis@top}{#1}%
  \pgfutil@colorlet{tikz@axis@middle}{tikz@axis@top!50!tikz@axis@bottom}%
  \def\tikz@shading{axis}\tikz@addmode{\tikz@mode@shadetrue}}
\tikzoption{bottom color}{%
  \pgfutil@colorlet{tikz@axis@bottom}{#1}%
  \pgfutil@colorlet{tikz@axis@middle}{tikz@axis@top!50!tikz@axis@bottom}%
  \def\tikz@shading{axis}\tikz@addmode{\tikz@mode@shadetrue}}
\tikzoption{middle color}{%
  \pgfutil@colorlet{tikz@axis@middle}{#1}%
  \def\tikz@shading{axis}\tikz@addmode{\tikz@mode@shadetrue}}
\makeatother


%: isometric  South West (-150): Y , East : X , North : Z
\tikzset{isometricYXZ/.style={x={(1cm,0cm)}, y={(-1.299cm,-0.75cm)}, z={(0cm,1cm)}}}

\begin{document}
 \begin{tikzpicture}[inner sep=0.2cm]
  \def \radi{3}
  \def \x{2}
  \def \y{2}
  \def \z{2}

  \begin{scope}[isometricYXZ]
   % the grid
   \begin{scope}[color=gray!50, thin]
    \foreach \xi in {0,...,\radi}{ \draw (\xi,\radi,0) -- (\xi,0,0) -- (\xi,0,\radi); }%
    \foreach \yi in {1,...,\radi}{ \draw (0,\yi,\radi) -- (0,\yi,0) -- (\radi,\yi,0); }%
    \foreach \zi in {0,...,\radi}{ \draw (0,\radi,\zi) -- (0,0,\zi) -- (\radi,0,\zi); }%
   \end{scope}

   \draw[-latex, ultra thick, color=blue] (0,0,0) -- (4,0,0) node[anchor=west] {X};%
   \draw[-latex, ultra thick, color=red] (0,0,0) -- (0,4,0) node[anchor=north] {Y};%
   \draw[-latex, ultra thick, color=green] (0,0,0) -- (0,0,4) node[anchor=east] {Z};%

   \fill[shading angle=45, top color=green!30, bottom color=blue!30] (0,0,0) -- (\x,0,0) -- (\x,\y,0) -- (0,\y,0) -- cycle; %
   \fill[shading angle=-45, top color=green!30, bottom color=blue!30] (0,0,0) -- (0,0,\z) -- (0,\y,\z) -- (0,\y,0) -- cycle; %
   \fill[shading angle=120, top color=green!30, bottom color=blue!30] (0,0,0) -- (\x,0,0) -- (\x,0,\z) -- (0,0,\z) -- cycle;

   \draw[color=gray, thick]%
   (0,\y,\z) -- (\x,\y,\z) -- (\x,\y,0) (\x,\y,\z) -- (\x,0,\z);%
  \end{scope}

  \shade[ball color=yellow] ($\y*(-1.299cm,-0.75cm)+(\x,\z)$) circle (0.1);%
 \end{tikzpicture}
\end{document}

enter image description here

I guess the reason for the shading angle disabled (set to zero) originally is to get the other transformations invalid at the time of shading declaration. You can make these changes local if you have other TikZ pictures that use these options.

share|improve this answer
    
Thanks! it works! What I actually needed was this shading: \fill[shading angle=45, top color=green!30, bottom color=blue!30] (0,0,0) -- (\x,0,0) -- (\x,0,\z) -- (0,0,\z) -- cycle; \fill[shading angle=-60, top color=blue!30, bottom color=red!30] (0,0,0) -- (\x,0,0) -- (\x,\y,0) -- (0,\y,0) -- cycle; \fill[shading angle=-30, top color=green!30, bottom color=red!30] (0,0,0) -- (0,0,\z) -- (0,\y,\z) -- (0,\y,0) -- cycle; But why when I try to make opacity=0.3, the effect is not something transparent, but something dark? Is it because of the shading? Should one use fading here? –  Elena Jul 8 '13 at 7:49
    
It would still be nice to know how to rotate in a given plane, let's say a triangle drawn in the XY plane. –  Elena Jul 8 '13 at 8:17
    
@Elena I can't replicate that writelatex.com/219094gjxmfg . Also I don't see any reason why it should be like that. Does it change if you add fill=yellow (maybe the black is still creeping up)? For rotation, I'll look into it later when I have some time. –  percusse Jul 8 '13 at 9:04
    
why not? it's getting dark (also transparent). In the end I am using fadings: \begin{scope}[opacity=0.3]\draw[draw=none] [postaction={path fading=south,fading angle=45,fill=mygreen}] [postaction={path fading=north,fading angle=45,fill=myblue}] (0,0,0) -- (\x,0,0) -- (\x,0,\z) -- (0,0,\z) -- cycle; \end{scope} See the difference on writelatex –  Elena Jul 8 '13 at 12:10
    
@Elena It might be so. I'm colorblind and I think it's an issue here :) –  percusse Jul 8 '13 at 12:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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