<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sticky Coding - Android Developer</title>
	<atom:link href="http://stickycoding.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://stickycoding.com</link>
	<description>Redefining Awesome</description>
	<lastBuildDate>Sat, 03 Jul 2010 11:04:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Point in a (convex) polygon</title>
		<link>http://stickycoding.com/2010/07/03/point-in-a-convex-polygon/</link>
		<comments>http://stickycoding.com/2010/07/03/point-in-a-convex-polygon/#comments</comments>
		<pubDate>Sat, 03 Jul 2010 10:49:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Game Developement]]></category>

		<guid isPermaLink="false">http://stickycoding.com/?p=5</guid>
		<description><![CDATA[So, I may as-well start this new (spam-free!) blog up with something which I implemented into a game I'm working on last night. I make no promises that it's optimized, there's probably quicker ways. Thanks to evancharlton of #android-dev for the guidance, he requested I write this up, so it's for you! As with all [...]]]></description>
			<content:encoded><![CDATA[<p>So, I may as-well start this new (spam-free!) blog up with something which I implemented into a game I'm working on last night. I make no promises that it's optimized, there's probably quicker ways.</p>
<p>Thanks to evancharlton of #android-dev for the guidance, he requested I write this up, so it's for you!</p>
<p>As with all things I'll be putting in this section, it can easily be applied to other languages. But I'm writing in Java (Android-specific is my platform of choice, at the minute), and also because it's fairly easy to understand.</p>
<p>I already have my polygons vertices stored, and have written an algorithm to find their position when this polygon is translated/rotated. This was all set up when I wrote my separating axis theorem collision detection algorithm.</p>
<p>All I needed was an algorithm to check whether a polygon on screen was touched, that is, determine whether a specific point is inside the polygon. This, for some reason, I couldn't think up myself ...</p>
<p>A point is inside a (convex) polygon when the condition below is true for all edges.</p>
<blockquote><p>All points (that is, your test point and all polygon vertices) are wholly on one side of an edge.</p></blockquote>
<p>In a convex polygon, we can simplify things, because we know that for every edge - the vertices must all be on the same side of the edge anyway. So we need only check one vertex and the test point.</p>
<p>This meant coming up with a simple algorithm to test it, which is easy enough:</p>
<ol>
<li>We begin with a set of vertices, and a test point.</li>
<li>Calculate the edge, and hence the normal axis.</li>
<li>Calculate (vertexDot) the dot product of the axis, and a vertex which does not form part of the edge.</li>
<li>Calculate (pointDot) the dot product of the axis, and the test point.</li>
<li>If vertexDot and pointDot are on opposite sides to the edge, the point cannot be inside the polygon, return false.</li>
<li>Repeat steps 2 to 5 for all edges.</li>
<li>If still alive, the point must be inside the polygon, return true.</li>
</ol>
<p>It isn't as difficult as it seemed before, so let's write some code <img src='http://stickycoding.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">boolean</span> isPointInPolygon<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> vertexCount, <span style="color: #003399;">Vector</span> vertex<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>, <span style="color: #003399;">Vector</span> testPoint<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">/* Loop over all edges, the number of edges == number of vertices */</span>
	<span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> vertexCount<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* Start the edge at i, go to i + 1. Be sure to check that we are looping back to the start */</span>
		<span style="color: #000066; font-weight: bold;">int</span> edgeStartIndex <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">int</span> edgeEndIndex <span style="color: #339933;">=</span> i <span style="color: #339933;">&lt;</span> vertexCount <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">?</span> i <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* We choose the next vertex in the polygon for testing, making sure we loop if necessary */</span>
		<span style="color: #000066; font-weight: bold;">int</span> testIndex <span style="color: #339933;">=</span> edgeEndIndex <span style="color: #339933;">&lt;</span> vertexCount <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">?</span> edgeEndIndex <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* Fetch our vertex objects, each contains an X and Y value */</span>
		<span style="color: #003399;">Vector</span> edgeStartVertex <span style="color: #339933;">=</span> vertex<span style="color: #009900;">&#91;</span>edgeStartIndex<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">Vector</span> edgeEndVertex <span style="color: #339933;">=</span> vertex<span style="color: #009900;">&#91;</span>edgeEndIndex<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">Vector</span> testVertex <span style="color: #339933;">=</span> vertex<span style="color: #009900;">&#91;</span>testIndex<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* Calculate the edge, simply (dx, dy) */</span>
		<span style="color: #000066; font-weight: bold;">float</span> edgeX <span style="color: #339933;">=</span> edgeEndVertex.<span style="color: #006633;">X</span> <span style="color: #339933;">-</span> edgeStartVertex.<span style="color: #006633;">X</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">float</span> edgeY <span style="color: #339933;">=</span> edgeEndVertex.<span style="color: #006633;">Y</span> <span style="color: #339933;">-</span> edgeStartVertex.<span style="color: #006633;">Y</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* Find the normal. For speed, we do not need to normalize this vector (note, normal does not mean normalised) Note that my vertices are ordered clockwise, you would have to flip the signs here if anticlockwise */</span>
		<span style="color: #000066; font-weight: bold;">float</span> axisX <span style="color: #339933;">=</span> edgeY<span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">float</span> axisY <span style="color: #339933;">=</span> <span style="color: #339933;">-</span>edgeX<span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* Note, calculating dot products is simple: 
			dot([x1, y1], [x2, y2]) = (x1 * x2) + (y1 * 2) */</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* Because our normal axis does not necessarily have its origin at the edge, we must find the dot product of one of the edges vertices */</span>
		<span style="color: #000066; font-weight: bold;">float</span> axisDot <span style="color: #339933;">=</span> dot<span style="color: #009900;">&#40;</span>axisX, axisY, edgeStartVertex.<span style="color: #006633;">X</span>, edgeStartVertex.<span style="color: #006633;">Y</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* Calculate the dot product of the third vertex */</span>
		<span style="color: #000066; font-weight: bold;">float</span> vertexDot <span style="color: #339933;">=</span> dot<span style="color: #009900;">&#40;</span>axisX, axisY, testVertex.<span style="color: #006633;">X</span>, testVertex.<span style="color: #006633;">Y</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* Calculate the dot product of our test point */</span>
		<span style="color: #000066; font-weight: bold;">float</span> pointDot <span style="color: #339933;">=</span> dot<span style="color: #009900;">&#40;</span>axisX, axisY, testPoint.<span style="color: #006633;">X</span>, testPoint.<span style="color: #006633;">Y</span><span style="color: #009900;">&#41;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* Determine whether our vertexDot and pointDot lay on opposing sides of axisDot, if so, exit now. 
			Note the use of &gt;=, &lt;=, &gt; and &lt;. These are used in such a way that the testVertex is 'allowed' to exist in line with the axis, but our testPoint is not. This way, if testPoint were to lay on the axis, it would be considered as being inside the polygon. */</span>	   
		<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span>nextDot <span style="color: #339933;">&gt;=</span> axisDot <span style="color: #339933;">&amp;&amp;</span> testDot <span style="color: #339933;">&lt;</span> axisDot<span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>nextDot <span style="color: #339933;">&lt;=</span> axisDot <span style="color: #339933;">&amp;&amp;</span> testDot <span style="color: #339933;">&gt;</span> axisDot<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">/* If we have reached this far, the point must be inside the polygon, so let the world know! */</span>
	<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://stickycoding.com/2010/07/03/point-in-a-convex-polygon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
