{"id":83,"date":"2014-11-04T09:51:33","date_gmt":"2014-11-04T14:51:33","guid":{"rendered":"https:\/\/blogs.mathworks.com\/graphics\/?p=83"},"modified":"2016-06-29T14:19:51","modified_gmt":"2016-06-29T18:19:51","slug":"sortmethod","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/graphics\/2014\/11\/04\/sortmethod\/","title":{"rendered":"SortMethod"},"content":{"rendered":"<div class=\"content\"><h3>SortMethod<\/h3><p>Today we're going to talk about the SortMethod property which was added to the Axes object in R2014b. It's actually been around for a long time, but it wasn't supported by all renderers, and it had the confusing name 'DrawMode'. We renamed it because it's a very important property and we want to make sure that everyone understands what it is for.<\/p><p>First we'll create a very simple scene. This is just 3 patch objects. I've set they're DisplayName properties so that we'll recognize them when we see them at the command line.<\/p><p>Also note that they are coplanar. In other words, they all have the same Z coordinates. That's going to be important later.<\/p><pre class=\"codeinput\">figure\r\npatch([1 3 3 1],[1 1 3 3],[0 0 0 0],<span class=\"string\">'r'<\/span>, <span class=\"string\">'DisplayName'<\/span>,<span class=\"string\">'red'<\/span>)\r\npatch([2 4 4 2],[2 2 4 4],[0 0 0 0],<span class=\"string\">'g'<\/span>, <span class=\"string\">'DisplayName'<\/span>,<span class=\"string\">'green'<\/span>)\r\npatch([3 5 5 3],[3 3 5 5],[0 0 0 0],<span class=\"string\">'b'<\/span>, <span class=\"string\">'DisplayName'<\/span>,<span class=\"string\">'blue'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_01.png\" alt=\"\"> <p>As we can see here, the last patch we created is the first one in the Children list of the Axes.<\/p><pre class=\"codeinput\">ax = gca;\r\nax.Children\r\n<\/pre><pre class=\"codeoutput\">\r\nans = \r\n\r\n  3x1 Patch array:\r\n\r\n  Patch    (blue)\r\n  Patch    (green)\r\n  Patch    (red)\r\n\r\n<\/pre><p>The last patch added is also the one we see in the areas where they overlap. The blue patch covers the green one, and the green patch covers the red one.<\/p><p>That's because the SortMethod property of the axes is set to 'childorder'.<\/p><pre class=\"codeinput\">ax.SortMethod\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\nchildorder\r\n\r\n<\/pre><p>I can change the order of the children by setting the Children property to a permutation of it's current value. Notice what happens to the picture.<\/p><pre class=\"codeinput\">ax.Children = ax.Children([2 3 1]);\r\nax.Children\r\n<\/pre><pre class=\"codeoutput\">\r\nans = \r\n\r\n  3x1 Patch array:\r\n\r\n  Patch    (green)\r\n  Patch    (red)\r\n  Patch    (blue)\r\n\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_02.png\" alt=\"\"> <p>Now the green patch is first, so it covers both the red one and the blue one. The rule with childorder is pretty simple. An object which is near the beginning of the Children list always covers an object which is later in the Children list.<\/p><p>So what happens if we set SortMethod to the other option?<\/p><pre class=\"codeinput\">ax.SortMethod = <span class=\"string\">'depth'<\/span>;\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_03.png\" alt=\"\"> <p>Eww! That's a mess, isn't it? Why would we ever want that? To answer that question, we'll have to take a trip to \"the third dimension\" (I don't know the markup for adding scifi echo sound effects to that last phrase).<\/p><p>So let's start over. We'll create a new figure so we can come back to that example later.<\/p><p>Next we'll create a simple 3D scene out of patches. In this case the Z coordinates are not the same. Instead of being coplanar, these patches are arranged around the outside of a cube.<\/p><pre class=\"codeinput\">figure(2)\r\npatch([1 2 2 1],[1 1 2 2],[1 1 1 1],<span class=\"string\">'r'<\/span>, <span class=\"string\">'DisplayName'<\/span>,<span class=\"string\">'red'<\/span>)\r\npatch([2 2 2 2],[1 1 2 2],[1 2 2 1],<span class=\"string\">'g'<\/span>, <span class=\"string\">'DisplayName'<\/span>,<span class=\"string\">'green'<\/span>)\r\npatch([2 1 1 2],[1 1 2 2],[2 2 2 2],<span class=\"string\">'b'<\/span>, <span class=\"string\">'DisplayName'<\/span>,<span class=\"string\">'blue'<\/span>)\r\npatch([1 1 1 1],[1 1 2 2],[2 1 1 2],<span class=\"string\">'c'<\/span>, <span class=\"string\">'DisplayName'<\/span>,<span class=\"string\">'cyan'<\/span>)\r\nview(3)\r\nax = gca;\r\nax.Children\r\n<\/pre><pre class=\"codeoutput\">\r\nans = \r\n\r\n  4x1 Patch array:\r\n\r\n  Patch    (cyan)\r\n  Patch    (blue)\r\n  Patch    (green)\r\n  Patch    (red)\r\n\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_04.png\" alt=\"\"> <p>At first it looks like the same rules apply here. The cyan patch is first, and it covers the red one. Same with the blue and green patches.<\/p><p>But if we permute the children in this case, the picture doesn't change.<\/p><pre class=\"codeinput\">ax.Children = ax.Children([4 1 3 2]);\r\nax.Children\r\n<\/pre><pre class=\"codeoutput\">\r\nans = \r\n\r\n  4x1 Patch array:\r\n\r\n  Patch    (red)\r\n  Patch    (cyan)\r\n  Patch    (green)\r\n  Patch    (blue)\r\n\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_05.png\" alt=\"\"> <p>That's because the SortMethod property has changed.<\/p><pre class=\"codeinput\">ax.SortMethod\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\ndepth\r\n\r\n<\/pre><p>The axes has noticed that we have a 3D scene and it has chosen depth instead of childorder. In most cases the axes will choose the correct value and we won't have to worry about our SortMethod. But the property allows us to override the choice that axes makes.<\/p><p>So lets try setting it to childorder for this scene.<\/p><pre class=\"codeinput\">ax.SortMethod = <span class=\"string\">'childorder'<\/span>;\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_06.png\" alt=\"\"> <p>Wow, it turned inside out! Now permuting the children does change the picture.<\/p><pre class=\"codeinput\">ax.Children = ax.Children([3 2 1 4]);\r\nax.Children\r\n<\/pre><pre class=\"codeoutput\">\r\nans = \r\n\r\n  4x1 Patch array:\r\n\r\n  Patch    (green)\r\n  Patch    (cyan)\r\n  Patch    (red)\r\n  Patch    (blue)\r\n\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_07.png\" alt=\"\"> <p>What's happening is that when we use 'depth' for the SortMethod, the graphics system sorts all of the objects in \"depth\" order. This means that it ensures that the objects which are closer to the viewer cover the objects which are farther from the viewer.<\/p><pre class=\"codeinput\">ax.SortMethod = <span class=\"string\">'depth'<\/span>;\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_08.png\" alt=\"\"> <p>But that still doesn't explain this picture, does it?<\/p><pre class=\"codeinput\">figure(1)\r\nax = gca;\r\nax.SortMethod = <span class=\"string\">'depth'<\/span>;\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_09.png\" alt=\"\"> <p>What's going on here is that the technique that the graphics system uses to sort the objects struggles when it encounters coplanar objects. When it finds coplanar objects, it tries to draw them in child order, but it has a number of limitations. Most notably, the default renderer (OpenGL) tends to let lines win over faces in coplanar situations. It does this to make sure that you can always see the edges of a patch, even when that patch is drawn at a funny angle. It actually works pretty well in most cases, but here it is making the edges of the red and blue patches poke through the green patch.<\/p><p>Depth sorting techniques is one of oldest and richest corners of computer graphics programming. Many different techniques have been developed over the years. They all have different combinations of strengths and weaknesses, and they all have different performance characteristics.<\/p><p>Different graphics cards can actually get different results in these coplanar cases. And different renderers can too. The painters renderer, which is used for generating vector file formats like PDF, uses a different sorting technique which has different limitations in this coplanar case.<\/p><pre class=\"codeinput\">set(1,<span class=\"string\">'Renderer'<\/span>,<span class=\"string\">'painters'<\/span>);\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_10.png\" alt=\"\"> <p>But the depth sort that the painters renderer uses works fine on our scene that doesn't have coplanar patches.<\/p><pre class=\"codeinput\">figure(2)\r\nset(2,<span class=\"string\">'Renderer'<\/span>,<span class=\"string\">'painters'<\/span>);\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/sortmethod_11.png\" alt=\"\"> <p>I hope that you've learned a little more about an important, but underappreciated axes property.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_8f37706330aa4a76883ee3d7cd8cd059() {\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='8f37706330aa4a76883ee3d7cd8cd059 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 8f37706330aa4a76883ee3d7cd8cd059';\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 2014 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_8f37706330aa4a76883ee3d7cd8cd059()\"><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; R2014b<br><\/p><\/div><!--\r\n8f37706330aa4a76883ee3d7cd8cd059 ##### SOURCE BEGIN #####\r\n%% SortMethod\r\n% Today we're going to talk about the SortMethod property which was added \r\n% to the Axes object in R2014b. It's actually been around for a long time, \r\n% but it wasn't supported by all renderers, and it had the confusing name \r\n% 'DrawMode'. We renamed it because it's a very important property and we \r\n% want to make sure that everyone understands what it is for.\r\n%\r\n% First we'll create a very simple scene. This is just 3 patch objects.\r\n% I've set they're DisplayName properties so that we'll recognize them when\r\n% we see them at the command line.\r\n%\r\n% Also note that they are coplanar. In other words, they all have the same \r\n% Z coordinates. That's going to be important later.\r\n%\r\nfigure\r\npatch([1 3 3 1],[1 1 3 3],[0 0 0 0],'r', 'DisplayName','red')\r\npatch([2 4 4 2],[2 2 4 4],[0 0 0 0],'g', 'DisplayName','green')\r\npatch([3 5 5 3],[3 3 5 5],[0 0 0 0],'b', 'DisplayName','blue')\r\n\r\n%%\r\n% As we can see here, the last patch we created is the first one in the\r\n% Children list of the Axes.\r\nax = gca;\r\nax.Children\r\n\r\n%%\r\n% The last patch added is also the one we see in the areas where they\r\n% overlap. The blue patch covers the green one, and the green patch covers the\r\n% red one.\r\n\r\n%%\r\n% That's because the SortMethod property of the axes is set to\r\n% 'childorder'.\r\nax.SortMethod\r\n\r\n%%\r\n% I can change the order of the children by setting the Children property\r\n% to a permutation of it's current value. Notice what happens to the\r\n% picture.\r\nax.Children = ax.Children([2 3 1]);\r\nax.Children\r\n\r\n%%\r\n% Now the green patch is first, so it covers both the red one and the blue\r\n% one. The rule with childorder is pretty simple. An object which is near\r\n% the beginning of the Children list always covers an object which is later\r\n% in the Children list.\r\n\r\n%%\r\n% So what happens if we set SortMethod to the other option?\r\nax.SortMethod = 'depth';\r\n\r\n%%\r\n% Eww! That's a mess, isn't it? Why would we ever want that? To answer that\r\n% question, we'll have to take a trip to \"the third dimension\" (I don't \r\n% know the markup for adding scifi echo sound effects to that last phrase).\r\n\r\n%%\r\n% So let's start over. We'll create a new figure so we can come back to\r\n% that example later.\r\n%\r\n% Next we'll create a simple 3D scene out of patches. In this case the Z\r\n% coordinates are not the same. Instead of being coplanar, these patches\r\n% are arranged around the outside of a cube.\r\nfigure(2)\r\npatch([1 2 2 1],[1 1 2 2],[1 1 1 1],'r', 'DisplayName','red')\r\npatch([2 2 2 2],[1 1 2 2],[1 2 2 1],'g', 'DisplayName','green')\r\npatch([2 1 1 2],[1 1 2 2],[2 2 2 2],'b', 'DisplayName','blue')\r\npatch([1 1 1 1],[1 1 2 2],[2 1 1 2],'c', 'DisplayName','cyan')\r\nview(3)\r\nax = gca;\r\nax.Children\r\n\r\n%%\r\n% At first it looks like the same rules apply here. The cyan patch is first, \r\n% and it covers the red one. Same with the blue and green patches.\r\n%\r\n%\r\n% But if we permute the children in this case, the picture doesn't change.\r\nax.Children = ax.Children([4 1 3 2]);\r\nax.Children\r\n\r\n%%\r\n% That's because the SortMethod property has changed.\r\nax.SortMethod\r\n\r\n%%\r\n% The axes has noticed that we have a 3D scene and it has chosen depth instead of\r\n% childorder. In most cases the axes will choose the correct value and\r\n% we won't have to worry about our SortMethod. But the property allows\r\n% us to override the choice that axes makes.\r\n%\r\n% So lets try setting it to childorder for this scene.\r\nax.SortMethod = 'childorder';\r\n\r\n%%\r\n% Wow, it turned inside out! Now permuting the children does change the\r\n% picture.\r\nax.Children = ax.Children([3 2 1 4]);\r\nax.Children\r\n\r\n%%\r\n% What's happening is that when we use 'depth' for the SortMethod, the\r\n% graphics system sorts all of the objects in \"depth\" order. This means\r\n% that it ensures that the objects which are closer to the viewer cover the\r\n% objects which are farther from the viewer.\r\nax.SortMethod = 'depth';\r\n\r\n%%\r\n% But that still doesn't explain this picture, does it?\r\nfigure(1)\r\nax = gca;\r\nax.SortMethod = 'depth';\r\n\r\n%%\r\n% What's going on here is that the technique that the graphics system uses\r\n% to sort the objects struggles when it encounters coplanar objects. When\r\n% it finds coplanar objects, it tries to draw them in child order, but it\r\n% has a number of limitations. Most notably, the default renderer (OpenGL)\r\n% tends to let lines win over faces in coplanar situations. It does this\r\n% to make sure that you can always see the edges of a patch, even when\r\n% that patch is drawn at a funny angle. It actually works pretty well in\r\n% most cases, but here it is making the edges of the red and blue patches\r\n% poke through the green patch.\r\n%\r\n% Depth sorting techniques is one of <http:\/\/cs.brown.edu\/courses\/cs123\/lectures\/CS123_Visible_Surface_Determination_2014.pdf oldest and richest corners of computer graphics\r\n% programming>. Many different techniques have been developed over the\r\n% years. They all have different combinations of strengths and weaknesses,\r\n% and they all have different performance characteristics.\r\n%\r\n% Different graphics cards can actually get different results in these\r\n% coplanar cases. And different renderers can too. The painters renderer,\r\n% which is used for generating vector file formats like PDF, uses a\r\n% different sorting technique which has different limitations in this\r\n% coplanar case.\r\nset(1,'Renderer','painters');\r\n\r\n%%\r\n% But the depth sort that the painters renderer uses works fine on our scene \r\n% that doesn't have coplanar patches.\r\nfigure(2)\r\nset(2,'Renderer','painters');\r\n\r\n%%\r\n% I hope that you've learned a little more about an important, but underappreciated\r\n% axes property.\r\n\r\n##### SOURCE END ##### 8f37706330aa4a76883ee3d7cd8cd059\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/graphics\/files\/feature_image\/sortmethod_04.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>SortMethodToday we're going to talk about the SortMethod property which was added to the Axes object in R2014b. It's actually been around for a long time, but it wasn't supported by all renderers,... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/graphics\/2014\/11\/04\/sortmethod\/\">read more >><\/a><\/p>","protected":false},"author":89,"featured_media":86,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/83"}],"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=83"}],"version-history":[{"count":7,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/83\/revisions"}],"predecessor-version":[{"id":529,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/83\/revisions\/529"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media\/86"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media?parent=83"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/categories?post=83"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/tags?post=83"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}