{"id":403,"date":"2016-01-29T08:37:29","date_gmt":"2016-01-29T13:37:29","guid":{"rendered":"https:\/\/blogs.mathworks.com\/graphics\/?p=403"},"modified":"2016-02-04T09:09:28","modified_gmt":"2016-02-04T14:09:28","slug":"tiling-hexagons-and-other-permutohedra","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/graphics\/2016\/01\/29\/tiling-hexagons-and-other-permutohedra\/","title":{"rendered":"Tiling Hexagons and Other Permutohedra"},"content":{"rendered":"<div class=\"content\"><p>In earlier posts we've looked at tiling <a href=\"https:\/\/blogs.mathworks.com\/graphics\/2015\/09\/04\/tiling-quadrilaterals\/\">quadrilaterals<\/a> and <a href=\"https:\/\/blogs.mathworks.com\/graphics\/2015\/08\/19\/type-15-convex-pentagon\/\">pentagons<\/a>. So what about hexagons? I'm sure you've seen tilings of regular hexagons. They're popular in floor tiles and game tiles. Even bees know about this one. But there's one interesting feature of this tiling that you might not be familiar with. To see this feature, we need to start in a very different place.<\/p><p>We're going to start by making all of the permutations of the sequence [1 2 3]. As you probably know, for n items, there are n! permutations. So there are 6 different ways we can arrange these 3 numbers.<\/p><pre class=\"codeinput\">n = 3;\r\nnp = factorial(n);\r\npts = perms(1:n)\r\n<\/pre><pre class=\"codeoutput\">\r\npts =\r\n\r\n     3     2     1\r\n     3     1     2\r\n     2     3     1\r\n     2     1     3\r\n     1     2     3\r\n     1     3     2\r\n\r\n<\/pre><p>Now we have an array with 6 rows and 3 columns. Since we have 3 columns, I'm just going to go ahead and use them as coordinates in 3D space. That gives me 6 points that I can draw with the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/stem3.html\">stem3 function<\/a>.<\/p><pre class=\"codeinput\">stem3(pts(:,1),pts(:,2),pts(:,3),<span class=\"string\">'filled'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_01.png\" alt=\"\"> <p>These points are all arranged on the edges of a box that goes from 1 to 3 along each axis.<\/p><pre class=\"codeinput\">lx = [1 3 3 1 1 nan 1 3 3 1 1 nan 1 1 nan 3 3 nan 3 3 nan 1 1 nan];\r\nly = [1 1 3 3 1 nan 1 1 3 3 1 nan 1 1 nan 1 1 nan 3 3 nan 3 3 nan];\r\nlz = [1 1 1 1 1 nan 3 3 3 3 3 nan 1 3 nan 1 3 nan 1 3 nan 1 3 nan];\r\nline(lx,ly,lz,<span class=\"string\">'Color'<\/span>,[.75 .75 .75])\r\nxlim([0.5 3.5])\r\nylim([0.5 3.5])\r\nzlim([0.5 3.5])\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_02.png\" alt=\"\"> <p>Let's add some labels so we can see what we've got.<\/p><pre class=\"codeinput\">xlabel <span class=\"string\">X<\/span>\r\nylabel <span class=\"string\">Y<\/span>\r\nzlabel <span class=\"string\">Z<\/span>\r\nnodelabels = cellstr(arrayfun(@(x)sprintf(<span class=\"string\">'%d'<\/span>,x),pts));\r\n<span class=\"keyword\">for<\/span> i=1:np\r\n    text(pts(i,1),pts(i,2),pts(i,3)+.1,nodelabels{i,1}, <span class=\"keyword\">...<\/span>\r\n        <span class=\"string\">'HorizontalAlignment'<\/span>,<span class=\"string\">'center'<\/span>, <span class=\"keyword\">...<\/span>\r\n        <span class=\"string\">'VerticalAlignment'<\/span>,<span class=\"string\">'baseline'<\/span>, <span class=\"keyword\">...<\/span>\r\n        <span class=\"string\">'FontSize'<\/span>,16);\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_03.png\" alt=\"\"> <p>Now I want to connect each pair of points that are on the same face of the cube. One way to do that is like this:<\/p><pre class=\"codeinput\">edges = [];\r\n<span class=\"keyword\">for<\/span> i=1:np\r\n    <span class=\"keyword\">for<\/span> j=(i+1):np\r\n        diff = pts(j,:) - pts(i,:);\r\n        <span class=\"keyword\">if<\/span> isscalar(find(diff==-1)) &amp;&amp; isscalar(find(diff==1)) &amp;&amp; (n-2)==length(find(diff==0))\r\n            edges(end+1,:) = [i j];\r\n        <span class=\"keyword\">end<\/span>\r\n    <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span>\r\ng = graph(edges(:,1),edges(:,2));\r\no = dfsearch(g,1);\r\nf = [o; 1];\r\nline(pts(f,1),pts(f,2),pts(f,3))\r\nf = o';\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_04.png\" alt=\"\"> <p>You can probably already see that these form a hexagon. Let's emphasize that by creating a patch from them, and rotating around to get a better view.<\/p><pre class=\"codeinput\">cla\r\ncols = lines(7);\r\npatch(<span class=\"string\">'Faces'<\/span>,f,<span class=\"string\">'Vertices'<\/span>,pts,<span class=\"string\">'FaceColor'<\/span>,cols(1,:))\r\nview([120 30])\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_05.png\" alt=\"\"> <p>And if we stacked an infinite number of boxes and intersected them all with that same plane, we would get a number of different hexagons, tiled in the familiar pattern.<\/p><pre class=\"codeinput\">cla\r\nvec1 = pts(f(5),:) - pts(f(3),:);\r\nvec2 = pts(f(5),:) - pts(f(1),:);\r\np = gobjects(0);\r\n<span class=\"keyword\">for<\/span> i=-4:4\r\n    <span class=\"keyword\">for<\/span> j=-4:4\r\n        cindex = 1+mod(2*mod(i,2) + 1*mod(j,2),7);\r\n        tmp_pts = pts + repmat(i*vec1,[np 1]) + repmat(j*vec2,[np 1]);\r\n        p(end+1) = patch(<span class=\"string\">'Faces'<\/span>,f,<span class=\"string\">'Vertices'<\/span>,tmp_pts,<span class=\"string\">'FaceColor'<\/span>,cols(cindex,:));\r\n    <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span>\r\nxlim([-2 6])\r\nylim([-2 6])\r\nzlim([-2 6])\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_06.png\" alt=\"\"> <p>And because all of these patches line in a plane, we can project them into 2D using a pair of basis vectors which are tangent to the plane.<\/p><pre class=\"codeinput\">uvec = [1, 0, 0];\r\nvvec = [0, sqrt(2)\/2, -sqrt(2)\/2];\r\n\r\n<span class=\"keyword\">for<\/span> i=1:numel(p)\r\n    v3 = p(i).Vertices;\r\n    x = sum(v3 .* repmat(uvec,[np 1]),2);\r\n    y = sum(v3 .* repmat(vvec,[np 1]),2);\r\n    p(i).Vertices = [x, y, zeros(np,1)];\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_07.png\" alt=\"\"> <p>And now we have the familiar 2D tiling of regular hexagons.<\/p><pre class=\"codeinput\">view(2)\r\naxis <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_08.png\" alt=\"\"> <p>That's kind of an odd way to think about hexagonal tilings, isn't it? But it's actually useful because of one surprising fact. And that is that this trick works in any dimension!<\/p><p>If we did this in 2D, we'd get a line connecting the points [1 2] and [2 1]. What if we did it in 4D? Let's give it a try, and see what we get.<\/p><p>This time we'll get an array that is 24x4 because 4! is 24.<\/p><pre class=\"codeinput\">n = 4;\r\nnp = factorial(n);\r\npts = perms(1:n)\r\n<\/pre><pre class=\"codeoutput\">\r\npts =\r\n\r\n     4     3     2     1\r\n     4     3     1     2\r\n     4     2     3     1\r\n     4     2     1     3\r\n     4     1     2     3\r\n     4     1     3     2\r\n     3     4     2     1\r\n     3     4     1     2\r\n     3     2     4     1\r\n     3     2     1     4\r\n     3     1     2     4\r\n     3     1     4     2\r\n     2     3     4     1\r\n     2     3     1     4\r\n     2     4     3     1\r\n     2     4     1     3\r\n     2     1     4     3\r\n     2     1     3     4\r\n     1     3     2     4\r\n     1     3     4     2\r\n     1     2     3     4\r\n     1     2     4     3\r\n     1     4     2     3\r\n     1     4     3     2\r\n\r\n<\/pre><p>If we use each row as a point, we have 4 dimensions. This makes things a bit more abstract. Let's start by drawing the points and their connections as an undirected graph.<\/p><pre class=\"codeinput\">nodelabels = cellstr(arrayfun(@(x)sprintf(<span class=\"string\">'%d'<\/span>,x),pts));\r\nedges = [];\r\n<span class=\"keyword\">for<\/span> i=1:np\r\n    <span class=\"keyword\">for<\/span> j=(i+1):np\r\n        diff = pts(j,:) - pts(i,:);\r\n        <span class=\"keyword\">if<\/span> isscalar(find(diff==-1)) &amp;&amp; isscalar(find(diff==1)) &amp;&amp; (n-2)==length(find(diff==0))\r\n            edges(end+1,:) = [i j];\r\n        <span class=\"keyword\">end<\/span>\r\n    <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span>\r\ng = graph(edges(:,1),edges(:,2),[],nodelabels);\r\nplot(g)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_09.png\" alt=\"\"> <p>We can see that there appears to be a polyhedron hiding in there.<\/p><p>What if we project this shape down into 3 dimensions? To do this, we'll need three 4D vectors which are normal to each other, and normal to the hyperplane. I happen to have a set right here.<\/p><pre class=\"codeinput\">u = [sqrt(2)\/2, -sqrt(2)\/2, 0, 0];\r\nv = [sqrt(6)\/6, sqrt(6)\/6, -sqrt(2\/3), 0];\r\nw = [sqrt(12)\/12, sqrt(12)\/12, sqrt(12)\/12, -sqrt(3)\/2];\r\n<\/pre><p>Now we can use the same technique I used to project that plane of hexagons down from 3D to 2D.<\/p><pre class=\"codeinput\">x = sum(pts .* repmat(u,[np 1]),2);\r\ny = sum(pts .* repmat(v,[np 1]),2);\r\nz = sum(pts .* repmat(w,[np 1]),2);\r\nscatter3(x,y,z,<span class=\"string\">'filled'<\/span>);\r\naxis <span class=\"string\">equal<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_10.png\" alt=\"\"> <p>And then we can get the faces of the shape by using convhull.<\/p><pre class=\"codeinput\">faces = convhull(x,y,z);\r\n\r\nhold <span class=\"string\">on<\/span>\r\ntrisurf(faces,x,y,z,<span class=\"string\">'FaceColor'<\/span>,cols(3,:),<span class=\"string\">'EdgeColor'<\/span>,<span class=\"string\">'none'<\/span>)\r\naxis <span class=\"string\">vis3d<\/span>\r\ncamlight <span class=\"string\">right<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_example_11.png\" alt=\"\"> <p>And we can recognize this as a truncated octahedron.<\/p><p>And just as we saw in the 2D case, these octahedra will tile 3D space with no gaps.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2016\/permutohedron_animation.gif\" alt=\"\"> <\/p><p>This tiling is known as the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bitruncated_cubic_honeycomb\">bitruncated cubic honeycomb<\/a>.<\/p><p>And as I said, you can do this same thing in any dimension to generate a set of objects which tile the next dimension down. For example, if you do this with n=5, you'll get a 4D shape called the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Runcinated_5-cell#Omnitruncated_5-cell\">great prismatodecachoron<\/a>. This family of shapes go by the curious name of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Permutohedron\">permutohedron<\/a>. Aren't they an interesting family?<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_d3c60471184b482c99edd2ce64b112e9() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='d3c60471184b482c99edd2ce64b112e9 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' d3c60471184b482c99edd2ce64b112e9';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2016 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_d3c60471184b482c99edd2ce64b112e9()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2015b<br><\/p><\/div><!--\r\nd3c60471184b482c99edd2ce64b112e9 ##### SOURCE BEGIN #####\r\n\r\n%% Tiling Hexagons and Other Permutohedra\r\n% In earlier posts we've looked at tiling <https:\/\/blogs.mathworks.com\/graphics\/2015\/09\/04\/tiling-quadrilaterals\/ quadrilaterals>\r\n% and\r\n% <https:\/\/blogs.mathworks.com\/graphics\/2015\/08\/19\/type-15-convex-pentagon\/\r\n% pentagons>. So what about hexagons? I'm sure you've seen tilings of\r\n% regular hexagons. They're popular in floor tiles and game tiles. Even bees \r\n% know about this one. But there's one interesting feature of this tiling \r\n% that you might not be familiar with. To see this feature, we need to start \r\n% in a very different place.\r\n%\r\n% We're going to start by making all of the permutations of the sequence [1\r\n% 2 3]. As you probably know, for n items, there are n! permutations. So\r\n% there are 6 different ways we can arrange these 3 numbers.\r\n%\r\nn = 3;\r\nnp = factorial(n);\r\npts = perms(1:n)\r\n\r\n%%\r\n% Now we have an array with 6 rows and 3 columns. Since we have 3 columns,\r\n% I'm just going to go ahead and use them as coordinates in 3D space. That\r\n% gives me 6 points that I can draw with the <https:\/\/www.mathworks.com\/help\/matlab\/ref\/stem3.html stem3 function>.\r\n%\r\nstem3(pts(:,1),pts(:,2),pts(:,3),'filled')\r\n\r\n%%\r\n% These points are all arranged on the edges of a box that goes from 1 to 3 along each\r\n% axis.\r\n%\r\nlx = [1 3 3 1 1 nan 1 3 3 1 1 nan 1 1 nan 3 3 nan 3 3 nan 1 1 nan];\r\nly = [1 1 3 3 1 nan 1 1 3 3 1 nan 1 1 nan 1 1 nan 3 3 nan 3 3 nan];\r\nlz = [1 1 1 1 1 nan 3 3 3 3 3 nan 1 3 nan 1 3 nan 1 3 nan 1 3 nan];\r\nline(lx,ly,lz,'Color',[.75 .75 .75])\r\nxlim([0.5 3.5])\r\nylim([0.5 3.5])\r\nzlim([0.5 3.5])\r\n\r\n%%\r\n% Let's add some labels so we can see what we've got.\r\n%\r\nxlabel X\r\nylabel Y\r\nzlabel Z\r\nnodelabels = cellstr(arrayfun(@(x)sprintf('%d',x),pts));\r\nfor i=1:np\r\n    text(pts(i,1),pts(i,2),pts(i,3)+.1,nodelabels{i,1}, ...\r\n        'HorizontalAlignment','center', ...\r\n        'VerticalAlignment','baseline', ...\r\n        'FontSize',16);\r\nend\r\n\r\n%%\r\n% Now I want to connect each pair of points that are on the same face of\r\n% the cube. One way to do that is like this:\r\n%\r\nedges = [];\r\nfor i=1:np\r\n    for j=(i+1):np\r\n        diff = pts(j,:) - pts(i,:);\r\n        if isscalar(find(diff==-1)) && isscalar(find(diff==1)) && (n-2)==length(find(diff==0))\r\n            edges(end+1,:) = [i j];\r\n        end\r\n    end\r\nend\r\ng = graph(edges(:,1),edges(:,2));\r\no = dfsearch(g,1);\r\nf = [o; 1];\r\nline(pts(f,1),pts(f,2),pts(f,3))\r\nf = o';\r\n\r\n%%\r\n% You can probably already see that these form a hexagon. Let's emphasize\r\n% that by creating a patch from them, and rotating around to get a better\r\n% view.\r\n%\r\ncla\r\ncols = lines(7);\r\npatch('Faces',f,'Vertices',pts,'FaceColor',cols(1,:))\r\nview([120 30])\r\n\r\n%%\r\n% And if we stacked an infinite number of boxes and intersected them all\r\n% with that same plane, we would get a number of different hexagons, tiled \r\n% in the familiar pattern.\r\n%\r\ncla\r\nvec1 = pts(f(5),:) - pts(f(3),:);\r\nvec2 = pts(f(5),:) - pts(f(1),:);\r\np = gobjects(0);\r\nfor i=-4:4\r\n    for j=-4:4\r\n        cindex = 1+mod(2*mod(i,2) + 1*mod(j,2),7);\r\n        tmp_pts = pts + repmat(i*vec1,[np 1]) + repmat(j*vec2,[np 1]);\r\n        p(end+1) = patch('Faces',f,'Vertices',tmp_pts,'FaceColor',cols(cindex,:));\r\n    end\r\nend\r\nxlim([-2 6])\r\nylim([-2 6])\r\nzlim([-2 6])\r\n\r\n%%\r\n% And because all of these patches line in a plane, we can project them\r\n% into 2D using a pair of basis vectors which are tangent to the plane.\r\n%\r\nuvec = [1, 0, 0];\r\nvvec = [0, sqrt(2)\/2, -sqrt(2)\/2];\r\n\r\nfor i=1:numel(p)\r\n    v3 = p(i).Vertices;\r\n    x = sum(v3 .* repmat(uvec,[np 1]),2);\r\n    y = sum(v3 .* repmat(vvec,[np 1]),2);\r\n    p(i).Vertices = [x, y, zeros(np,1)];\r\nend\r\n\r\n%%\r\n% And now we have the familiar 2D tiling of regular hexagons.\r\n%\r\nview(2)\r\naxis off\r\n\r\n%%\r\n% That's kind of an odd way to think about hexagonal tilings, isn't it? But \r\n% it's actually useful because of one surprising fact. And that is that this\r\n% trick works in any dimension! \r\n%\r\n% If we did this in 2D, we'd get a line connecting the points [1 2] and [2\r\n% 1]. What if we did it in 4D? Let's give it a try, and see what we get. \r\n%\r\n% This time we'll get an array that is 24x4 because 4! is 24.\r\n%\r\nn = 4;\r\nnp = factorial(n);\r\npts = perms(1:n)\r\n\r\n%%\r\n% If we use each row as a point, we have 4 dimensions. This makes things a\r\n% bit more abstract. Let's start by drawing the points and their\r\n% connections as an undirected graph.\r\n%\r\nnodelabels = cellstr(arrayfun(@(x)sprintf('%d',x),pts));\r\nedges = [];\r\nfor i=1:np\r\n    for j=(i+1):np\r\n        diff = pts(j,:) - pts(i,:);\r\n        if isscalar(find(diff==-1)) && isscalar(find(diff==1)) && (n-2)==length(find(diff==0))\r\n            edges(end+1,:) = [i j];\r\n        end\r\n    end\r\nend\r\ng = graph(edges(:,1),edges(:,2),[],nodelabels);\r\nplot(g)\r\n\r\n%%\r\n% We can see that there appears to be a polyhedron hiding in there.\r\n%\r\n% What if we project this shape down into 3 dimensions? To do this, we'll\r\n% need three 4D vectors which are normal to each other, and normal to the hyperplane. I\r\n% happen to have a set right here.\r\n%\r\nu = [sqrt(2)\/2, -sqrt(2)\/2, 0, 0];\r\nv = [sqrt(6)\/6, sqrt(6)\/6, -sqrt(2\/3), 0];\r\nw = [sqrt(12)\/12, sqrt(12)\/12, sqrt(12)\/12, -sqrt(3)\/2];\r\n\r\n%%\r\n% Now we can use the same technique I used to project that plane of\r\n% hexagons down from 3D to 2D.\r\n%\r\nx = sum(pts .* repmat(u,[np 1]),2);\r\ny = sum(pts .* repmat(v,[np 1]),2);\r\nz = sum(pts .* repmat(w,[np 1]),2);\r\nscatter3(x,y,z,'filled');\r\naxis equal\r\n\r\n%%\r\n% And then we can get the faces of the shape by using convhull.\r\n%\r\nfaces = convhull(x,y,z);\r\n\r\nhold on\r\ntrisurf(faces,x,y,z,'FaceColor',cols(3,:),'EdgeColor','none')\r\naxis vis3d\r\ncamlight right\r\n\r\n%%\r\n% And we can recognize this as a truncated octahedron. \r\n%\r\n% And just as we saw in the 2D case, these octahedra will tile 3D space with no gaps.\r\n%\r\n% <<permutohedron_animation.gif>>\r\n%\r\n% This tiling is known as the <https:\/\/en.wikipedia.org\/wiki\/Bitruncated_cubic_honeycomb bitruncated cubic honeycomb>.\r\n%\r\n% And as I said, you can do this same thing in any dimension to generate a\r\n% set of objects which tile the next dimension down. For example, if you do\r\n% this with n=5, you'll get a 4D shape called the <https:\/\/en.wikipedia.org\/wiki\/Runcinated_5-cell#Omnitruncated_5-cell great prismatodecachoron>.\r\n% This family of shapes go by the curious name of <https:\/\/en.wikipedia.org\/wiki\/Permutohedron\r\n% permutohedron>. Aren't they an interesting family?\r\n%\r\n\r\n\r\n%%\r\n% _Copyright 2016 The MathWorks, Inc._\r\n\r\n##### SOURCE END ##### d3c60471184b482c99edd2ce64b112e9\r\n-->\r\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/graphics\/files\/feature_image\/hexagonal_tiling_thumbnail.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>In earlier posts we've looked at tiling quadrilaterals and pentagons. So what about hexagons? I'm sure you've seen tilings of regular hexagons. They're popular in floor tiles and game tiles. Even... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/graphics\/2016\/01\/29\/tiling-hexagons-and-other-permutohedra\/\">read more >><\/a><\/p>","protected":false},"author":89,"featured_media":406,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/403"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/users\/89"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/comments?post=403"}],"version-history":[{"count":5,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/403\/revisions"}],"predecessor-version":[{"id":413,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/403\/revisions\/413"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media\/406"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media?parent=403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/categories?post=403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/tags?post=403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}