# Same shading for the patches in the same plane

I have the following polyhedron figure:

\documentclass{article}

\usepackage{pgfplots}
\pgfplotsset{compat=1.16}

\usepgfplotslibrary{patchplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}[view/h=210,xlabel=$a_1$,ylabel=$a_2$,zlabel=$a_3$,colormap/blackwhite]
opacity=0.3,
table/row sep=\\,
patch,
patch type=polygon,
vertex count=3,
patch table with point meta={%
% pt1 pt2 pt3 pt4 pt5 cdata
0   4   7   0 \\
7   8   1   7 \\
6   4   2   6 \\
4   0   2   4 \\
8   7   6   8 \\
7   4   6   7 \\
0   1   2   0 \\
0   7   1   0 \\
1   8   2   1 \\
8   6   2   8 \\
}
]

table {
x y z\\
0   0   0\\ %0
0   0   0.285957\\ %1
0   0.285957    0.285957\\ %2
0   0.3812378724    0.1906189362\\ %3
0   0.571914    0\\ %4
0.1906761276    0.3812378724    0.1906189362\\ %5
0.285957    0.285957    0.285957\\ %6
0.571914    0   0\\ %7
0.571914    0   0.285957\\ %8
};

\end{axis}
\end{tikzpicture}
\end{document}

which gives this picture,

because my patches are triangles and not polygons of more sides.

I should provide a script with the polygons that form each side of the figure to get the same shading on each side, making a figure like this:

Since I only have triangles and, besides, I do not know what triangles are in the same plane, is there any way to shade the patch triangles included in the same face of the polyhedron?.

ANNEX: Mathematica notebook to get the patch table of the solution provided below

> H2 = Import["convex2.dat"]
{{0, 0, 0}, {0, 0, 0.285957}, {0, 0.285957, 0.285957}, {0, 0.381238,
0.190619}, {0, 0.571914, 0}, {0.190676, 0.381238,
0.190619}, {0.285957, 0.285957, 0.285957}, {0.571914, 0,
0}, {0.571914, 0, 0.285957}}

H2 are the coordinates of the {x, y, z} points of the convex hull. We can plot the convex hull as following:

ConvexHullMesh[H2, Axes -> True, AxesLabel -> {a1, a2, a3},
Boxed -> False, ViewPoint -> {60, 100, 100},
MeshCellStyle -> Opacity[0.2, Orange]
]

which give a 3D shape like the above plots. We now process this plot to get the list of triangles on each side of the convex hull and their shades to use these data in Tick - pgf

R = ConvexHullMesh[H2];
lookuptable =
Flatten[Nearest[H2 -> Automatic, MeshCoordinates[R]]]];

faces = Partition[
Lookup[lookuptable,
Flatten[MeshCells[R, 2, "Multicells" -> True][[1, 1]]]], 3];
closedfaces = Join[faces, faces[[All, {1}]], 2] - 1;

lsttriangles = {};
Do[x = H2[[closedfaces[[i, 1]] + 1]] - H2[[closedfaces[[i, 2]] + 1]];
y = H2[[closedfaces[[i, 1]] + 1]] - H2[[closedfaces[[i, 3]] + 1]];
z = Cross[x, y];
AppendTo[lsttriangles,
Join[Take[closedfaces[[i]], 3], {Abs[z.{1, 2, 3}/Sqrt[z.z]]}]], {i,
1, Length[closedfaces]}];

To form the patch table with point meta of the Tikz figure.

TableForm[lsttriangles]

0   4   7   3.
8   7   5   2.12132
4   0   2   1.
7   8   1   2.
4   2   6   3.53553
0   7   1   2.
0   1   2   1.
7   4   5   2.12132
2   1   6   3.
1   8   6   3.
4   6   5   2.12132
6   8   5   2.12132

I believe it will be possible but nontrivial to shade the surfaces according to their normal vectors. In the meantime, you could do that by hand. One possible way to go is to get an intuition for the points by using nodes near coords

\documentclass{article}

\usepackage{pgfplots}
\pgfplotsset{compat=1.16}

\usepgfplotslibrary{patchplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}[view/h=210,xlabel=$a_1$,ylabel=$a_2$,zlabel=$a_3$,colormap/blackwhite]
opacity=0, % trick to make the lines go away
fill opacity=0.6,
table/row sep=\\,
patch,
patch type=polygon,
vertex count=3,
patch table with point meta={%
% pt1 pt2 pt3 pt4 pt5 cdata
1   7   8   8 \\
1   7   8   0 \\
0   1   7   0 \\
0   4   7   1 \\
4   6   7   3 \\
7   6   8   3 \\
4   2   6   4 \\
4   2   0   5 \\
0   1   2   5 \\
2   6   8   6 \\
1   2   8   6 \\
}
]
table {
x y z\\
0   0   0\\ %0
0   0   0.285957\\ %1
0   0.285957    0.285957\\ %2
0   0.3812378724    0.1906189362\\ %3
0   0.571914    0\\ %4
0.1906761276    0.3812378724    0.1906189362\\ %5
0.285957    0.285957    0.285957\\ %6
0.571914    0   0\\ %7
0.571914    0   0.285957\\ %8
};
opacity=1,
table/row sep=\\,nodes near coords/.append style={color=blue},
only marks,nodes near coords=\coordindex
]
table {
x y z\\
0   0   0\\ %0
0   0   0.285957\\ %1
0   0.285957    0.285957\\ %2
0   0.3812378724    0.1906189362\\ %3
0   0.571914    0\\ %4
0.1906761276    0.3812378724    0.1906189362\\ %5
0.285957    0.285957    0.285957\\ %6
0.571914    0   0\\ %7
0.571914    0   0.285957\\ %8
};

\end{axis}
\end{tikzpicture}
\end{document}

and then dropping the second \addplot3.

lsttriangles = {};
Do[x = H2[[closedfaces[[i, 1]] + 1]] - H2[[closedfaces[[i, 2]] + 1]];
y = H2[[closedfaces[[i, 1]] + 1]] - H2[[closedfaces[[i, 3]] + 1]];
z = Cross[x, y];
AppendTo[lsttriangles,
Join[Take[closedfaces[[i]], 3], {Abs[z.{1, 2, 3}/Sqrt[z.z]]}]], {i,
1, Length[closedfaces]}];

and then exported lsttriangles to the TeX file. That is, the first table in the following snippet is made by Mathematica.

\documentclass{article}

\usepackage{pgfplots}
\pgfplotsset{compat=1.16}

\usepgfplotslibrary{patchplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}[view/h=210,xlabel=$a_1$,ylabel=$a_2$,zlabel=$a_3$,colormap/blackwhite]
line width=0pt,opacity=0,
fill opacity=0.3,
table/row sep=\\,
patch,
patch type=polygon,
vertex count=3,
patch table with point meta={%
% pt1 pt2 pt3 cdata
0  4  7  3.\\
8  7  5  2.1213203435596424\\
4  0  2  0.9999999999999999\\
7  8  1  1.9999999999999998\\
4  2  6  3.535533905932738\\
0  7  1  1.9999999999999998\\
0  1  2  0.9999999999999999\\
7  4  5  2.1213203435596424\\
2  1  6  3.\\
1  8  6  3.\\
4  6  5  2.1213203435611967\\
6  8  5  2.121320343559643\\
}
]
table {
x y z\\
0   0   0\\ %0
0   0   0.285957\\ %1
0   0.285957    0.285957\\ %2
0   0.3812378724    0.1906189362\\ %3
0   0.571914    0\\ %4
0.1906761276    0.3812378724    0.1906189362\\ %5
0.285957    0.285957    0.285957\\ %6
0.571914    0   0\\ %7
0.571914    0   0.285957\\ %8
};

\end{axis}
\end{tikzpicture}
\end{document}

• Thank you very much. It would be nice to be able to shade using the normal vectors since I have to plot two or three convex hulls in the same figure and make more than a hundred of them. – user1993416 Jun 6 '18 at 16:02
• I do not know if I understand the comment. I am using Mathematica to get the convex hull from a set of {x,y,z} points and from there I am able to extract the triangles that form the figure as a list of the positions of the points in the list of points. I can provide a link with the Mathematica notebook. – user1993416 Jun 6 '18 at 22:53
• I already have the outer triangles. What I would need is to join the triangles that actually are in the same plane and compute the polygon of the sum the two triangle (e.g. if the polygon has 4 edges). If you do not see an easy way to do it, I would prefer you do not waste more effort and time with this. You already have helped me a lot. Thanks. – user1993416 Jun 6 '18 at 23:01
• I will try to make less figures and generate the polygons manually. – user1993416 Jun 6 '18 at 23:07
• @user1993416 I added a Mathematica solution, not fully understanding what I was doing since the table closedfaces has four rather than three columns. I just ignored the last column. Now I am wondering if you could add a minimal Mathematica notebook to your questions such that others can reproduce what's going on here. – marmot Jun 7 '18 at 2:55