12

I would like to make a 3d plot containing the 3d axis and a convex polyhedron or better a Dodecahedron

screenshot

on the positive side for which one of its boundary edge points on its top is annotated e.g. \hat{x} "chosen" or "selected" and draw a line segment from that labeled point towards the origin. Then also highlight and annotate where this line segment intersects with the convex hull of the Dodecahedron. Would this be a nightmare to do using TikZ?

btw what's the best way to learn TikZ once and for all? are there good books? I always end up consuming TikZ one way or another :(

UPDATE: actually I need several plots around this same idea to illustrate in detail the behavior of an algorithm I need to document. I hope that by seeing how it is done for this case I will be able to generalize and do the others by myself ... though knowing how difficult it TikZ ... :(

5

2 Answers 2

19
\documentclass{article}
\usepackage[dvipsnames]{pstricks}
\usepackage{pst-solides3d}
\begin{document}

\begin{pspicture}[solidmemory,fontsize=20](-4,-4)(4,4)
\psset{Decran=30,viewpoint=20 40 30 rtp2xyz, lightsrc=viewpoint}
\psSolid[object=dodecahedron,a=2.5,action=draw*,name=my_dodecahedron,
         fillcolor=green!50!white]
\psSolid[object=point,definition=solidgetsommet,
  args=my_dodecahedron 0,linecolor=blue,text=A,pos=uc,name=A]
\psSolid[object=point,definition=solidgetsommet,
  args=my_dodecahedron 4,linecolor=blue,text=B,pos=uc,name=B]
\psSolid[object=line,args=A B,linecolor=blue]
\psSolid[object=vecteur,args=A,linecolor=blue]
\psSolid[object=vecteur,args=B,linecolor=blue]
\axesIIID(2.5,2.5,2.5)(3.5,3,3)
\end{pspicture}
%
\begin{pspicture}[solidmemory,fontsize=20](-4,-4)(4,4)
\psset{Decran=30,viewpoint=20 40 35 rtp2xyz, lightsrc=viewpoint}
\psSolid[object=dodecahedron,a=2.5,action=draw*,RotX=22.5,RotY=22.5,
  fillcolor=red!50!white,name=my_dodecahedron,action=draw**,
%  numfaces=all,num=all,
]
\psSolid[object=point,definition=solidcentreface,
   args=my_dodecahedron 2,linecolor=white,text=Centre face 2,pos=uc]
\psSolid[object=point,definition=solidgetsommet,
  args=my_dodecahedron 0,linecolor=white,text=A,pos=cl,name=A]
\psSolid[object=point,definition=solidgetsommet,
  args=my_dodecahedron 4,linecolor=white,text=B,pos=cl,name=B]
\psSolid[object=line,args=A B,linecolor=white]
\end{pspicture}

\end{document}

enter image description here

3
  • nice :) but I can't do anything with a dodecahedron if I can not draw lines, annotate points and intersections etc. Can it not be done in TikZ using a similar "dodecahedron" command?
    – SkyWalker
    Aug 22, 2012 at 14:33
  • you can do anything with the dodecahedron itself or with lines ...
    – user2478
    Aug 22, 2012 at 15:18
  • ´Undefined control sequence. \psSolid´ is what Latex tells me when testing the code
    – InLaw
    Apr 2, 2022 at 16:00
15
+50

Here's a TikZ starting point, all vertices, edges and faces are definded independantly, so you can use them for further magic:

Code

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}

\begin{document}

% golden ratio and inverse golden ratio
\pgfmathsetmacro{\gr}{(1+sqrt(5))/2}
\pgfmathsetmacro{\igr}{2/(1+sqrt(5))}

%choose axis angles
\newcommand{\xangle}{0}
\newcommand{\yangle}{90}
\newcommand{\zangle}{225}

%choose axis lengths
\newcommand{\xlength}{1}
\newcommand{\ylength}{1}
\newcommand{\zlength}{0.5}

\pgfmathsetmacro{\xx}{\xlength*cos(\xangle)}
\pgfmathsetmacro{\xy}{\xlength*sin(\xangle)}
\pgfmathsetmacro{\yx}{\ylength*cos(\yangle)}
\pgfmathsetmacro{\yy}{\ylength*sin(\yangle)}
\pgfmathsetmacro{\zx}{\zlength*cos(\zangle)}
\pgfmathsetmacro{\zy}{\zlength*sin(\zangle)}

\begin{tikzpicture}
[   x={(\xx cm,\xy cm)},
    y={(\yx cm,\yy cm)},
    z={(\zx cm,\zy cm)},
    scale=2,
    every path/.style={thick}
]

% coordinates of the vertices (see wikipedia page)
    % vertices of inscribed cube
    \coordinate (pd1) at (-1,-1,-1);
    \coordinate (pd2) at (-1,-1,1);
    \coordinate (pd3) at (-1,1,-1);
    \coordinate (pd4) at (-1,1,1);
    \coordinate (pd5) at (1,-1,-1);
    \coordinate (pd6) at (1,-1,1);
    \coordinate (pd7) at (1,1,-1);
    \coordinate (pd8) at (1,1,1);
    % "front/back" "outside of cube" points
    \coordinate (pd9) at (0,-\igr,-\gr);
    \coordinate (pd10) at (0,-\igr,\gr);
    \coordinate (pd11) at (0,\igr,-\gr);
    \coordinate (pd12) at (0,\igr,\gr);
    % "top/bottom" "outside of cube" points
    \coordinate (pd13) at (-\igr,-\gr,0);
    \coordinate (pd14) at (-\igr,\gr,0);
    \coordinate (pd15) at (\igr,-\gr,0);
    \coordinate (pd16) at (\igr,\gr,0);
    % "left/right" "outside of cube" points
    \coordinate (pd17) at (-\gr,0,-\igr);
    \coordinate (pd18) at (-\gr,0,\igr);
    \coordinate (pd19) at (\gr,0,-\igr);
    \coordinate (pd20) at (\gr,0,\igr);

% black background rectangle for contrast (better option: backgrounds library)  
    \fill (-2.2,-2) rectangle (2.2,2);

% mark vertices 
    \foreach \x in {1,...,20}
    {   \fill[white] (pd\x) circle (0.03) node[above right] {\tiny\x};
    }

% draw inscribed cube
\draw[gray, densely dotted] (pd8) -- (pd7) -- (pd3) -- (pd4) -- cycle;
\draw[gray, densely dotted] (pd8) -- (pd6) -- (pd5) -- (pd7) -- cycle;
\draw[gray, densely dotted] (pd5) -- (pd6) -- (pd2) -- (pd1) -- cycle;
\draw[gray, densely dotted] (pd1) -- (pd2) -- (pd4) -- (pd3) -- cycle;

% faces; "back" ones gray, "front" ones red
    \fill[gray,fill opacity=0.2] (pd11) -- (pd9) -- (pd5) -- (pd19) -- (pd7) -- cycle;
    \fill[gray,fill opacity=0.2] (pd11) -- (pd9) -- (pd1) -- (pd17) -- (pd3) -- cycle;
    \fill[gray,fill opacity=0.2] (pd11) -- (pd7) -- (pd16) -- (pd14) -- (pd3) -- cycle;
    \fill[gray,fill opacity=0.2] (pd3) -- (pd14) -- (pd4) -- (pd18) -- (pd17) -- cycle;
    \fill[gray,fill opacity=0.2] (pd1) -- (pd9) -- (pd5) -- (pd15) -- (pd13) -- cycle;
    \fill[gray,fill opacity=0.2] (pd1) -- (pd13) -- (pd2) -- (pd18) -- (pd17) -- cycle;
    \fill[red,fill opacity=0.2] (pd14) -- (pd16) -- (pd8) -- (pd12) -- (pd4) -- cycle;
    \fill[red,fill opacity=0.2] (pd8) -- (pd16) -- (pd7) -- (pd19) -- (pd20) -- cycle;
    \fill[red,fill opacity=0.2] (pd20) -- (pd19) -- (pd5) -- (pd15) -- (pd6) -- cycle;
    \fill[red,fill opacity=0.2] (pd12) -- (pd8) -- (pd20) -- (pd6) -- (pd10) -- cycle;
    \fill[red,fill opacity=0.2] (pd10) -- (pd6) -- (pd15) -- (pd13) -- (pd2) -- cycle;
    \fill[red,fill opacity=0.2] (pd12) -- (pd10) -- (pd2) -- (pd18) -- (pd4) -- cycle;

% edges on "back"    face of inscribes cube
    \draw[red] (pd9) -- (pd11);
    \draw[red] (pd11) -- (pd3);
    \draw[red] (pd11) -- (pd7);
    \draw[red] (pd9) -- (pd1);
    \draw[red] (pd9) -- (pd5);
% edges on "top"     face of inscribes cube
    \draw[blue] (pd14) -- (pd16);
    \draw[blue] (pd16) -- (pd8);
    \draw[blue] (pd16) -- (pd7);
    \draw[blue] (pd14) -- (pd3);
    \draw[blue] (pd14) -- (pd4);
% edges on "left"    face of inscribes cube
    \draw[green] (pd17) -- (pd18);
    \draw[green] (pd17) -- (pd3);
    \draw[green] (pd17) -- (pd1);
    \draw[green] (pd18) -- (pd2);
    \draw[green] (pd18) -- (pd4);
% edges on "bottom"  face of inscribes cube
    \draw[yellow] (pd13) -- (pd15);
    \draw[yellow] (pd13) -- (pd1);
    \draw[yellow] (pd13) -- (pd2);
    \draw[yellow] (pd15) -- (pd5);
    \draw[yellow] (pd15) -- (pd6);
% edges on "front"   face of inscribes cube
    \draw[violet] (pd10) -- (pd12);
    \draw[violet] (pd12) -- (pd4);
    \draw[violet] (pd12) -- (pd8);
    \draw[violet] (pd10) -- (pd2);
    \draw[violet] (pd10) -- (pd6);
% edges on "right"   face of inscribes cube 
    \draw[orange] (pd20) -- (pd19); 
    \draw[orange] (pd19) -- (pd7);
    \draw[orange] (pd19) -- (pd5);
    \draw[orange] (pd20) -- (pd8);
    \draw[orange] (pd20) -- (pd6);
\end{tikzpicture}

\end{document}

Result

enter image description here


Edit 1: There are several problems doing this in TikZ, as also 3D points are internally stored at 2d points. Furthermore you can't automatically find hidden lines, so you have to do it yourself. With the problem you described there would be the problem to know through which of the 12 surfaces the connecting line is going, so I chose one where thats easy to see. The macro I wrote for detemining the intersection only works if your line is passing through the origin.

Code

\documentclass[tikz]{standalone}
\usepackage{xifthen}

\begin{document}

%command to find intersection of plane through abc and line p (through origin)
\newcommand{\planelineinter}[5]% a, b, c, p as {a_x,a_y,a_z}, coordinate name
{   \foreach \a [count=\k] in {#1}
    { \ifthenelse{\k=1}{\xdef\tempxa{\a}}
        \ifthenelse{\k=2}{\xdef\tempya{\a}}
        \ifthenelse{\k=3}{\xdef\tempza{\a}}
    }
    \foreach \b [count=\k] in {#2}
    { \ifthenelse{\k=1}{\xdef\tempxb{\b}}
        \ifthenelse{\k=2}{\xdef\tempyb{\b}}
        \ifthenelse{\k=3}{\xdef\tempzb{\b}}
    }
    \foreach \c [count=\k] in {#3}
    { \ifthenelse{\k=1}{\xdef\tempxc{\c}}
        \ifthenelse{\k=2}{\xdef\tempyc{\c}}
        \ifthenelse{\k=3}{\xdef\tempzc{\c}}
    }
    \foreach \p [count=\k] in {#4}
    { \ifthenelse{\k=1}{\xdef\tempxp{\p}}
        \ifthenelse{\k=2}{\xdef\tempyp{\p}}
        \ifthenelse{\k=3}{\xdef\tempzp{\p}}
    }
    \pgfmathsetmacro{\abx}{\tempxb-\tempxa}
    \pgfmathsetmacro{\aby}{\tempyb-\tempya}
    \pgfmathsetmacro{\abz}{\tempzb-\tempza}
    \pgfmathsetmacro{\acx}{\tempxc-\tempxa}
    \pgfmathsetmacro{\acy}{\tempyc-\tempya}
    \pgfmathsetmacro{\acz}{\tempzc-\tempza}
    \pgfmathsetmacro{\nx}{\aby*\acz-\abz*\acy}
    \pgfmathsetmacro{\ny}{\abz*\acx-\abx*\acz}
    \pgfmathsetmacro{\nz}{\abx*\acy-\aby*\acx}
    \pgfmathsetmacro{\d}{(\nx+\ny+\nz)/(\nx*\tempxp+\ny*\tempyp+\nz*\tempzp)}
    \path (0,0,0) -- (#4) coordinate[pos=\d] (#5);
}

% golden ratio and inverse golden ratio
\pgfmathsetmacro{\gr}{(1+sqrt(5))/2}
\pgfmathsetmacro{\igr}{2/(1+sqrt(5))}

%choose axis angles
\newcommand{\xangle}{0}
\newcommand{\yangle}{90}
\newcommand{\zangle}{225}

%choose axis lengths
\newcommand{\xlength}{1}
\newcommand{\ylength}{1}
\newcommand{\zlength}{0.5}

\pgfmathsetmacro{\xx}{\xlength*cos(\xangle)}
\pgfmathsetmacro{\xy}{\xlength*sin(\xangle)}
\pgfmathsetmacro{\yx}{\ylength*cos(\yangle)}
\pgfmathsetmacro{\yy}{\ylength*sin(\yangle)}
\pgfmathsetmacro{\zx}{\zlength*cos(\zangle)}
\pgfmathsetmacro{\zy}{\zlength*sin(\zangle)}

\begin{tikzpicture}
[   x={(\xx cm,\xy cm)},
  y={(\yx cm,\yy cm)},
  z={(\zx cm,\zy cm)},
  scale=2,
  every path/.style={thick}
]

% coordinates of the vertices (see wikipedia page)
    \node[below left] at (0,0,0) {$\vec{0}$};
    \fill (0,0,0) circle (0.03);
    % vertices of inscribed cube
    \coordinate (pd1) at (-1,-1,-1);
    \coordinate (pd2) at (-1,-1,1);
    \coordinate (pd3) at (-1,1,-1);
    \coordinate (pd4) at (-1,1,1);
    \coordinate (pd5) at (1,-1,-1);
    \coordinate (pd6) at (1,-1,1);
    \coordinate (pd7) at (1,1,-1);
    \coordinate (pd8) at (1,1,1);
    % "front/back" "outside of cube" points
    \coordinate (pd9) at (0,-\igr,-\gr);
    \coordinate (pd10) at (0,-\igr,\gr);
    \coordinate (pd11) at (0,\igr,-\gr);
    \coordinate (pd12) at (0,\igr,\gr);
    % "top/bottom" "outside of cube" points
    \coordinate (pd13) at (-\igr,-\gr,0);
    \coordinate (pd14) at (-\igr,\gr,0);
    \coordinate (pd15) at (\igr,-\gr,0);
    \coordinate (pd16) at (\igr,\gr,0);
    % "left/right" "outside of cube" points
    \coordinate (pd17) at (-\gr,0,-\igr);
    \coordinate (pd18) at (-\gr,0,\igr);
    \coordinate (pd19) at (\gr,0,-\igr);
    \coordinate (pd20) at (\gr,0,\igr);

% ========== the point of interest, part 1
    \coordinate (x) at (4,3,0);
    \planelineinter{1,1,-1}{1,1,1}{\igr,\gr,0}{4,3,0}{interpoint}
    \draw[very thick,red,densely dashed] (0,0) -- (interpoint);

% faces; "back" ones gray, "front" ones red
    \fill[gray,fill opacity=0.4] (pd11) -- (pd9) -- (pd5) -- (pd19) -- (pd7) -- cycle;
    \fill[gray,fill opacity=0.4] (pd11) -- (pd9) -- (pd1) -- (pd17) -- (pd3) -- cycle;
    \fill[gray,fill opacity=0.4] (pd11) -- (pd7) -- (pd16) -- (pd14) -- (pd3) -- cycle;
    \fill[gray,fill opacity=0.4] (pd3) -- (pd14) -- (pd4) -- (pd18) -- (pd17) -- cycle;
    \fill[gray,fill opacity=0.4] (pd1) -- (pd9) -- (pd5) -- (pd15) -- (pd13) -- cycle;
    \fill[gray,fill opacity=0.4] (pd1) -- (pd13) -- (pd2) -- (pd18) -- (pd17) -- cycle;

    \fill[gray,fill opacity=0.4] (pd14) -- (pd16) -- (pd8) -- (pd12) -- (pd4) -- cycle;
    \fill[lime,fill opacity=0.4] (pd8) -- (pd16) -- (pd7) -- (pd19) -- (pd20) -- cycle;
    \fill[gray,fill opacity=0.4] (pd20) -- (pd19) -- (pd5) -- (pd15) -- (pd6) -- cycle;
    \fill[gray,fill opacity=0.4] (pd12) -- (pd8) -- (pd20) -- (pd6) -- (pd10) -- cycle;
    \fill[gray,fill opacity=0.4] (pd10) -- (pd6) -- (pd15) -- (pd13) -- (pd2) -- cycle;
    \fill[gray,fill opacity=0.4] (pd12) -- (pd10) -- (pd2) -- (pd18) -- (pd4) -- cycle;

% edges on "back"    face of inscribes cube; red
    \draw[dashed] (pd9) -- (pd11);
    \draw[dashed] (pd11) -- (pd3);
    \draw[dashed] (pd11) -- (pd7);
    \draw[dashed] (pd9) -- (pd1);
    \draw[dashed] (pd9) -- (pd5);
% edges on "top"     face of inscribes cube
    \draw[] (pd14) -- (pd16);
    \draw[] (pd16) -- (pd8);
    \draw[] (pd16) -- (pd7);
    \draw[dashed] (pd14) -- (pd3);
    \draw[] (pd14) -- (pd4);
% edges on "left"    face of inscribes cube
    \draw[dashed] (pd17) -- (pd18);
    \draw[dashed] (pd17) -- (pd3);
    \draw[dashed] (pd17) -- (pd1);
    \draw[] (pd18) -- (pd2);
    \draw[] (pd18) -- (pd4);
% edges on "bottom"  face of inscribes cube
    \draw[] (pd13) -- (pd15);
    \draw[dashed] (pd13) -- (pd1);
    \draw[] (pd13) -- (pd2);
    \draw[] (pd15) -- (pd5);
    \draw[] (pd15) -- (pd6);
% edges on "front"   face of inscribes cube
    \draw[] (pd10) -- (pd12);
    \draw[] (pd12) -- (pd4);
    \draw[] (pd12) -- (pd8);
    \draw[] (pd10) -- (pd2);
    \draw[] (pd10) -- (pd6);
% edges on "right"   face of inscribes cube 
    \draw[] (pd20) -- (pd19);   
    \draw[] (pd19) -- (pd7);
    \draw[] (pd19) -- (pd5);
    \draw[] (pd20) -- (pd8);
    \draw[] (pd20) -- (pd6);    

% ========== the point of interest, part 2
    \draw[very thick,red] (interpoint) -- (x);
    \fill[blue] (x) circle (0.03) node[above] {$\mathbf{\hat{x}}$};
    \fill[blue] (interpoint) circle (0.03) node[above,fill,white,rounded corners=1mm,fill opacity=0.5,text opacity=1,text=black,above left=1mm] {intersection point};
\end{tikzpicture}

\end{document}

Output

enter image description here

You must log in to answer this question.

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