{"id":102,"date":"2006-12-13T15:43:26","date_gmt":"2006-12-13T20:43:26","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=102"},"modified":"2019-10-22T16:37:38","modified_gmt":"2019-10-22T20:37:38","slug":"poly2mask-and-roipoly-part-2","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2006\/12\/13\/poly2mask-and-roipoly-part-2\/","title":{"rendered":"POLY2MASK and ROIPOLY &#8211; Part 2"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>I'm familiar with two basic ways to determine whether a point is inside a polygon.  The first is to compute the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Winding_number\">winding number<\/a>, which is the number of times that a closed curve encircles the point. This technique is used by the MATLAB function <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/inpolygon.html\">inpolygon<\/a>.\r\n   <\/p>\r\n   <p>When computing point-inside-polygon for all the points on a pixel grid, the crossing test is more commonly used.  You follow\r\n      a ray from one side of the image to the other, counting the number of times the ray crosses an edge of the polygon.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">x1 = [30 80 60 30];\r\ny1 = [30 50 90 30];\r\nray_x = [20 90];\r\nray_y = [70 70];\r\npoints_x = [30 60 80];\r\npoints_y = [70 70 70];\r\nplot(x1,y1)\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\nplot(ray_x,ray_y, <span style=\"color: #A020F0\">'r'<\/span>)\r\nplot(points_x,points_y,<span style=\"color: #A020F0\">'Marker'<\/span>,<span style=\"color: #A020F0\">'o'<\/span>,<span style=\"color: #A020F0\">'MarkerSize'<\/span>,4,<span style=\"color: #A020F0\">'Color'<\/span>,<span style=\"color: #A020F0\">'k'<\/span>,<span style=\"color: #0000FF\">...<\/span>\r\n    <span style=\"color: #A020F0\">'MarkerFaceColor'<\/span>,<span style=\"color: #A020F0\">'k'<\/span>,<span style=\"color: #A020F0\">'LineStyle'<\/span>,<span style=\"color: #A020F0\">'none'<\/span>)\r\ntext(30,70,<span style=\"color: #A020F0\">'A'<\/span>,<span style=\"color: #A020F0\">'VerticalAlignment'<\/span>,<span style=\"color: #A020F0\">'bottom'<\/span>)\r\ntext(60,70,<span style=\"color: #A020F0\">'B'<\/span>,<span style=\"color: #A020F0\">'VerticalAlignment'<\/span>,<span style=\"color: #A020F0\">'bottom'<\/span>)\r\ntext(80,70,<span style=\"color: #A020F0\">'C'<\/span>,<span style=\"color: #A020F0\">'VerticalAlignment'<\/span>,<span style=\"color: #A020F0\">'bottom'<\/span>)\r\naxis <span style=\"color: #A020F0\">off<\/span>\r\nhold <span style=\"color: #A020F0\">off<\/span>\r\ntitle(<span style=\"color: #A020F0\">'Polygon 1'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/102\/roipoly2_01.png\"> <p>At point A, the ray has not crossed a polygon edge; A is outside the polygon.  At point B, the ray has crossed a polygon edge\r\n      one time; B is inside.  At point C, the ray has crossed a polygon edge twice; C is outside.\r\n   <\/p>\r\n   <p>Polygons can get much more complex than a triangle, of course.  Here are a couple of convex, nonsimple polygons.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">subplot(2,1,1)\r\nplot([30 70 70 30 30], [30 70 30 70 30])\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\nplot([20 80],[60 60],<span style=\"color: #A020F0\">'r'<\/span>)\r\nhold <span style=\"color: #A020F0\">off<\/span>\r\naxis <span style=\"color: #A020F0\">off<\/span>\r\ntitle(<span style=\"color: #A020F0\">'Polygon 2'<\/span>)\r\n\r\nsubplot(2,1,2)\r\nplot([30 70 70 40 40 60 60 30 30], <span style=\"color: #0000FF\">...<\/span>\r\n    [30 30 55 55 35 35 60 60 30])\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\nplot([20 80],[45 45],<span style=\"color: #A020F0\">'r'<\/span>)\r\nplot(50,45,<span style=\"color: #A020F0\">'Marker'<\/span>,<span style=\"color: #A020F0\">'o'<\/span>,<span style=\"color: #A020F0\">'MarkerSize'<\/span>,4,<span style=\"color: #A020F0\">'MarkerFaceColor'<\/span>,<span style=\"color: #A020F0\">'k'<\/span>)\r\ntext(50,45,<span style=\"color: #A020F0\">'D'<\/span>,<span style=\"color: #A020F0\">'VerticalAlignment'<\/span>,<span style=\"color: #A020F0\">'bottom'<\/span>)\r\nylim([25 75])\r\nhold <span style=\"color: #A020F0\">off<\/span>\r\naxis <span style=\"color: #A020F0\">off<\/span>\r\ntitle(<span style=\"color: #A020F0\">'Polygon 3'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/102\/roipoly2_02.png\"> <p>In polygon 2, the ray crosses into and then out of the polygon twice.  Polygon 3 is even more interesting.  Is point D inside\r\n      or outside the polygon? The answer is a matter of convention.  A commonly-used convention is the <i>even-odd<\/i> rule.  A point is outside the polygon if there have been an even number of edge crossings.  A point is inside there have\r\n      been an odd number.  By this rule, point D is outside the polygon.\r\n   <\/p>\r\n   <p>The crossing test and the even-odd rule are easy to understand.  The challenge is to avoid getting tripped up in the special\r\n      cases.  The troublesome cases include rays intersecting vertices, edge intersections, and coincident edges.  Another case\r\n      is when a ray is coincident with an edge.  Here are some diagrams to illustrate.  (Note that in polygon 7 there are two coincident\r\n      edges on the left side of the polygon.)\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">subplot(2,2,1)\r\nplot([20 30 40 30 20], [30 20 30 40 30]);\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\nplot([10 50], [30 30], <span style=\"color: #A020F0\">'r'<\/span>)\r\nhold <span style=\"color: #A020F0\">off<\/span>\r\naxis <span style=\"color: #A020F0\">off<\/span>\r\ntitle(<span style=\"color: #A020F0\">'Polygon 4'<\/span>), ylim([10 50])\r\n\r\nsubplot(2,2,2)\r\nplot([20 30 40 50 60 20], [30 10 20 10 30 30]);\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\nplot([10 70], [10 10], <span style=\"color: #A020F0\">'r'<\/span>)\r\nhold <span style=\"color: #A020F0\">off<\/span>\r\naxis <span style=\"color: #A020F0\">off<\/span>\r\ntitle(<span style=\"color: #A020F0\">'Polygon 5'<\/span>), ylim([0 40])\r\n\r\nsubplot(2,2,3)\r\nplot([20 50 20 50 20], [20 20 60 60 20]);\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\nplot([10 60], [40 40], <span style=\"color: #A020F0\">'r'<\/span>)\r\nhold <span style=\"color: #A020F0\">off<\/span>\r\naxis <span style=\"color: #A020F0\">off<\/span>\r\ntitle(<span style=\"color: #A020F0\">'Polygon 6'<\/span>), ylim([10 70])\r\n\r\nsubplot(2,2,4)\r\nplot([20 60 60 20 20 50 20 20], <span style=\"color: #0000FF\">...<\/span>\r\n    [20 20 50 50 20 35 50 20]);\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\nplot([10 70],[35 35],<span style=\"color: #A020F0\">'r'<\/span>)\r\nhold <span style=\"color: #A020F0\">off<\/span>\r\naxis <span style=\"color: #A020F0\">off<\/span>\r\ntitle(<span style=\"color: #A020F0\">'Polygon 7'<\/span>), ylim([10 60])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/102\/roipoly2_03.png\"> <p>In my next post on this topic, I'll get into the specific algorithm used by the Image Processing Toolbox functions <tt>polymask<\/tt> and <tt>roipoly<\/tt>.\r\n   <\/p>\r\n   <p>Here's <a href=\"https:\/\/blogs.mathworks.com\/steve\/?p=99\">Part 1<\/a> of this topic.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_a1ed7265169349e3b82da45627c297ba() {\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='a1ed7265169349e3b82da45627c297ba ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' a1ed7265169349e3b82da45627c297ba';\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        author = 'Steve Eddins';\r\n        copyright = 'Copyright 2006 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 author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\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      -->\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_a1ed7265169349e3b82da45627c297ba()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.3<br><\/p>\r\n<\/div>\r\n<!--\r\na1ed7265169349e3b82da45627c297ba ##### SOURCE BEGIN #####\r\n%% POLY2MASK and ROIPOLY - Part 2\r\n% I'm familiar with two basic ways to determine whether a point is inside a\r\n% polygon.  The first is to compute the <http:\/\/en.wikipedia.org\/wiki\/Winding_number \r\n% winding number>, which is the number of times that a closed curve \r\n% encircles the point. This technique is used by the MATLAB function\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/inpolygon.html \r\n% inpolygon>.\r\n%\r\n% When computing point-inside-polygon for all the points on a pixel grid,\r\n% the crossing test is more commonly used.  You follow a ray from one side\r\n% of the image to the other, counting the number of times the ray crosses\r\n% an edge of the polygon.\r\n\r\nx1 = [30 80 60 30];\r\ny1 = [30 50 90 30];\r\nray_x = [20 90];\r\nray_y = [70 70];\r\npoints_x = [30 60 80];\r\npoints_y = [70 70 70];\r\nplot(x1,y1)\r\nhold on\r\nplot(ray_x,ray_y, 'r')\r\nplot(points_x,points_y,'Marker','o','MarkerSize',4,'Color','k',...\r\n    'MarkerFaceColor','k','LineStyle','none')\r\ntext(30,70,'A','VerticalAlignment','bottom')\r\ntext(60,70,'B','VerticalAlignment','bottom')\r\ntext(80,70,'C','VerticalAlignment','bottom')\r\naxis off\r\nhold off\r\ntitle('Polygon 1')\r\n\r\n%%\r\n% At point A, the ray has not crossed a polygon edge; A is outside the\r\n% polygon.  At point B, the ray has crossed a polygon edge one time; B is\r\n% inside.  At point C, the ray has crossed a polygon edge twice; C is\r\n% outside.\r\n%\r\n% Polygons can get much more complex than a triangle, of course.  Here are\r\n% a couple of convex, nonsimple polygons.\r\n\r\nsubplot(2,1,1)\r\nplot([30 70 70 30 30], [30 70 30 70 30])\r\nhold on\r\nplot([20 80],[60 60],'r')\r\nhold off\r\naxis off\r\ntitle('Polygon 2')\r\n\r\nsubplot(2,1,2)\r\nplot([30 70 70 40 40 60 60 30 30], ...\r\n    [30 30 55 55 35 35 60 60 30])\r\nhold on\r\nplot([20 80],[45 45],'r')\r\nplot(50,45,'Marker','o','MarkerSize',4,'MarkerFaceColor','k')\r\ntext(50,45,'D','VerticalAlignment','bottom')\r\nylim([25 75])\r\nhold off\r\naxis off\r\ntitle('Polygon 3')\r\n\r\n%%\r\n% In polygon 2, the ray crosses into and then out of the polygon twice.  Polygon\r\n% 3 is even more interesting.  Is point D inside or outside the polygon?\r\n% The answer is a matter of convention.  A commonly-used convention is the\r\n% _even-odd_ rule.  A point is outside the polygon if there have been an\r\n% even number of edge crossings.  A point is inside there have been an odd\r\n% number.  By this rule, point D is outside the polygon.\r\n%\r\n% The crossing test and the even-odd rule are easy to understand.  The\r\n% challenge is to avoid getting tripped up in the special cases.  The\r\n% troublesome cases include rays intersecting vertices, edge intersections,\r\n% and coincident edges.  Another case is when a ray is coincident with an\r\n% edge.  Here are some diagrams to illustrate.  (Note that in polygon 7\r\n% there are two coincident edges on the left side of the polygon.)\r\n\r\nsubplot(2,2,1)\r\nplot([20 30 40 30 20], [30 20 30 40 30]);\r\nhold on\r\nplot([10 50], [30 30], 'r')\r\nhold off\r\naxis off\r\ntitle('Polygon 4'), ylim([10 50])\r\n\r\nsubplot(2,2,2)\r\nplot([20 30 40 50 60 20], [30 10 20 10 30 30]);\r\nhold on\r\nplot([10 70], [10 10], 'r')\r\nhold off\r\naxis off\r\ntitle('Polygon 5'), ylim([0 40])\r\n\r\nsubplot(2,2,3)\r\nplot([20 50 20 50 20], [20 20 60 60 20]);\r\nhold on\r\nplot([10 60], [40 40], 'r')\r\nhold off\r\naxis off\r\ntitle('Polygon 6'), ylim([10 70])\r\n\r\nsubplot(2,2,4)\r\nplot([20 60 60 20 20 50 20 20], ...\r\n    [20 20 50 50 20 35 50 20]);\r\nhold on\r\nplot([10 70],[35 35],'r')\r\nhold off\r\naxis off\r\ntitle('Polygon 7'), ylim([10 60])\r\n\r\n%%\r\n% In my next post on this topic, I'll get into the specific algorithm used\r\n% by the Image Processing Toolbox functions \r\n% <https:\/\/www.mathworks.com\/help\/images\/index.htmlpoly2mask.html\r\n% |polymask|> and \r\n% <https:\/\/www.mathworks.com\/help\/images\/index.htmlroipoly.html\r\n% |roipoly|>.\r\n%\r\n% Here's <https:\/\/blogs.mathworks.com\/steve\/?p=99 Part 1> of this topic.\r\n\r\n##### SOURCE END ##### a1ed7265169349e3b82da45627c297ba\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   I'm familiar with two basic ways to determine whether a point is inside a polygon.  The first is to compute the winding number, which is the number of times that a closed curve encircles the... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2006\/12\/13\/poly2mask-and-roipoly-part-2\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[28,1],"tags":[50,90,68,72,78,52,298],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/102"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=102"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/102\/revisions"}],"predecessor-version":[{"id":2216,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/102\/revisions\/2216"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=102"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=102"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=102"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}