{"id":433,"date":"2025-03-18T18:13:00","date_gmt":"2025-03-18T18:13:00","guid":{"rendered":"https:\/\/permutationcity.co.uk\/bp\/?p=433"},"modified":"2025-03-18T19:41:19","modified_gmt":"2025-03-18T19:41:19","slug":"area-of-a-polygon","status":"publish","type":"post","link":"https:\/\/permutationcity.co.uk\/bp\/2025\/03\/18\/area-of-a-polygon\/","title":{"rendered":"Area of a polygon"},"content":{"rendered":"\n<p>I wasn&#8217;t planning on a follow up but here we go.\nYou&#8217;ve calculated the\n<a href=\"https:\/\/permutationcity.co.uk\/bp\/2024\/03\/07\/ai-assistance\/\">closest distance between a point and a line<\/a> and\n<a href=\"https:\/\/permutationcity.co.uk\/bp\/2024\/12\/01\/area-of-a-triangle\/\">calculated the area of a triangle<\/a>\nbut now want more,\nthe area of a polygon!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"winging-it\">Winging it<\/h2>\n\n\n\n<p>Let&#8217;s try to remember our school geometry lessons.\nYou can divide any polygon up into triangles.\nSo do that, calculate the area of each and add it all together?\nThat&#8217;s going be easy for\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Convex_polygon\">convex polygons<\/a> but\nI&#8217;m not sure about\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Concave_polygon\">concave polygons<\/a>.\nFor the first any\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Triangle_fan\">triangle fan<\/a>\nor\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Triangle_strip\">triangle strip<\/a>\nis going to work but\nnot for the second.\nLots of nieve triangulations methods are going to go outside the bounds of the polygon.\nFortunately it looks like there&#8217;s hope with the\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Two_ears_theorem\">two ears theorem<\/a>.\nThat&#8217;s not what this post is about so I&#8217;m just going to think about convex polygons for now.<\/p>\n\n\n\n<p>Remember we have:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-c++src&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C++&quot;,&quot;language&quot;:&quot;C++&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;cpp&quot;}\">struct Point {\n    double x, y;\n};\n\nstruct Triangle {\n    std::array&lt;Point, 3&gt; points;\n};\n\nfloat AreaOf(Triangle triangle);<\/pre><\/div>\n\n\n\n<p>So could just do this:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-c++src&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C++&quot;,&quot;language&quot;:&quot;C++&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;cpp&quot;}\">struct Polygon {\n    std::vector&lt;Point&gt; points;\n};\n\nfloat AreaOf(const Polygon&amp; polygon) {\n    float total = 0;\n    const auto initial = polygon.points[0];\n    auto previous = polygon.points[1];\n    for (size_t i = 2; i &lt; polygon.size(); i++) {\n        const auto current = polygon.points[i];\n        total += AreaOf(Triangle(initial, previous, current);\n        previous = current;\n    }\n    return total;\n}<\/pre><\/div>\n\n\n\n<p>I&#8217;m being lazy here and just assuming that the polygon has at least 3 points but\notherwise it&#8217;s sound.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"area-of-a-trapezium\">Area of a trapezium<\/h2>\n\n\n\n<p>We need to take a brief detour.\nA <a href=\"https:\/\/en.wikipedia.org\/wiki\/Trapezoid\">trapezium<\/a> or trapezoid\nis a four sided shape with two parallel sides.\nWe are interested in a right trapezium where one of the angled sides is at 90 degrees and\nthe other is unconstrained.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"36\" height=\"54\" src=\"https:\/\/permutationcity.co.uk\/bp\/wp-content\/uploads\/2025\/03\/trapezium.svg\" alt=\"\" class=\"wp-image-425\" style=\"width:240px\"\/><\/figure>\n\n\n\n<p>Think of it as a rectangle with a triangle on top.\nIt&#8217;s area is:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>(area of rectangle) + (area of triangle)<\/p>\n<\/blockquote>\n\n\n\n<p>or:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>(b * h) + ((a &#8211; b) * h \/ 2)<\/p>\n<\/blockquote>\n\n\n\n<p>or:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>b * h + a * h \/ 2 &#8211; b * h \/ 2<\/p>\n<\/blockquote>\n\n\n\n<p>or:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>(a + b) * h \/ 2<\/p>\n<\/blockquote>\n\n\n\n<p>Which matches the\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Trapezoid#Area\">general case<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"trapezium-formula\">Trapezium formula<\/h2>\n\n\n\n<p>We can calculate the area of a polygon based on the area of it&#8217;s triangles.\nCan we do better?\nIf you care about such things we already know each triangle area calculation takes\n6 additions \/ subtractions, 7 multiplications, 1 division, 1 square root and 1 branch.\nLet&#8217;s simplify and call it 16 operations per triangle.\nSo if our polygon has 5 points, i.e. is made of 3 triangles,\nthen we have 48 operations.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"80\" height=\"65\" src=\"https:\/\/permutationcity.co.uk\/bp\/wp-content\/uploads\/2025\/03\/polygon_basic.svg\" alt=\"\" class=\"wp-image-430\" style=\"width:240px\"\/><\/figure>\n\n\n\n<p>Instead we can instead take the polygon and use it to make trapeziums.\nTake two points at a time and project them down on to the x-axis.\nSometimes the next point takes us to the right and\nsometimes to the left.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Rightward<\/th><th class=\"has-text-align-center\" data-align=\"center\">Leftward<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><img loading=\"lazy\" decoding=\"async\" width=\"240\" height=\"195\" class=\"wp-image-431\" style=\"width: 240px;\" src=\"https:\/\/permutationcity.co.uk\/bp\/wp-content\/uploads\/2025\/03\/polygon_p0p1.svg\" alt=\"\"><\/td><td class=\"has-text-align-center\" data-align=\"center\"><img loading=\"lazy\" decoding=\"async\" width=\"240\" height=\"195\" class=\"wp-image-428\" style=\"width: 240px;\" src=\"https:\/\/permutationcity.co.uk\/bp\/wp-content\/uploads\/2025\/03\/polygon_p3p4.svg\" alt=\"\"><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><img loading=\"lazy\" decoding=\"async\" width=\"240\" height=\"195\" class=\"wp-image-426\" style=\"width: 240px;\" src=\"https:\/\/permutationcity.co.uk\/bp\/wp-content\/uploads\/2025\/03\/polygon_p1p2.svg\" alt=\"\"><\/td><td class=\"has-text-align-center\" data-align=\"center\"><img loading=\"lazy\" decoding=\"async\" width=\"240\" height=\"195\" class=\"wp-image-429\" style=\"width: 240px;\" src=\"https:\/\/permutationcity.co.uk\/bp\/wp-content\/uploads\/2025\/03\/polygon_p4p0.svg\" alt=\"\"><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><img loading=\"lazy\" decoding=\"async\" width=\"240\" height=\"195\" class=\"wp-image-428\" style=\"width: 240px;\" src=\"https:\/\/permutationcity.co.uk\/bp\/wp-content\/uploads\/2025\/03\/polygon_p3p4.svg\" alt=\"\"><\/td><td class=\"has-text-align-center\" data-align=\"center\"><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>As <code>h<\/code> for each trapezium comes from the x-difference between points sometimes this will be positive and\nsometimes negative.\nWe calculate the area of each trapezium, for example:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>(y0 + y1) * (x1 &#8211; x0) \/ 2<\/p>\n<\/blockquote>\n\n\n\n<p>Then add them all up, respecting their positive and negative areas, and take the absolute value.\nAs many of these areas are outside the polygon it seems a bit like magic.\nFor this example you can think it through like this:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"280\" height=\"70\" src=\"https:\/\/permutationcity.co.uk\/bp\/wp-content\/uploads\/2025\/03\/polygon_summation.svg\" alt=\"\" class=\"wp-image-432\" style=\"width:960px\"\/><\/figure>\n\n\n\n<p>The first trapezium shown is an overestimate,\nthe next two are remove the right amount,\nthe next removes too much and\nthe final one corrects for this.<\/p>\n\n\n\n<p>In code we it&#8217;s just:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-c++src&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C++&quot;,&quot;language&quot;:&quot;C++&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;cpp&quot;}\">float AreaOf(const Polygon&amp; polygon) {\n    float total = 0;    \n    for (size_t i = 0; i &lt; polygon.size(); i++) {\n        const auto current = polygon.points[i];\n        const auto next = polygon.points[(i + 1) % polygons.size()];\n        total += (current.y + next.y) * (next.y - current.y);\n    }\n    return std::abs(0.5 * total);\n}<\/pre><\/div>\n\n\n\n<p>We now have 2 additions \/ subtractions, 1 multiplication, 1 modulo per triangle plus\n1 multiplication and 1 branch at the end.\nLet&#8217;s simplify again and call it 4 operations per triangle plus 2 overall.\nSo if our polygon has 5 points, 3 triangles,\nthen it&#8217;s only 14 operations.\nNice.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"in-the-end\">In the end<\/h2>\n\n\n\n<p>If I was writing a geometry library I would go away and\nwrite some tests to check all this.\nIs it producing the right results?\nIs it faster than the nieve method?\nMaybe I&#8217;d use the nieve method to unit test this one.\nIn this case I just thought it was an interesting follow on.<\/p>\n\n\n\n<p>Do keep in mind that there are a lot of clever ideas out there.\nIf it feels like something should be a solved problem spend some time looking for an existing solution.\nThanks to this video on\n<a href=\"https:\/\/www.youtube.com\/watch?v=GXh0Vxg7AnQ\">soft body procedural animation<\/a>\nfor providing this one.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I wasn&#8217;t planning on a follow up but here we go. You&#8217;ve calculated the closest distance between a point and a line and calculated the area of a triangle but now want more, the area of a polygon! Winging it Let&#8217;s try to remember our school geometry lessons. You can divide any polygon up into [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[1],"tags":[22,40],"class_list":["post-433","post","type-post","status-publish","format-standard","hentry","category-general","tag-algorithms","tag-geometry"],"_links":{"self":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/433","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/comments?post=433"}],"version-history":[{"count":3,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/433\/revisions"}],"predecessor-version":[{"id":438,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/433\/revisions\/438"}],"wp:attachment":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/media?parent=433"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/categories?post=433"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/tags?post=433"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}