2

I am trying to get this plot that contains 2 skewed cones with the center projected onto the xy plane:

enter image description here

This is what I have so far as per the solution given here:

\documentclass[tikz, border=3pt]{standalone}
\usepackage{tikz,tikz-3dplot}
\tdplotsetmaincoords{80}{45}
\tdplotsetrotatedcoords{-90}{180}{-90}

%% style for surfaces
\tikzset{surface/.style={draw=blue!70!black, fill=blue!40!white, fill opacity=.6}}

%% macros to draw back and front of cones
%% optional first argument is styling; others are z, radius, side offset (in degrees)
\newcommand{\coneback}[4][]{
  %% start at the correct point on the circle, draw the arc, then draw to the origin of the diagram, then close the path
  \draw[canvas is xy plane at z=#2, #1] (45-#4:#3) arc (45-#4:225+#4:#3) -- (O) --cycle;
  }
\newcommand{\conefront}[4][]{
  \draw[canvas is xy plane at z=#2, #1] (45-#4:#3) arc (45-#4:-135+#4:#3) -- (O) --cycle;
  }

\begin{document}
\begin{tikzpicture}[tdplot_main_coords]
  \coordinate (O) at (0,0,0);

  %% make sure to draw everything from back to front
  %\coneback[surface]{-1.5}{2.5}{-15}
\coneback[surface]{-3}{2}{-10}
\draw (0,0,-5) -- (O);
\conefront[surface]{-3}{2}{-10}

\coneback[surface]{3}{-2}{-10}
\conefront[surface]{3}{-2}{-10}

\end{tikzpicture}

\end{document}

UPDATE

From the first solution given below, this is the output that I got when I used XeLaTeX to compile:

enter image description here

Am I missing some settings on my machine that is causing me to obtain this output? Thanks!

Joe
  • 9,080
  • The issue is that you are using an outdated TeX installation, in which the xy plane has a bug. You can either use the patch from here or, what will be much better, update your LaTeX installation. The more so since the older versions have also some problems with xelatex and shadows.blur. Let me also mention that I am not a fan of unaccepting answers to make the OP, who has spent time and efforts to help you, address additional requests. –  Oct 17 '19 at 02:09
  • 1
    Sincerest apologies for unaccepting of your answer. I did that just to catch your attention. It will not happen in the future. Thanks again! – Joe Oct 17 '19 at 14:03

1 Answers1

4

This may be a start. The points at which the boundaries of the mantle attach to the base circle are computed numerically in a loop.

\documentclass[tikz, border=3pt]{standalone}
\usepackage{tikz,tikz-3dplot}
\usetikzlibrary{shadows.blur}
\newcounter{iloop}
\begin{document}
\tdplotsetmaincoords{70}{20}
\begin{tikzpicture}[tdplot_main_coords,font=\sffamily]
  \draw[thick,-stealth] (0,0,0) coordinate(O) -- (4,0,0) coordinate (X) 
   node[pos=0.7,below] {$X$}
  -- (4,4,0) coordinate(XY) -- (0,4,0) coordinate (Y) -- (O)
  node[pos=0.3,left] {$Y$} -- (0,0,4)
  coordinate (Z) node[pos=0.7,left]{Time};
  \path (2.2,2.2,3) coordinate (T) (1.8,1.8,1) coordinate (B) (2,2,0) coordinate
  (C);
  \begin{scope}[shift={(2,2,2)}]
   \tdplotsetrotatedcoords{0}{-10}{0}
   \begin{scope}[tdplot_rotated_coords,canvas is xy plane at z=0]
     \path[fill=gray!30,blur shadow={shadow blur steps=10,shadow xshift=0ex,
        shadow yshift=0ex,shadow blur radius=1.5ex}] (C)
        circle[radius=1cm-0.75ex];
     \pgfmathsetmacro{\maxT}{-90}\pgfmathsetmacro{\maxTT}{-90}
     \pgfmathsetmacro{\minT}{90}\pgfmathsetmacro{\minTT}{-90}
     \pgfmathsetmacro{\maxB}{-90}\pgfmathsetmacro{\maxBB}{-90}
     \pgfmathsetmacro{\minB}{90}\pgfmathsetmacro{\minBB}{-90}
     \setcounter{iloop}{0}
     \loop\stepcounter{iloop}
     \path let \p1=($(T)-(\number\value{iloop}:1)$),\n1={atan2(\y1,\x1)},
      \p2=($(B)-(\number\value{iloop}:1)$),\n2={atan2(\y2,\x2)} in 
      \pgfextra{\ifdim\n1>\maxT pt
       \pgfmathsetmacro{\maxT}{\n1}\xdef\maxT{\maxT}
       \pgfmathsetmacro{\maxTT}{\number\value{iloop}}\xdef\maxTT{\maxTT}
       \fi
       \ifdim\n1<\minT pt
       \pgfmathsetmacro{\minT}{\n1}\xdef\minT{\minT}
       \pgfmathsetmacro{\minTT}{\number\value{iloop}}\xdef\minTT{\minTT}
       \fi
       \ifdim\n2>\maxB pt
       \pgfmathsetmacro{\maxB}{\n2}\xdef\maxB{\maxB}
       \pgfmathsetmacro{\maxBB}{\number\value{iloop}}\xdef\maxBB{\maxBB}
       \fi
       \ifdim\n2<\minB pt
       \pgfmathsetmacro{\minB}{\n2}\xdef\minB{\minB}
       \pgfmathsetmacro{\minBB}{\number\value{iloop}}\xdef\minBB{\minBB}
       \fi};
     \ifnum\value{iloop}<360\repeat  
     \draw[thick,left color=blue!60,right color=blue!60,middle color=blue,
        shading angle=180-\minBB/2-\maxBB/2,fill opacity=0.6] (\minBB:1) -- (B) -- (\maxBB:1) 
        arc(\maxBB:\minBB:1);
     \draw[thick,fill=gray!60] circle[radius=1cm];
     \draw[thick,left color=blue!60,right color=blue!60,middle color=blue!20,
        shading angle=180-\minTT/2-\maxTT/2,fill opacity=0.6] (\minTT:1) -- (T) -- (\maxTT:1) arc(\maxTT-360:\minTT:1);
   \end{scope}
  \end{scope}  
\end{tikzpicture}
\end{document}

enter image description here

  • Hello, I compiled your code and got the output shown in my update above. I use XeLaTeX to compile. Is there something that I am missing? Thanks! – Joe Oct 17 '19 at 01:57