44

I would like to draw an Octahedron using TikZ, I found nowhere to start, I tried drawing 6 points and then connecting them properly, but this method gives no 3D feel at all, this is my drawing:

\begin{tikzpicture}[scale=3]
\coordinate (A1) at (0,0);
\coordinate (A2) at (0.6,0.2);
\coordinate (A3) at (1,0);
\coordinate (A4) at (0.4,-0.2);
\coordinate (B1) at (0.5,0.5);
\coordinate (B2) at (0.5,-0.5);

\draw[dashed] (A1) -- (A2) -- (A3);
\draw (A1) -- (A4) -- (A3);
\draw[dashed] (B1) -- (A2) -- (B2);
\draw (B1) -- (A4) -- (B2);
\draw (B1) -- (A1) -- (B2) -- (A3) --cycle;
\end{tikzpicture}

I wonder how can I add shading to each surface, and make each surface semi-transparent, also adjust the invisible edges' color lighter from the observer perspective, like the one on the wikipedia page: Octahedron on wikipedia page

So my question is: How to polish my TikZ drawing to make a polyhedron look like a 3D object? or is there a package other than TikZ could do that? Thanks

Shuhao Cao
  • 3,131
  • 3
  • 29
  • 33

10 Answers10

41

TikZ also has an xyz-coordinate system that is quite useful here. There's a nice answer making use of this feature: Table, i.e. the piece of furniture on which one eats, in Tikz

Here's a way of drawing your octahedron. To rotate it, play around with the x, y and z options of the tikzpicture:

\documentclass{article}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}[line join=bevel,z=-5.5]
\coordinate (A1) at (0,0,-1);
\coordinate (A2) at (-1,0,0);
\coordinate (A3) at (0,0,1);
\coordinate (A4) at (1,0,0);
\coordinate (B1) at (0,1,0);
\coordinate (C1) at (0,-1,0);

\draw (A1) -- (A2) -- (B1) -- cycle;
\draw (A4) -- (A1) -- (B1) -- cycle;
\draw (A1) -- (A2) -- (C1) -- cycle;
\draw (A4) -- (A1) -- (C1) -- cycle;
\draw [fill opacity=0.7,fill=green!80!blue] (A2) -- (A3) -- (B1) -- cycle;
\draw [fill opacity=0.7,fill=orange!80!black] (A3) -- (A4) -- (B1) -- cycle;
\draw [fill opacity=0.7,fill=green!30!black] (A2) -- (A3) -- (C1) -- cycle;
\draw [fill opacity=0.7,fill=purple!70!black] (A3) -- (A4) -- (C1) -- cycle;
\end{tikzpicture}

\end{document}

3D octahedron

Jake
  • 232,450
35

You can use the fill and opacity constructs:

\documentclass{article}
\usepackage{tikz}

\definecolor{cof}{RGB}{219,144,71}
\definecolor{pur}{RGB}{186,146,162}
\definecolor{greeo}{RGB}{91,173,69}
\definecolor{greet}{RGB}{52,111,72}

\begin{document}

\begin{tikzpicture}[thick,scale=5]
\coordinate (A1) at (0,0);
\coordinate (A2) at (0.6,0.2);
\coordinate (A3) at (1,0);
\coordinate (A4) at (0.4,-0.2);
\coordinate (B1) at (0.5,0.5);
\coordinate (B2) at (0.5,-0.5);

\begin{scope}[thick,dashed,,opacity=0.6]
\draw (A1) -- (A2) -- (A3);
\draw (B1) -- (A2) -- (B2);
\end{scope}
\draw[fill=cof,opacity=0.6] (A1) -- (A4) -- (B1);
\draw[fill=pur,opacity=0.6] (A1) -- (A4) -- (B2);
\draw[fill=greeo,opacity=0.6] (A3) -- (A4) -- (B1);
\draw[fill=greet,opacity=0.6] (A3) -- (A4) -- (B2);
\draw (B1) -- (A1) -- (B2) -- (A3) --cycle;
\end{tikzpicture}

\end{document}

diabonas
  • 25,784
Gonzalo Medina
  • 505,128
16

PSTricks can handle this one. Run it with xelatex or latex->dvips->ps2pdf

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

\begin{pspicture}(-2.5,-2)(2.5,2.5)
\psset{lightsrc=10 20 30,viewpoint=40 10 30 rtp2xyz,Decran=40}
 \psSolid[object=octahedron,a=3,linecolor=blue,
          opacity=0.6,hollow,hue=0 1,
          action=draw**]
% \axesIIID(3,3,3)(4,4,4)
\end{pspicture}

\end{document}

enter image description here

  • 1
    I'm trying to make 3D polyhedra and this is nicer than tikz-* for me because you don't need to manually specify the face order! (You specify the vertices, and for each face, its vertices in anticlockwise order relative to the exterior.) – daveagp Jun 03 '12 at 00:23
16

It think a solution with tikz-3dplot should not be missing here.

\documentclass{minimal}
\usepackage{tikz,tikz-3dplot}

\definecolor{cof}{RGB}{219,144,71}
\definecolor{pur}{RGB}{186,146,162}
\definecolor{greeo}{RGB}{91,173,69}
\definecolor{greet}{RGB}{52,111,72}

\tdplotsetmaincoords{70}{165}

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

%    \draw[thick,->] (0,0,0) -- (1,0,0) node[anchor=north east]{$x$};
%    \draw[thick,->] (0,0,0) -- (0,1,0) node[anchor=north west]{$y$};
%    \draw[thick,->] (0,0,0) -- (0,0,1) node[anchor=south]{$z$};

    \tdplotsetcoord{A}{1}{90}{0}    % cartesian (1,0,0)
    \tdplotsetcoord{B}{1}{90}{90}   % cartesian (0,1,0)
    \tdplotsetcoord{C}{1}{90}{180}  % cartesian (-1,0,0)
    \tdplotsetcoord{D}{1}{90}{270}  % cartesian (0,-1,0)
    \tdplotsetcoord{E}{1}{0}{0}     % cartesian (0,0,1)
    \tdplotsetcoord{F}{1}{180}{0}   % cartesian (0,0,-1)

    \draw (A) -- (B) -- (C);
    \draw (E) -- (A) -- (F);
    \draw (E) -- (B) -- (F);
    \draw (E) -- (C) -- (F);
    \draw[dashed] (C) -- (D) -- (A);
    \draw[dashed](E) -- (D) -- (F);
    \fill[cof,opacity=0.6](A) -- (B) -- (E) -- cycle;
    \fill[pur,opacity=0.6](A) -- (B) -- (F) -- cycle;
    \fill[greeo,opacity=0.6](B) -- (C) -- (E) -- cycle;
    \fill[greet,opacity=0.6](B) -- (C) -- (F) -- cycle;
  \end{tikzpicture}
\end{document}

enter image description here

  • \tdplotsetcoord{A}{1}{90}{0} % cartesian (1,0,0) is better spelt \coordinate (A) at (1, 0, 0) – Eric Nov 01 '19 at 13:25
8

To add another approach to the collection: The development version of pgfplots supports "patch plots", where the user supplies a collection of polygons to be plotted:

\documentclass{minimal}

\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{axis}[axis equal]
\addplot3[fill opacity=0.7,patch,table/row sep=\\,
patch table={
 0 1 4\\
 1 2 4\\
 2 3 4\\
 3 0 4\\
 0 1 5\\
 1 2 5\\
 2 3 5\\
 3 0 5\\
}]
table 
{
 -1 0 0\\
 0 -1 0\\
 1 0 0\\
 0 1 0\\
 0 0 1\\
 0 0 -1\\
};
\end{axis}
\end{tikzpicture}
\end{document}

pgfplots CVS patch plot

David Carlisle
  • 757,742
Jake
  • 232,450
7

With tkz-berge and some macros of TikZ but tkz-berge is not a perfect tool for this kind of picture. This is only to give some ideas.

%  based on the work of Andreas Menge with my package
\documentclass{scrartcl}
\usepackage[usenames,dvipsnames,pdftex]{xcolor} 
\usepackage{tkz-berge}
% add 3D view
\newcommand{\GlobalTransformation}[2]{%
\pgftransformcm{1}{0}{0.6}{0.2}{\pgfpoint{#1cm}{#2cm}}
}
% some colors from  Gonzalo Medina' answer
\definecolor{cof}{RGB}{219,144,71}
\definecolor{pur}{RGB}{186,146,162}
\definecolor{greeo}{RGB}{91,173,69}
\definecolor{greet}{RGB}{52,111,72}


\begin{document}
\pagestyle{empty}

\begin{tikzpicture}
  \GraphInit[vstyle=Art]
  \begin{scope}
    \GlobalTransformation{0}{0}
    \grEmptyCycle[prefix=a,RA=4]{4}
  \end{scope}
  \begin{scope}
    \GlobalTransformation{0}{-4}
    \Vertex{x}
  \end{scope}  
  \begin{scope}
    \GlobalTransformation{0}{4}
    \Vertex{y}
  \end{scope} 
  % add color to the faces
\fill[color=cof,opacity=0.6] (a2.center)--(y.center)--(a3.center)--cycle;
\fill[color=pur,opacity=0.6] (y.center)--(a3.center)--(a0.center)--cycle;
\fill[color=greeo,opacity=0.6] (x.center)--(a2.center)--(a3.center)--cycle;
\fill[color=greet,opacity=0.6] (x.center)--(a3.center)--(a0.center)--cycle; 
 \Edges(a0,y,a2,a3,a0,x,a2)  \Edges(y,a3,x,a2)
 % dashed edges  
 \tikzset{EdgeStyle/.append style={dashed}} 
 \Edges(y,a1,x)  \Edges(a0,a1,a2)   
% redraw some vertices
\foreach \n in {a0,a2,a3,x,y} {\Vertex[Node]{\n}}
\end{tikzpicture} 

\end{document} 

enter image description here

Alain Matthes
  • 95,075
6

I suggest you to give a look at Sketch program here:

http://www.frontiernet.net/~eugene.ressler/

It is a language based on C that permits you to create a simple 3D scene.

After the compilation it gives you a tex file where TikZ code is written.

The useful thing about it is that if you want to change the view point, it needs only to change the eye position and another compilation.

Azoun
  • 2,317
5

FYI: It is possible to use Sage to produce TikZ pictures of any 3-D polytope. See this ticket followed by this ticket. For documentations and examples, see the official reference of sage and the page of the author.

Here is an example code (from the author's webpage) generated by Sage. As you can see, the code can be customized as you want (semi-transparent, shading effect, etc.).

\begin{tikzpicture}%
    [x={(0.249656cm, -0.577639cm)},
    y={(0.777700cm, -0.358578cm)},
    z={(-0.576936cm, -0.733318cm)},
    scale=3.000000,
    back/.style={loosely dashed,line width=2pt},
    edge/.style={color=yellow, line width=2pt},
    facet/.style={fill=cyan,fill opacity=0.400000},
    vertex/.style={inner sep=4pt,star,star points=7,draw=blue!75!white,fill=blue!85!white,thick,anchor=base}]
%
%
%% Coordinate of the vertices:
%%
\coordinate (-0.500, -0.500, -0.500) at (-0.500, -0.500, -0.500);
\coordinate (-1.00, 0.000, 0.000) at (-1.00, 0.000, 0.000);
\coordinate (-1.00, 0.000, 1.00) at (-1.00, 0.000, 1.00);
\coordinate (-1.00, 1.00, 0.000) at (-1.00, 1.00, 0.000);
\coordinate (-1.00, 1.00, 1.00) at (-1.00, 1.00, 1.00);
\coordinate (0.000, -1.00, 0.000) at (0.000, -1.00, 0.000);
\coordinate (0.000, -1.00, 1.00) at (0.000, -1.00, 1.00);
\coordinate (0.000, 0.000, -1.00) at (0.000, 0.000, -1.00);
\coordinate (0.000, 1.00, -1.00) at (0.000, 1.00, -1.00);
\coordinate (1.00, -1.00, 0.000) at (1.00, -1.00, 0.000);
\coordinate (1.00, -1.00, 1.00) at (1.00, -1.00, 1.00);
\coordinate (1.00, 0.000, -1.00) at (1.00, 0.000, -1.00);
\coordinate (1.00, 1.00, -1.00) at (1.00, 1.00, -1.00);
\coordinate (1.00, 1.00, 1.00) at (1.00, 1.00, 1.00);
%%
%%
%% Drawing edges in the back
%%
\draw[edge,back] (0.000, -1.00, 0.000) -- (1.00, -1.00, 0.000);
\draw[edge,back] (0.000, 0.000, -1.00) -- (1.00, 0.000, -1.00);
\draw[edge,back] (1.00, -1.00, 0.000) -- (1.00, -1.00, 1.00);
\draw[edge,back] (1.00, -1.00, 0.000) -- (1.00, 0.000, -1.00);
\draw[edge,back] (1.00, 0.000, -1.00) -- (1.00, 1.00, -1.00);
%%
%%
%% Drawing vertices in the back
%%
\node[vertex] at (1.00, -1.00, 0.000)     {};
\node[vertex] at (1.00, 0.000, -1.00)     {};
%%
%%
%% Drawing the facets
%%
\fill[facet] (1.00, 1.00, 1.00) -- (-1.00, 1.00, 1.00) -- (-1.00, 1.00, 0.000) -- (0.000, 1.00, -1.00) -- (1.00, 1.00, -1.00) -- cycle {};
\fill[facet] (1.00, 1.00, 1.00) -- (-1.00, 1.00, 1.00) -- (-1.00, 0.000, 1.00) -- (0.000, -1.00, 1.00) -- (1.00, -1.00, 1.00) -- cycle {};
\fill[facet] (0.000, -1.00, 1.00) -- (-1.00, 0.000, 1.00) -- (-1.00, 0.000, 0.000) -- (-0.500, -0.500, -0.500) -- (0.000, -1.00, 0.000) -- cycle {};
\fill[facet] (0.000, 1.00, -1.00) -- (-1.00, 1.00, 0.000) -- (-1.00, 0.000, 0.000) -- (-0.500, -0.500, -0.500) -- (0.000, 0.000, -1.00) -- cycle {};
\fill[facet] (-1.00, 1.00, 1.00) -- (-1.00, 0.000, 1.00) -- (-1.00, 0.000, 0.000) -- (-1.00, 1.00, 0.000) -- cycle {};
%%
%%
%% Drawing edges in the front
%%
\draw[edge] (-0.500, -0.500, -0.500) -- (-1.00, 0.000, 0.000);
\draw[edge] (-0.500, -0.500, -0.500) -- (0.000, -1.00, 0.000);
\draw[edge] (-0.500, -0.500, -0.500) -- (0.000, 0.000, -1.00);
\draw[edge] (-1.00, 0.000, 0.000) -- (-1.00, 0.000, 1.00);
\draw[edge] (-1.00, 0.000, 0.000) -- (-1.00, 1.00, 0.000);
\draw[edge,->,orange] (-1.00, 0.000, 1.00) -- node[below left] {\color{white}FLOW} (-1.00, 1.00, 1.00);
\draw[edge] (-1.00, 0.000, 1.00) -- (0.000, -1.00, 1.00);
\draw[edge,->,orange] (-1.00, 1.00, 0.000) -- node[below right] {\color{white}TO THE} (-1.00, 1.00, 1.00);
\draw[edge] (-1.00, 1.00, 0.000) -- (0.000, 1.00, -1.00);
\draw[edge,<-,orange] (-1.00, 1.00, 1.00) -- node[above left] {\color{white}VERTEX}(1.00, 1.00, 1.00);
\draw[edge] (0.000, -1.00, 0.000) -- (0.000, -1.00, 1.00);
\draw[edge] (0.000, -1.00, 1.00) -- (1.00, -1.00, 1.00);
\draw[edge] (0.000, 0.000, -1.00) -- (0.000, 1.00, -1.00);
\draw[edge] (0.000, 1.00, -1.00) -- (1.00, 1.00, -1.00);
\draw[edge] (1.00, -1.00, 1.00) -- (1.00, 1.00, 1.00);
\draw[edge] (1.00, 1.00, -1.00) -- (1.00, 1.00, 1.00);
%%
%%
%% Drawing the vertices in the front
%%
\node[vertex] at (-0.500, -0.500, -0.500)     {$\alpha$};
\node[vertex] at (-1.00, 0.000, 0.000)     {};
\node[vertex] at (-1.00, 0.000, 1.00)     {};
\node[vertex] at (-1.00, 1.00, 0.000)     {};
\node at (-1.00, 1.00, 1.00)     {};
\node[vertex] at (0.000, -1.00, 0.000)     {};
\node[vertex] at (0.000, -1.00, 1.00)     {};
\node[vertex] at (0.000, 0.000, -1.00)     {};
\node[vertex] at (0.000, 1.00, -1.00)     {};
\node[vertex] at (1.00, -1.00, 1.00)     {};
\node[vertex,label=right:{$\Sigma\times\Omega$}] at (1.00, 1.00, -1.00)     {};
\node[vertex] at (1.00, 1.00, 1.00)     {\color{white}$\lim_{n\rightarrow \infty}$};
%%
%%
\end{tikzpicture}

And below is an example picture from the author's webpage:

a polytope

Hao Chen
  • 365
1

This should work.

\begin{tikzpicture}[scale=3]
\coordinate (A1) at (0,0);
\coordinate (A2) at (0.6,0.2);
\coordinate (A3) at (1,0);
\coordinate (A4) at (0.4,-0.2);
\coordinate (B1) at (0.5,0.5);
\coordinate (B2) at (0.5,-0.5);

\draw[dashed] (A1) -- (A2) -- (A3);
\draw[dashed] (B1) -- (A2) -- (B2);

\filldraw[fill=red,fill opacity=0.7] (B1)--(A4)--(A3)--cycle;
\filldraw[fill=green,fill opacity=0.7] (B1)--(A4)--(A1)--cycle;
\filldraw[fill=green!60!black,fill opacity=0.7] (B2)--(A4)--(A1)--cycle;
\filldraw[fill=purple,fill opacity=0.7] (B2)--(A4)--(A3)--cycle;
\end{tikzpicture}

You probably have to correct the colours.

ousakra
  • 11
0
\documentclass[oneside,tikz]{book}
\usepackage{tikz}
\usepackage{caption}
\usepackage{float}
\usepackage{graphicx}
\usetikzlibrary{calc}

\begin{document}
    \begin{figure}[H]
    \begin{center}
    \begin{tikzpicture}[line join=bevel,z=-5.5,scale=3]
    \coordinate (A1) at (0,0,-1);
    %\path(A1) node {A1};
    \coordinate (A2) at (-1,0,0);
    %\path(A2) node {A2};
    \coordinate (A3) at (0,0,1);
    %\path(A3) node {A3};
    \coordinate (A4) at (1,0,0);
    %\path(A4) node {A4};
    \coordinate (B1) at (0,1,0);
    %\path(B1) node {B1};
    \coordinate (C1) at (0,-1,0);
    %\path(C1) node {C1};
    \coordinate (X) at (0,0,0);
    %\path(X) node {X};
    \draw (A1) -- (A2) -- (B1) -- cycle;
    \draw (A4) -- (A1) -- (B1) -- cycle;
    \draw (A1) -- (A2) -- (C1) -- cycle;
    \draw (A4) -- (A1) -- (C1) -- cycle;
    \draw(A1) -- (A3);
    \draw(A2) -- (A4);
    \draw(B1) -- (C1);
    \draw [fill opacity=0.7,fill=green!80!blue] (A2) -- (A3) -- (B1) -- cycle;
    \draw [fill opacity=0.7,fill=green!70!black] (A2) -- (A3) -- (X) -- cycle;
    \draw [fill opacity=0.7,fill=orange!80!black] (A3) -- (A4) -- (B1) -- cycle;
    \draw [fill opacity=0.7,fill=orange!80!black] (X) -- (A4) -- (B1) -- cycle;
    \draw [fill opacity=0.7,fill=green!30!black] (A2) -- (A3) -- (C1) -- cycle;
    \draw [fill opacity=0.7,fill=purple!70!black] (A3) -- (A4) -- (C1) -- cycle;
    \draw [fill opacity=0.7,fill=purple!80!black] (A3) -- (X) -- (C1) -- cycle;
    \draw [fill opacity=0.9,fill=orange!60!black] (A3) -- (A4) -- (X) -- cycle;
    \end{tikzpicture}
    \caption{Radarreflector op een schip}
    \end{center}
    \end{figure}
\end{document}

I made a octahedron out of it. Like a radarreflector you see on a boat. I happen to need it in my course.

Marc VR
  • 61