<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Algorithm on bramp.net</title>
    <link>https://blog.bramp.net/</link>
    <description>Recent content in Algorithm on bramp.net</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-GB</language>
    <lastBuildDate>Sat, 26 Nov 2011 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://blog.bramp.net/tags/algorithm/" rel="self" type="application/rss+xml" />
    
    <item>
      <title>PHP Polygon Clipper using the Sutherland-Hodgman algorithm</title>
      <link>https://blog.bramp.net/post/2011/11/26/php-polygon-clipper-using-the-sutherland-hodgman-algorithm/</link>
      <pubDate>Sat, 26 Nov 2011 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2011/11/26/php-polygon-clipper-using-the-sutherland-hodgman-algorithm/</guid>
      <description><p>I wrote a PHP implementation of the polygon clipping algorithm by Sutherland-Hodgman. Available below, or from <a href="https://gist.github.com/bramp/1396058#file-clip-class-php">github</a>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-php" data-lang="php"><span class="line"><span class="cl"><span class="o">&lt;?</span><span class="nx">php</span>
</span></span><span class="line"><span class="cl"><span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd"> * Polygon Clipping
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @author Andrew Brampton me &lt;at&gt; bramp &lt;dot&gt; net
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @url http://bramp.net/blog/2011/11/php-polygon-clipper-using-the-sutherland-hodgman-algorithm/
</span></span></span><span class="line"><span class="cl"><span class="sd"> *
</span></span></span><span class="line"><span class="cl"><span class="sd"> * Based on the Sutherland-Hodgman algorithm (1974).
</span></span></span><span class="line"><span class="cl"><span class="sd"> * http://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm
</span></span></span><span class="line"><span class="cl"><span class="sd"> *
</span></span></span><span class="line"><span class="cl"><span class="sd"> * This approache assumes four clip edges (the bounding box).
</span></span></span><span class="line"><span class="cl"><span class="sd"> * The original algorithm iterated though each clip edge, and then each point. Instead
</span></span></span><span class="line"><span class="cl"><span class="sd"> * we iterate each point, and then clip edge. This reduces the memory usage. TODO Measure if that is useful!
</span></span></span><span class="line"><span class="cl"><span class="sd"> *
</span></span></span><span class="line"><span class="cl"><span class="sd"> * Usage:
</span></span></span><span class="line"><span class="cl"><span class="sd"> *   require(&#39;clip.class.php&#39;);
</span></span></span><span class="line"><span class="cl"><span class="sd"> * 
</span></span></span><span class="line"><span class="cl"><span class="sd"> *   // Create a cliper with bounds defined by the points (x1, y1)-(x2,y2);
</span></span></span><span class="line"><span class="cl"><span class="sd"> *   $clip = new SutherlandHodgman($x1, $y1, $x2, $y2);
</span></span></span><span class="line"><span class="cl"><span class="sd"> * 
</span></span></span><span class="line"><span class="cl"><span class="sd"> *   // Create array of 2 tuple coordinates
</span></span></span><span class="line"><span class="cl"><span class="sd"> *   $points = { {x1, y1}, {x2, y2} ... {xN, yN} }&#39;
</span></span></span><span class="line"><span class="cl"><span class="sd"> *
</span></span></span><span class="line"><span class="cl"><span class="sd"> *   // Clip! The resulting array will only have points within the bounds
</span></span></span><span class="line"><span class="cl"><span class="sd"> *   $points = $clip-&gt;clip($points);
</span></span></span><span class="line"><span class="cl"><span class="sd"> *
</span></span></span><span class="line"><span class="cl"><span class="sd"> */</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">abstract</span> <span class="k">class</span> <span class="nc">Edge</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">var</span> <span class="nv">$bound</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span><span class="nv">$bound</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span> <span class="o">=</span> <span class="nv">$bound</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * Is point $p inside the bounds. Techinically is it on the inside
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * of the infinite edge defined by $bound
</span></span></span><span class="line"><span class="cl"><span class="sd">	 *
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @param point $p
</span></span></span><span class="line"><span class="cl"><span class="sd">	 */</span>
</span></span><span class="line"><span class="cl">	<span class="k">abstract</span> <span class="k">function</span> <span class="nf">inside</span><span class="p">(</span><span class="nv">$p</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * Finds the intersection with the bounds, on the line p1-p2
</span></span></span><span class="line"><span class="cl"><span class="sd">	 *
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @param point $p1 The point inside the bounds
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @param point $p2 The point outside the bounds
</span></span></span><span class="line"><span class="cl"><span class="sd">	 */</span>
</span></span><span class="line"><span class="cl">	<span class="k">abstract</span> <span class="k">function</span> <span class="nf">intersect</span><span class="p">(</span><span class="nv">$p1</span><span class="p">,</span> <span class="nv">$p2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">abstract</span> <span class="k">class</span> <span class="nc">HorzEdge</span> <span class="k">extends</span> <span class="nx">Edge</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * Returns the point at which the line $p1-$p2 hits the horz boundary
</span></span></span><span class="line"><span class="cl"><span class="sd">	 *
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @param point $p1
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @param point $p2
</span></span></span><span class="line"><span class="cl"><span class="sd">	 *
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @return point
</span></span></span><span class="line"><span class="cl"><span class="sd">	 */</span>
</span></span><span class="line"><span class="cl">	<span class="k">function</span> <span class="nf">intersect</span><span class="p">(</span><span class="nv">$p1</span><span class="p">,</span> <span class="nv">$p2</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nv">$dY</span> <span class="o">=</span> <span class="nv">$p2</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="k">if</span> <span class="p">(</span><span class="nv">$dY</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">			<span class="k">return</span> <span class="k">array</span><span class="p">(</span><span class="nv">$p1</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="nv">$dX</span> <span class="o">=</span> <span class="nv">$p2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">		<span class="nv">$dY2</span> <span class="o">=</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span> <span class="o">-</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="k">return</span> <span class="k">array</span><span class="p">((</span><span class="nv">$dY2</span> <span class="o">/</span> <span class="nv">$dY</span><span class="p">)</span> <span class="o">*</span> <span class="nv">$dX</span> <span class="o">+</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">abstract</span> <span class="k">class</span> <span class="nc">VertEdge</span> <span class="k">extends</span> <span class="nx">Edge</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd">	* Returns the point at which the line $p1-$p2 hits the vertical boundary
</span></span></span><span class="line"><span class="cl"><span class="sd">	*
</span></span></span><span class="line"><span class="cl"><span class="sd">	* @param point $p1
</span></span></span><span class="line"><span class="cl"><span class="sd">	* @param point $p2
</span></span></span><span class="line"><span class="cl"><span class="sd">	*
</span></span></span><span class="line"><span class="cl"><span class="sd">	* @return point
</span></span></span><span class="line"><span class="cl"><span class="sd">	*/</span>
</span></span><span class="line"><span class="cl">	<span class="k">function</span> <span class="nf">intersect</span><span class="p">(</span><span class="nv">$p1</span><span class="p">,</span> <span class="nv">$p2</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nv">$dX</span> <span class="o">=</span> <span class="nv">$p2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="k">if</span> <span class="p">(</span><span class="nv">$dX</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">			<span class="k">return</span> <span class="k">array</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span><span class="p">,</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="nv">$dY</span> <span class="o">=</span> <span class="nv">$p2</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">		<span class="nv">$dX2</span> <span class="o">=</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span> <span class="o">-</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="k">return</span> <span class="k">array</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span><span class="p">,</span> <span class="p">(</span><span class="nv">$dX2</span> <span class="o">/</span> <span class="nv">$dX</span><span class="p">)</span> <span class="o">*</span> <span class="nv">$dY</span> <span class="o">+</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">function</span> <span class="nf">intersect</span><span class="p">(</span><span class="nv">$p1</span><span class="p">,</span> <span class="nv">$p2</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nv">$dX</span> <span class="o">=</span> <span class="nv">$p2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">	<span class="nv">$dY</span> <span class="o">=</span> <span class="nv">$p2</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="nv">$p1</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">RightEdge</span> <span class="k">extends</span> <span class="nx">VertEdge</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">function</span> <span class="nf">inside</span><span class="p">(</span><span class="nv">$p</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span> <span class="nv">$p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&lt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span><span class="p">;</span> <span class="c1">//X
</span></span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">LeftEdge</span> <span class="k">extends</span> <span class="nx">VertEdge</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">function</span> <span class="nf">inside</span><span class="p">(</span><span class="nv">$p</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span> <span class="nv">$p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span><span class="p">;</span> <span class="c1">//X
</span></span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">TopEdge</span> <span class="k">extends</span> <span class="nx">HorzEdge</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">function</span> <span class="nf">inside</span><span class="p">(</span><span class="nv">$p</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span> <span class="nv">$p</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span><span class="p">;</span> <span class="c1">//Y
</span></span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">BottomEdge</span> <span class="k">extends</span> <span class="nx">HorzEdge</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">function</span> <span class="nf">inside</span><span class="p">(</span><span class="nv">$p</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span> <span class="nv">$p</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&lt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bound</span><span class="p">;</span> <span class="c1">//Y
</span></span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">function</span> <span class="nf">check_point</span><span class="p">(</span><span class="nv">$p</span><span class="p">,</span> <span class="nv">$msg</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">if</span> <span class="p">(</span><span class="nv">$p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&lt;</span> <span class="o">-</span><span class="mi">180</span> <span class="o">||</span> <span class="nv">$p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">180</span> <span class="o">||</span> <span class="nv">$p</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&lt;</span> <span class="o">-</span><span class="mi">90</span> <span class="o">||</span> <span class="nv">$p</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">90</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nx">var_dump</span><span class="p">(</span><span class="nv">$p</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="nx">var_dump</span><span class="p">(</span><span class="nx">debug_backtrace</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">		<span class="k">die</span><span class="p">(</span><span class="s2">&#34;Something went wrong! </span><span class="si">$msg</span><span class="s2">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">SutherlandHodgman</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">var</span> <span class="nv">$edges</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * Construct with the bounds of the clipped area
</span></span></span><span class="line"><span class="cl"><span class="sd">	 *
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @param unknown_type $x1
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @param unknown_type $y1
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @param unknown_type $x2
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @param unknown_type $y2
</span></span></span><span class="line"><span class="cl"><span class="sd">	 */</span>
</span></span><span class="line"><span class="cl">	<span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span><span class="nv">$x1</span><span class="p">,</span> <span class="nv">$y1</span><span class="p">,</span> <span class="nv">$x2</span><span class="p">,</span> <span class="nv">$y2</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nx">assert</span><span class="p">(</span><span class="nv">$x1</span> <span class="o">&lt;</span> <span class="nv">$x2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="nx">assert</span><span class="p">(</span><span class="nv">$y1</span> <span class="o">&lt;</span> <span class="nv">$y2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">edges</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">			<span class="k">new</span> <span class="nx">RightEdge</span><span class="p">(</span><span class="nv">$x2</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">			<span class="k">new</span> <span class="nx">TopEdge</span><span class="p">(</span><span class="nv">$y1</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">			<span class="k">new</span> <span class="nx">LeftEdge</span><span class="p">(</span><span class="nv">$x1</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">			<span class="k">new</span> <span class="nx">BottomEdge</span><span class="p">(</span><span class="nv">$y2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * Clip the array of (x,y) coords to the bounds
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * specified in the constructor
</span></span></span><span class="line"><span class="cl"><span class="sd">	 *
</span></span></span><span class="line"><span class="cl"><span class="sd">	 * @param array $points
</span></span></span><span class="line"><span class="cl"><span class="sd">	 */</span>
</span></span><span class="line"><span class="cl">	<span class="k">function</span> <span class="nf">clip</span><span class="p">(</span><span class="nv">$points</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="k">if</span> <span class="p">(</span><span class="nx">count</span><span class="p">(</span><span class="nv">$points</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">			<span class="k">throw</span> <span class="s2">&#34;Clip requires a polygon of three points or more&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="k">foreach</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">edges</span> <span class="k">as</span> <span class="nv">$edge</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">			<span class="nv">$output</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">			<span class="k">if</span> <span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$points</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">				<span class="k">return</span> <span class="nv">$points</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">			<span class="nv">$previous</span> <span class="o">=</span> <span class="nv">$points</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">			<span class="nv">$previousInside</span> <span class="o">=</span> <span class="nv">$edge</span><span class="o">-&gt;</span><span class="na">inside</span><span class="p">(</span><span class="nv">$previous</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">			<span class="c1">// Add the first onto the end so it eventually gets processed
</span></span></span><span class="line"><span class="cl">			<span class="nv">$points_count</span> <span class="o">=</span> <span class="nx">count</span><span class="p">(</span><span class="nv">$points</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">			<span class="k">if</span> <span class="p">(</span><span class="nv">$points</span><span class="p">[</span><span class="nv">$points_count</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">!==</span> <span class="nv">$points</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">				<span class="nv">$points</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$points</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">				<span class="nv">$points_count</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">			<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">			<span class="k">for</span> <span class="p">(</span><span class="nv">$i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="nv">$i</span> <span class="o">&lt;</span> <span class="nv">$points_count</span><span class="p">;</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">				<span class="nv">$point</span> <span class="o">=</span> <span class="nv">$points</span><span class="p">[</span><span class="nv">$i</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">				<span class="nx">assert</span><span class="p">(</span><span class="nx">is_array</span><span class="p">(</span><span class="nv">$point</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">				<span class="nx">assert</span><span class="p">(</span><span class="nx">count</span><span class="p">(</span><span class="nv">$point</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">				<span class="nv">$inside</span> <span class="o">=</span> <span class="nv">$edge</span><span class="o">-&gt;</span><span class="na">inside</span><span class="p">(</span><span class="nv">$point</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">				<span class="k">if</span> <span class="p">(</span><span class="nv">$inside</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">					<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$previousInside</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">						<span class="nx">assert</span><span class="p">(</span><span class="o">!</span><span class="nv">$edge</span><span class="o">-&gt;</span><span class="na">inside</span><span class="p">(</span><span class="nv">$previous</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">						<span class="nv">$output</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$edge</span><span class="o">-&gt;</span><span class="na">intersect</span><span class="p">(</span><span class="nv">$point</span><span class="p">,</span> <span class="nv">$previous</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">					<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">					<span class="nv">$output</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$point</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">				<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$previousInside</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">					<span class="nx">assert</span><span class="p">(</span><span class="nv">$edge</span><span class="o">-&gt;</span><span class="na">inside</span><span class="p">(</span><span class="nv">$previous</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">					<span class="nv">$output</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$edge</span><span class="o">-&gt;</span><span class="na">intersect</span><span class="p">(</span><span class="nv">$previous</span><span class="p">,</span> <span class="nv">$point</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">				<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">				<span class="nv">$previous</span> <span class="o">=</span> <span class="nv">$point</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">				<span class="nv">$previousInside</span> <span class="o">=</span> <span class="nv">$inside</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">			<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">			<span class="nv">$points</span> <span class="o">=</span> <span class="nv">$output</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">		<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="k">return</span> <span class="nv">$output</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></description>
    </item>
    
  </channel>
</rss>
