3

I'm trying to draw a light cone diagram and would like for a time axis and a spatial axis to be overlaid over the top of the diagram I already have. I'd also like to add directional arrows on both diagonals of each cone but am aware that the code for the axes could be easily re-purposed to achieve this.

This is my code so far but I'm aware that there is a lack in my understanding of how to draw multiple shapes together. Whenever I alter the axis, it alters the positioning of the bottom cone, which I cannot figure out how to avoid. Here's the code I've been using so far, any insights would be much appreciated:

    \documentclass{article}
    \usepackage{tikz}
    \usepackage{tikz-3dplot}
    \begin{document}
    \tdplotsetmaincoords{70}{130}
    \begin{center}
    \begin{tikzpicture}

    %Cone data
    \pgfmathsetmacro{\radiush}{2};%Cone base radius
    \pgfmathsetmacro{\theight}{-5}%Cone height (negative if you want a inverse cone)
    \pgfmathsetmacro{\cheightp}{.4}%Cut height in percent of cone height

    %Calculating coordinates
    \coordinate (center) at (0,0);
    \pgfmathsetmacro{\radiusv}{.2 * \radiush};
    \pgfmathsetmacro{\sradiush}{\radiush * (1 - \cheightp)};%only for right circular cone
    \pgfmathsetmacro{\sradiusv}{.2 * \sradiush};
    \coordinate (peak) at ($(center) + (0,\theight)$);
    \coordinate (vert1) at ($(center)+(\radiush,0)$);
    \coordinate (vert2) at ($(center)-(\radiush,0)$);
    \coordinate (svert1) at ($(vert1)!\cheightp!(peak)$);
    \coordinate (svert2) at ($(vert2)!\cheightp!(peak)$);

    %Drawing    
    \fill[left color=blue!30,middle color=blue!10, right    color=blue!30,shading=axis,draw=black] (svert1) -- (peak) -- (svert2) arc  (-180:360:\sradiush cm and \sradiusv cm);

    %Lines, \h in percent of cone height
    \foreach \h in {.5,.6,.7,.8}{
        \pgfmathsetmacro{\rh}{\radiush * (1 - \h)}
        \pgfmathsetmacro{\rv}{.2 * \rh}
        \draw[black!70,densely dashed] ($(vert2)!\h!(peak)$) arc (180:360:\rh cm and \rv cm);
    }

    %\fill[inner color=gray!30,outer color=gray!50,shading=radial] (0,0) circle (\radiush cm and \radiusv cm);


    \end{tikzpicture}
    \begin{tikzpicture}
    %Cone data
    \pgfmathsetmacro{\radiush}{2};%Cone base radius
    \pgfmathsetmacro{\theight}{5}%Cone height (negative if you want a inverse cone)
    \pgfmathsetmacro{\cheightp}{.4}%Cut height in percent of cone height

    %Calculating coordinates
    \coordinate (center) at (0,0);
    \pgfmathsetmacro{\radiusv}{.2 * \radiush};
    \pgfmathsetmacro{\sradiush}{\radiush * (1 - \cheightp)};%only for right circular cone
    \pgfmathsetmacro{\sradiusv}{.2 * \sradiush};
    \coordinate (peak) at ($(center) + (0,\theight)$);
    \coordinate (vert1) at ($(center)+(\radiush,0)$);
    \coordinate (vert2) at ($(center)-(\radiush,0)$);
    \coordinate (svert1) at ($(vert1)!\cheightp!(peak)$);
    \coordinate (svert2) at ($(vert2)!\cheightp!(peak)$);

    %Drawing    
    \fill[left color=red!70,right color=red!50,middle color=red!40,shading=axis,draw=black] (svert1) -- (peak) -- (svert2) arc (-180:360:\sradiush cm and \sradiusv cm);
     %Lines, \h in percent of cone height
    \foreach \h in {.5,.6,.7,.8}{
        \pgfmathsetmacro{\rh}{\radiush * (1 - \h)}
        \pgfmathsetmacro{\rv}{.2 * \rh}
        \draw[black!70,densely dashed] ($(vert2)!\h!(peak)$) arc (180:360:\rh cm and \rv cm);
    }


    %\fill[inner color=gray!30,outer color=gray!50,shading=radial] (0,0) circle (\radiush cm and \radiusv cm);


    \end{tikzpicture}
    \end{center}
    %Drawing the time axis (directed upwards)
    \begin{center}
    \begin{tikzpicture}
    \draw[thick, ->] (15,0,0) -- (15,5,0) node[left] {$t$};
    \end{tikzpicture}
    \end{center}

    \end{document}
  • Please change your code to a complete MWE, i.e. something that starts with \documentclass and ends with \end{document} and contains the minimum amount of code to generate the problem that you're trying to solve. – JPi Mar 24 '17 at 13:36
2

Basically you need to put everything in the same tikzpicture I guess. I have no idea how you want to position those cones in relation to each other, but you can move them around relative to each other either by using a scope environment with yshift and/or xshift as optional parameters, as in the code below, or by just changing the position of the center coordinate of each cone. In that case you don't need the scopes.

Note that I changed the coordinates of the axis.

One way of adding a label at the base would be

\node at ($(vert2)!\cheightp!(peak) + (0.25*\radiush cm,0)$) {A};

Because it uses other macros and existing coordinates, the position of the label will be updated if you change any of those two parameters, or the center of the cone.

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{130}
\begin{center}
\begin{tikzpicture}

\begin{scope}[yshift=1cm]
%Cone data
\pgfmathsetmacro{\radiush}{2};%Cone base radius
\pgfmathsetmacro{\theight}{-5}%Cone height (negative if you want a inverse cone)
\pgfmathsetmacro{\cheightp}{.4}%Cut height in percent of cone height

%Calculating coordinates
\coordinate (center) at (0,0);
\pgfmathsetmacro{\radiusv}{.2 * \radiush};
\pgfmathsetmacro{\sradiush}{\radiush * (1 - \cheightp)};%only for right circular cone
\pgfmathsetmacro{\sradiusv}{.2 * \sradiush};
\coordinate (peak) at ($(center) + (0,\theight)$);
\coordinate (vert1) at ($(center)+(\radiush,0)$);
\coordinate (vert2) at ($(center)-(\radiush,0)$);
\coordinate (svert1) at ($(vert1)!\cheightp!(peak)$);
\coordinate (svert2) at ($(vert2)!\cheightp!(peak)$);

%Drawing    
\fill[left color=blue!30,middle color=blue!10, right    color=blue!30,shading=axis,draw=black] (svert1) -- (peak) -- (svert2) arc  (-180:360:\sradiush cm and \sradiusv cm);

%Lines, \h in percent of cone height
\foreach \h in {.5,.6,.7,.8}{
    \pgfmathsetmacro{\rh}{\radiush * (1 - \h)}
    \pgfmathsetmacro{\rv}{.2 * \rh}
    \draw[black!70,densely dashed] ($(vert2)!\h!(peak)$) arc (180:360:\rh cm and \rv cm);
}

\node at ($(vert2)!\cheightp!(peak) + (0.25*\radiush cm,0)$) {A};
\end{scope}
%\fill[inner color=gray!30,outer color=gray!50,shading=radial] (0,0) circle (\radiush cm and \radiusv cm);


\begin{scope}[yshift=-2cm]
%Cone data
\pgfmathsetmacro{\radiush}{2};%Cone base radius
\pgfmathsetmacro{\theight}{5}%Cone height (negative if you want a inverse cone)
\pgfmathsetmacro{\cheightp}{.4}%Cut height in percent of cone height

%Calculating coordinates
\coordinate (center) at (0,0);
\pgfmathsetmacro{\radiusv}{.2 * \radiush};
\pgfmathsetmacro{\sradiush}{\radiush * (1 - \cheightp)};%only for right circular cone
\pgfmathsetmacro{\sradiusv}{.2 * \sradiush};
\coordinate (peak) at ($(center) + (0,\theight)$);
\coordinate (vert1) at ($(center)+(\radiush,0)$);
\coordinate (vert2) at ($(center)-(\radiush,0)$);
\coordinate (svert1) at ($(vert1)!\cheightp!(peak)$);
\coordinate (svert2) at ($(vert2)!\cheightp!(peak)$);

%Drawing    
\fill[left color=red!70,right color=red!50,middle color=red!40,shading=axis,draw=black] (svert1) -- (peak) -- (svert2) arc (-180:360:\sradiush cm and \sradiusv cm);
 %Lines, \h in percent of cone height
\foreach \h in {.5,.6,.7,.8}{
    \pgfmathsetmacro{\rh}{\radiush * (1 - \h)}
    \pgfmathsetmacro{\rv}{.2 * \rh}
    \draw[black!70,densely dashed] ($(vert2)!\h!(peak)$) arc (180:360:\rh cm and \rv cm);
}

\node at ($(vert2)!\cheightp!(peak) + (0.25*\radiush cm,0)$) {B};
%\fill[inner color=gray!30,outer color=gray!50,shading=radial] (0,0) circle (\radiush cm and \radiusv cm);

\end{scope}

\draw[thick, ->] (0,-5,0) -- (0,5,0) node[left] {$t$};
\end{tikzpicture}
\end{center}

\end{document}

enter image description here

  • Fantastic, thank you very much that sorts it nicely! I'll play about with it an try and include the rest of the features on, how would you label the base of each cone? I was thinking that it might be better to attach labels to the shapes rather than points on the axis – djaf Mar 24 '17 at 14:58
  • @djaf I added one possible method for adding a label at the base. – Torbjørn T. Mar 24 '17 at 15:45
  • Much appreciated! – djaf Mar 24 '17 at 16:18
  • 1
    @djaf If my answer was sufficient, consider upvoting (clicking the uparrow next to the answer) and/or accepting it (by clicking the checkmark). Accepting an answer marks the question as solved. – Torbjørn T. Mar 25 '17 at 19:22

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.