<?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"
	>

<channel>
	<title>Pogopixels' Blog</title>
	<atom:link href="http://pogopixels.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://pogopixels.com/blog</link>
	<description>Just another WordPress weblog</description>
	<pubDate>Mon, 14 Jun 2010 19:20:19 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Using Gettext with the Qt Framework</title>
		<link>http://pogopixels.com/blog/using-gettext-with-the-qt-framework/</link>
		<comments>http://pogopixels.com/blog/using-gettext-with-the-qt-framework/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 19:14:34 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[Qt Framework]]></category>

		<category><![CDATA[gettext]]></category>

		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://pogopixels.com/blog/?p=113</guid>
		<description><![CDATA[The Qt Framework for some reason doesn&#8217;t provide any built-in support for Gettext, the quasi-standard for translating software programs. An alternative is provided, Qt Linguist, however there are several reasons why some may still prefer Gettext:

If your application is already partially translated using Gettext it&#8217;s much easier to keep on using it rather than converting [...]]]></description>
			<content:encoded><![CDATA[<p>The Qt Framework for some reason doesn&#8217;t provide any built-in support for <a href="http://www.gnu.org/software/gettext/">Gettext</a>, the quasi-standard for translating software programs. An alternative is provided, Qt Linguist, however there are several reasons why some may still prefer Gettext:</p>
<ul>
<li>If your application is already partially translated using Gettext it&#8217;s much easier to keep on using it rather than converting all your mo/po files to Qt&#8217;s format.</li>
<li>Another significant advantage of Gettext is that it doesn&#8217;t have any dependencies (unlike Qt Linguist which creates a dependency to the Qt Framework) and thus allows creating more portable code.</li>
</ul>
<p>So for these reasons, I&#8217;ve created a small library which parses and manages Gettext catalogues in Qt. The library includes a generic parser and a catalogue manager which can be used in any C++ project. On top of that, a Qt wrapper is provided for easy integration with the Qt framework.</p>
<p><strong>The library can be downloaded from the Google Code project:</strong></p>
<p><a href="http://code.google.com/p/simple-gettext/">Download the Gettext library for the Qt Framework</a></p>
<p>Setting up and using the library is easy:</p>
<pre class="syntax-highlight:cpp">#include &lt;QtGettext.h&gt;

QtGettext::instance()-&gt;setLocale(&quot;cn_TW&quot;); // Set the locale
QtGettext::instance()-&gt;setCatalogueName(&quot;catalogue&quot;); // Set the name of the mo files
QtGettext::instance()-&gt;setCatalogueLocation(&quot;Data/Locales&quot;); // Set the catalogue folder</pre>
<p>QtGettext is now set to use the file in <code>Data/Locales/cn_TW/catalogue.mo</code>.</p>
<p>Also note that if this file is not available, QtGettext will try to load <code>Data/Locales/cn/catalogue.mo</code> (if available) as an alternative.</p>
<p>To mark a string for translation, simply call:</p>
<pre class="syntax-highlight:cpp">QtGettext::instance()-&gt;getTranslation(&quot;Some string to be translated&quot;);</pre>
<p>Since this is rather long, a <code>_()</code> macro is also provided. It shortens the code to just:</p>
<pre class="syntax-highlight:cpp">_(&quot;Some string to be translated&quot;);</pre>
]]></content:encoded>
			<wfw:commentRss>http://pogopixels.com/blog/using-gettext-with-the-qt-framework/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Get the URL of an iPod or HD quality YouTube video</title>
		<link>http://pogopixels.com/blog/get-the-url-of-a-iphone-or-hd-quality-youtube-video/</link>
		<comments>http://pogopixels.com/blog/get-the-url-of-a-iphone-or-hd-quality-youtube-video/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 19:19:49 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
		
		<category><![CDATA[flash]]></category>

		<category><![CDATA[flv url]]></category>

		<category><![CDATA[hd]]></category>

		<category><![CDATA[high-resolution]]></category>

		<category><![CDATA[ipod]]></category>

		<category><![CDATA[youtube]]></category>

		<guid isPermaLink="false">http://pogopixels.com/blog/?p=101</guid>
		<description><![CDATA[I&#8217;ve described in a previous post how to get the URL of a YouTube video in Flash. However this method only returns the low-resolution quality video at 320&#215;240. Getting the high-res one is easy though - you just need to add a &#8220;fmt&#8221; parameter to the URL link.
These two values in particular can be interesting:
fmt=22: [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve described in a previous post <a href="getting-the-url-of-a-youtube-flv-file-in-flash">how to get the URL of a YouTube video in Flash</a>. However this method only returns the low-resolution quality video at 320&#215;240. Getting the high-res one is easy though - you just need to add a &#8220;fmt&#8221; parameter to the URL link.</p>
<p>These two values in particular can be interesting:</p>
<p><strong>fmt=22:</strong> This is an MP4 video in HD quality. On my tests, the resolution can go up to 1280 x 720.</p>
<p><strong>fmt=18:</strong> This is a 480 pixels wide version that can be used in portable devices such as iPods.</p>
<p>In order to use this additional parameter, just add an argument to the constructFLVURL method:</p>
<pre class="syntax-highlight:js">// Set &quot;format&quot; to 22 for the high resolution version, or 18 for the iPod one. Or just
// leave to -1 for the low res version.
private function constructFLVURL (video_id:String, t:String, format:Number = -1):String {
  var str:String = &quot;http://www.youtube.com/get_video.php?&quot;;
  str += &quot;video_id=&quot; + video_id;
  str += &quot;&amp;t=&quot; + t;
  if (format &gt;= 0) {
    str += &quot;&amp;fmt=&quot; + format;
  }
  return str;
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://pogopixels.com/blog/get-the-url-of-a-iphone-or-hd-quality-youtube-video/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Delete a file to the recycle bin from C++</title>
		<link>http://pogopixels.com/blog/delete-a-file-to-the-recycle-bin-from-cp/</link>
		<comments>http://pogopixels.com/blog/delete-a-file-to-the-recycle-bin-from-cp/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 21:16:34 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[Win32]]></category>

		<category><![CDATA[SHFileOperation]]></category>

		<guid isPermaLink="false">http://pogopixels.com/blog/?p=57</guid>
		<description><![CDATA[Today, I was looking for a way to delete a file to the recycle bin using C++, but couldn&#8217;t find any simple example, so here it is:
SHFILEOPSTRUCT operation;
operation.wFunc = FO_DELETE;
operation.pFrom = &#34;c:\\file\to\delete.txt&#34;;
operation.fFlags = FOF_ALLOWUNDO;

SHFileOperation(&#38;operation);
]]></description>
			<content:encoded><![CDATA[<p>Today, I was looking for a way to delete a file to the recycle bin using C++, but couldn&#8217;t find any simple example, so here it is:</p>
<pre class="syntax-highlight:cpp">SHFILEOPSTRUCT operation;
operation.wFunc = FO_DELETE;
operation.pFrom = &quot;c:\\file\to\delete.txt&quot;;
operation.fFlags = FOF_ALLOWUNDO;

SHFileOperation(&amp;operation);</pre>
]]></content:encoded>
			<wfw:commentRss>http://pogopixels.com/blog/delete-a-file-to-the-recycle-bin-from-cp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Get the 48&#215;48 or 256&#215;256 icon of a file on Windows</title>
		<link>http://pogopixels.com/blog/getting-the-48x48-or-256x256-icon-of-a-file-on-windows/</link>
		<comments>http://pogopixels.com/blog/getting-the-48x48-or-256x256-icon-of-a-file-on-windows/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 15:25:17 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[Win32]]></category>

		<category><![CDATA[icon]]></category>

		<category><![CDATA[SHGetFileInfo]]></category>

		<category><![CDATA[SHGetImageList]]></category>

		<guid isPermaLink="false">http://pogopixels.com/blog/?p=49</guid>
		<description><![CDATA[Getting the 16&#215;16 and 32&#215;32 icons on Windows is relatively easy and is often as simple as one call to ExtractIconEx.
However, getting the extra large (48&#215;48) and jumbo (256&#215;256) icons introduced respectively by XP and Vista is slighly more complex. This is normally done by:

Getting the file information, in particular the icon index, for the [...]]]></description>
			<content:encoded><![CDATA[<p>Getting the 16&#215;16 and 32&#215;32 icons on Windows is relatively easy and is often as simple as one call to <a title="ExtractIconEx Function" href="http://msdn.microsoft.com/en-us/library/ms648069(VS.85).aspx">ExtractIconEx</a>.</p>
<p>However, getting the extra large (48&#215;48) and jumbo (256&#215;256) icons introduced respectively by XP and Vista is slighly more complex. This is normally done by:</p>
<ol>
<li>Getting the file information, in particular the icon index, for the given file using <a title="SHGetFileInfo Function" href="http://msdn.microsoft.com/en-us/library/bb762179(VS.85).aspx">SHGetFileInfo</a></li>
<li>Retrieving the system image list where all the icons are stored</li>
<li>Casting the image list to an <a title="IImageList Interface" href="http://msdn.microsoft.com/en-us/library/bb761490(VS.85).aspx">IImageList</a> interface and getting the icon from there</li>
</ol>
<p>Below is the code I&#8217;m using in <a title="Appetizer" href="http://app.etizer.org">Appetizer</a> to retrieve the extra large icon. If needed it can easily be adapted to get the jumbo icon.</p>
<p><strong>Update:</strong> To do the same thing in C#, see the link in the comments below.</p>
<pre class="syntax-highlight:cpp">#include &lt;shlobj.h&gt;
#include &lt;shlguid.h&gt;
#include &lt;shellapi.h&gt;
#include &lt;commctrl.h&gt;
#include &lt;commoncontrols.h&gt;

// Get the icon index using SHGetFileInfo
SHFILEINFOW sfi = {0};
SHGetFileInfo(filePath, -1, &amp;sfi, sizeof(sfi), SHGFI_SYSICONINDEX);

// Retrieve the system image list.
// To get the 48x48 icons, use SHIL_EXTRALARGE
// To get the 256x256 icons (Vista only), use SHIL_JUMBO
HIMAGELIST* imageList;
HRESULT hResult = SHGetImageList(SHIL_EXTRALARGE, IID_IImageList, (void**)&amp;imageList);

if (hResult == S_OK) {
  // Get the icon we need from the list. Note that the HIMAGELIST we retrieved
  // earlier needs to be casted to the IImageList interface before use.
  HICON hIcon;
  hResult = ((IImageList*)imageList)-&gt;GetIcon(sfi.iIcon, ILD_TRANSPARENT, &amp;hIcon);

  if (hResult == S_OK) {
    // Do something with the icon here.
    // For example, in wxWidgets:
    wxIcon* icon = new wxIcon();
    icon-&gt;SetHICON((WXHICON)hIcon);
    icon-&gt;SetSize(48, 48);
  }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://pogopixels.com/blog/getting-the-48x48-or-256x256-icon-of-a-file-on-windows/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Appetizer 1.0 is out</title>
		<link>http://pogopixels.com/blog/appetizer-10-is-out/</link>
		<comments>http://pogopixels.com/blog/appetizer-10-is-out/#comments</comments>
		<pubDate>Wed, 12 Nov 2008 12:35:38 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
		
		<category><![CDATA[Software News]]></category>

		<category><![CDATA[appetizer]]></category>

		<category><![CDATA[PortableApps]]></category>

		<guid isPermaLink="false">http://pogopixels.com/blog/?p=46</guid>
		<description><![CDATA[I have just released version 1.0 of Appetizer. It is a free application launcher, or dock, for Windows. It allows organizing and launching your applications and other shortcuts into a convenient dock. The app is skinable and entirely customizable. It is currently available in five different languages.
The application also supports the PortableApps USB format. So [...]]]></description>
			<content:encoded><![CDATA[<p>I have just released version 1.0 of <a href="http://app.etizer.org">Appetizer</a>. It is a free application launcher, or dock, for Windows. It allows organizing and launching your applications and other shortcuts into a convenient dock. The app is skinable and entirely customizable. It is currently available in five different languages.</p>
<p>The application also supports the <a href="http://portableapps.com">PortableApps</a> USB format. So if you use <a href="http://app.etizer.org">Appetizer</a> on a USB key in the PortableApps format, the application will detect it and automatically import all your applications along with the &#8216;Documents&#8217;, &#8216;Videos&#8217;, &#8216;Music&#8217; and &#8216;Pictures&#8217; folders.</p>
<p><a href="http://app.etizer.org">Follow this link to download it.</a></p>
<p><img src="http://appetizer.sourceforge.net/images/Screenshot.png" alt="Appetizer" /></p>
]]></content:encoded>
			<wfw:commentRss>http://pogopixels.com/blog/appetizer-10-is-out/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Dump a SVN repository from a URL</title>
		<link>http://pogopixels.com/blog/dumping-a-svn-repository-from-a-remote-url/</link>
		<comments>http://pogopixels.com/blog/dumping-a-svn-repository-from-a-remote-url/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 11:25:07 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
		
		<category><![CDATA[subversion]]></category>

		<category><![CDATA[svnadmin]]></category>

		<category><![CDATA[svnsync]]></category>

		<guid isPermaLink="false">http://pogopixels.com/blog/?p=27</guid>
		<description><![CDATA[Dumping a repository is sometime necessary, for example when you want to transfer it from one place to the other, say from Google Code to Sourceforge. The dump is normally created using svnadmin. However if you ever try to dump a remote repository, you&#8217;ll find out that it can&#8217;t be done:
svnadmin dump http://projectname.googlecode.com/svn &#62; repodump

svnadmin: [...]]]></description>
			<content:encoded><![CDATA[<p>Dumping a repository is sometime necessary, for example when you want to transfer it from one place to the other, say from <a title="Google Code" href="http://code.google.com/">Google Code</a> to <a title="SourceForge.net" href="https://sourceforge.net/">Sourceforge</a>. The dump is normally created using <a title="svnadmin reference" href="http://svnbook.red-bean.com/en/1.0/ch09s02.html">svnadmin</a>. However if you ever try to dump a remote repository, you&#8217;ll find out that it can&#8217;t be done:</p>
<pre class="syntax-highlight:bash">svnadmin dump http://projectname.googlecode.com/svn &gt; repodump

svnadmin: &#039;http://projectname.googlecode.com/svn&#039; is an URL when it should be a path</pre>
<p>One way around that is to use <a title="svnsync reference" href="http://svn.collab.net/repos/svn/trunk/notes/svnsync.txt">svnsync</a>. This utility allows you to synchronize a local depository with a remote one. So the technique here is to create an empty repository, synchronize it with the remote one, and, finally, dump the local repository.</p>
<p>Here are some notes on how to do that:</p>
<p><strong>1. Create a local repository</strong></p>
<pre class="syntax-highlight:bash">svnadmin create c:/repository</pre>
<p><strong>2. Add a &#8220;pre-revprop-change&#8221; hook to the local repository.</strong></p>
<pre class="syntax-highlight:bash">echo &gt; c:\repository\hooks\pre-revprop-change.cmd</pre>
<p>This is done by opening the &#8220;hooks&#8221; folder of the repository and adding a blank &#8220;pre-revprop-change.cmd&#8221; file into it. This will enable revision property change, which is necessary for synchronization.</p>
<p>On Linux and Mac, please follow the instructions in <a href="/blog/dumping-a-svn-repository-from-a-remote-url/#comment-153">this comment</a>.</p>
<p><strong>3. Synchronize your new repository with the remote one:</strong></p>
<pre class="syntax-highlight:bash">svnsync init file:///c:/repository https://example.googlecode.com/svn

svnsync sync file:///c:/repository</pre>
<p>Note: if you get this error: &#8220;<em>Cannot initialize a repository with content in it</em>&#8220;, it means that you&#8217;ve made some changes to the repository. In which case, the best thing to do is to just delete it and start over. The repository must be completely empty for the synchronization to work.</p>
<p><strong>4. Finally, once the synchronization is done, simply dump your local repository:</strong></p>
<pre class="syntax-highlight:bash">svnadmin dump c:/repository &gt; repodump</pre>
<p>If everything went well, repodump should now contain the exact content of the remote repository.</p>
<p><strong>Everything in one batch script<br />
</strong></p>
<p>The batch script below allows to do all that in just one script. Simply replace REPO_PATH and REPO_PATH_NUX by the path to your repository and REPO_URL by the repository URL.</p>
<pre class="syntax-highlight:bash">SET REPO_PATH=c:\your\local\repository
SET REPO_PATH_NUX=file:///c:/your/local/repository
SET REPO_URL=https://example.com/remote/repository

REM Uncomment the line below if the repository folder already exists
REM rmdir %REPO_PATH% /s/q
mkdir %REPO_PATH%
svnadmin create %REPO_PATH%
echo &gt; %REPO_PATH%\hooks\pre-revprop-change.cmd
svnsync init %REPO_PATH_NUX% %REPO_URL%
svnsync sync %REPO_PATH_NUX%</pre>
]]></content:encoded>
			<wfw:commentRss>http://pogopixels.com/blog/dumping-a-svn-repository-from-a-remote-url/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Get the URL of a YouTube FLV in Flash</title>
		<link>http://pogopixels.com/blog/getting-the-url-of-a-youtube-flv-file-in-flash/</link>
		<comments>http://pogopixels.com/blog/getting-the-url-of-a-youtube-flv-file-in-flash/#comments</comments>
		<pubDate>Fri, 31 Oct 2008 13:00:15 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
		
		<category><![CDATA[flash]]></category>

		<category><![CDATA[flv]]></category>

		<category><![CDATA[youtube]]></category>

		<guid isPermaLink="false">http://pogopixels.com/blog/?p=23</guid>
		<description><![CDATA[YouTube recently changed the way it serves FLV videos and previous methods to get the URL of the FLV files no longer work. As a workaround, it is still possible to retrieve it by:
1. Downloading the YouTube webpage where the video is embedded
2. Parsing it to extract the &#8220;t&#8221; and &#8220;video_id&#8221; parameters
3. Building the FLV [...]]]></description>
			<content:encoded><![CDATA[<p>YouTube recently changed the way it serves FLV videos and previous methods to get the URL of the FLV files no longer work. As a workaround, it is still possible to retrieve it by:</p>
<p>1. Downloading the YouTube webpage where the video is embedded<br />
2. Parsing it to extract the &#8220;t&#8221; and &#8220;video_id&#8221; parameters<br />
3. Building the FLV URL using the old method.</p>
<p>Obviously, having to download and parse the YouTube web page is a lot slower than the previous method, which was just about reading the HTTP headers, but at least it works.</p>
<p>The code snippet below allows to do just that:</p>
<pre class="syntax-highlight:js">public function getFLVURL(iYouTubeVideoURL) {
  // iYouTubeVideoURL is the &quot;watch&quot; URL such as:
  // http://www.youtube.com/watch?v=OVVvAnU3m6E

  var loader:URLLoader = new URLLoader();
  var req:URLRequest = new URLRequest(iYouTubeVideoURL);
  loader.addEventListener(Event.COMPLETE, this.getFLVURL_complete);
  loader.addEventListener(IOErrorEvent.IO_ERROR, this.getFLVURL_ioError);
  loader.load(req);
}

private function getFLVURL_complete(iEvent) {
  var pageData:String = iEvent.currentTarget.data;

  // Get the &quot;t&quot; parameter
  var regex:RegExp = /&quot;t&quot;: &quot;(.*?)&quot;/;
  var result:Array = pageData.match(regex);
  if (result.length &lt; 2) {
    trace(&quot;Error parsing YouTube page: Couldn&#039;t get &#039;t&#039; parameter&quot;);
    return;
  }
  var param_t = result[1];

  // Get the &quot;video_id&quot; parameter
  regex = /&quot;video_id&quot;: &quot;(.*?)&quot;/;
  result = pageData.match(regex);
  if (result.length &lt; 2) {
    trace(&quot;Error parsing YouTube page: Couldn&#039;t get &#039;video_id&#039; parameter&quot;);
    return;
  }
  var param_video_id = result[1];

  var flvURL:String = constructFLVURL(param_video_id, param_t);
  trace(&quot;Here&#039;s the FLV URL: &quot; + flvURL);

  flvTextBox.text = flvURL;
}

private function getFLVURL_ioError(iEvent) {
  var loader = iEvent.target;
  trace(&quot;Couldn&#039;t download YouTube web page: &quot; + iEvent);
}

private function constructFLVURL (video_id:String, t:String):String {
  var str:String = &quot;http://www.youtube.com/get_video.php?&quot;;
  str += &quot;video_id=&quot; + video_id;
  str += &quot;&amp;t=&quot; + t;
  return str;
}</pre>
<p><strong>Update (01/12/2008):</strong></p>
<p>As it turns out, this technique only works from Adobe AIR and not from a web page. This is because YouTube doesn&#8217;t allow crossdomain calls, which means that if a Flash application tries to fetch one of their pages, it will fail with a security error.</p>
<p>To go around this issue, it is possible to use a simple PHP stub file, which fetches the YouTube page and send it back to Flash. The PHP file would be as follow:</p>
<pre class="syntax-highlight:php">&lt;?php

$url = urldecode($_GET[&quot;url&quot;]);
header(&quot;Content-Type: text/html&quot;);
readfile($url);

?&gt;</pre>
<p>Then, in Flash, instead of calling the YouTube URL directly, you call the PHP URL:</p>
<pre class="syntax-highlight:js">
var youTubeURL = &quot;http://uk.youtube.com/watch?v=bxfpMGLMZ7Y&quot;
var stubURL = &quot;http://example.com/stub.php?url=&quot; + escape(youTubeURL)
getFLVURL(stubURL);</pre>
<p><a href="http://pogopixels.com/download/flvurl/">This small demo</a> illustrates all that. The source code with PHP stub is available <a href="http://pogopixels.com/blog/wp-content/uploads/2008/12/getflvurl.zip">here</a>.</p>
<p><strong>Update (19/03/2009):</strong></p>
<p>I&#8217;ve posted a follow up to this post with some information on how to get the HD quality version of the videos:<br />
<a href="/blog/get-the-url-of-a-iphone-or-hd-quality-youtube-video">Get the URL of an HD-quality Youtube video</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://pogopixels.com/blog/getting-the-url-of-a-youtube-flv-file-in-flash/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Create a short unique ID in PHP</title>
		<link>http://pogopixels.com/blog/creating-a-short-unique-id-in-php/</link>
		<comments>http://pogopixels.com/blog/creating-a-short-unique-id-in-php/#comments</comments>
		<pubDate>Tue, 21 Oct 2008 18:01:55 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
		
		<category><![CDATA[PHP / MySQL]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[UUID]]></category>

		<guid isPermaLink="false">http://pogopixels.com/blog/?p=21</guid>
		<description><![CDATA[Mads Kristensen describes a nice way of generating shorter UUIDs in C#. The idea is to take the 16 bytes of a UUID and convert them to a readable string via a Base64 encoder. The result is a string of 22 characters instead of 32, which is particularly convenient for web services since it makes [...]]]></description>
			<content:encoded><![CDATA[<p><a title="A shorter and URL friendly GUID" href="http://blog.madskristensen.dk/post/A-shorter-and-URL-friendly-GUID.aspx">Mads Kristensen</a> describes a nice way of generating shorter <a title="Universally Unique Identifier" href="http://en.wikipedia.org/wiki/Uuid">UUIDs</a> in C#. The idea is to take the 16 bytes of a UUID and convert them to a readable string via a Base64 encoder. The result is a string of 22 characters instead of 32, which is particularly convenient for web services since it makes the URLs 10 characters shorter.</p>
<p>I&#8217;ve implemented a version of it in PHP. Just copy and paste the code below and call createBase64UUID()</p>
<pre style="background-color: #eeeeee; padding: 5px;"><span style="color: #007700;">function </span><span style="color: #0000bb;">createBase64UUID</span><span style="color: #007700;">() {
  </span><span style="color: #0000bb;">$uuid </span><span style="color: #007700;">= </span><span style="color: #0000bb;">com_create_guid</span><span style="color: #007700;">();
  </span><span style="color: #0000bb;">$byteString </span><span style="color: #007700;">= </span><span style="color: #dd0000;">""</span><span style="color: #007700;">;

  </span><span style="color: #ff8000;">// Remove the dashes from the string
  </span><span style="color: #0000bb;">$uuid </span><span style="color: #007700;">= </span><span style="color: #0000bb;">str_replace</span><span style="color: #007700;">(</span><span style="color: #dd0000;">"-"</span><span style="color: #007700;">, </span><span style="color: #dd0000;">""</span><span style="color: #007700;">, </span><span style="color: #0000bb;">$uuid</span><span style="color: #007700;">);

  </span><span style="color: #ff8000;">// Remove the opening and closing brackets
  </span><span style="color: #0000bb;">$uuid </span><span style="color: #007700;">= </span><span style="color: #0000bb;">substr</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$uuid</span><span style="color: #007700;">, </span><span style="color: #0000bb;">1</span><span style="color: #007700;">, </span><span style="color: #0000bb;">strlen</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$uuid</span><span style="color: #007700;">) - </span><span style="color: #0000bb;">2</span><span style="color: #007700;">); 

  </span><span style="color: #ff8000;">// Read the UUID string byte by byte
  </span><span style="color: #007700;">for(</span><span style="color: #0000bb;">$i </span><span style="color: #007700;">= </span><span style="color: #0000bb;">0</span><span style="color: #007700;">; </span><span style="color: #0000bb;">$i </span><span style="color: #007700;">&lt; </span><span style="color: #0000bb;">strlen</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$uuid</span><span style="color: #007700;">); </span><span style="color: #0000bb;">$i </span><span style="color: #007700;">+= </span><span style="color: #0000bb;">2</span><span style="color: #007700;">) {
    </span><span style="color: #ff8000;">// Get two hexadecimal characters
    </span><span style="color: #0000bb;">$s </span><span style="color: #007700;">= </span><span style="color: #0000bb;">substr</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$uuid</span><span style="color: #007700;">, </span><span style="color: #0000bb;">$i</span><span style="color: #007700;">, </span><span style="color: #0000bb;">2</span><span style="color: #007700;">);
    </span><span style="color: #ff8000;">// Convert them to a byte
    </span><span style="color: #0000bb;">$d </span><span style="color: #007700;">= </span><span style="color: #0000bb;">hexdec</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$s</span><span style="color: #007700;">);
    </span><span style="color: #ff8000;">// Convert it to a single character
    </span><span style="color: #0000bb;">$c </span><span style="color: #007700;">= </span><span style="color: #0000bb;">chr</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$d</span><span style="color: #007700;">);
    </span><span style="color: #ff8000;">// Append it to the byte string
    </span><span style="color: #0000bb;">$byteString </span><span style="color: #007700;">= </span><span style="color: #0000bb;">$byteString</span><span style="color: #007700;">.</span><span style="color: #0000bb;">$c</span><span style="color: #007700;">;
  } 

  </span><span style="color: #ff8000;">// Convert the byte string to a base64 string
  </span><span style="color: #0000bb;">$b64uuid </span><span style="color: #007700;">= </span><span style="color: #0000bb;">base64_encode</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$byteString</span><span style="color: #007700;">);
  </span><span style="color: #ff8000;">// Replace the "/" and "+" since they are reserved characters
  </span><span style="color: #0000bb;">$b64uuid </span><span style="color: #007700;">= </span><span style="color: #0000bb;">str_replace</span><span style="color: #007700;">(</span><span style="color: #dd0000;">"/"</span><span style="color: #007700;">, </span><span style="color: #dd0000;">"_"</span><span style="color: #007700;">, </span><span style="color: #0000bb;">$b64uuid</span><span style="color: #007700;">);
  </span><span style="color: #0000bb;">$b64uuid </span><span style="color: #007700;">= </span><span style="color: #0000bb;">str_replace</span><span style="color: #007700;">(</span><span style="color: #dd0000;">"+"</span><span style="color: #007700;">, </span><span style="color: #dd0000;">"-"</span><span style="color: #007700;">, </span><span style="color: #0000bb;">$b64uuid</span><span style="color: #007700;">);
  </span><span style="color: #ff8000;">// Remove the trailing "=="
  </span><span style="color: #0000bb;">$b64uuid </span><span style="color: #007700;">= </span><span style="color: #0000bb;">substr</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$b64uuid</span><span style="color: #007700;">, </span><span style="color: #0000bb;">0</span><span style="color: #007700;">, </span><span style="color: #0000bb;">strlen</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$b64uuid</span><span style="color: #007700;">) - </span><span style="color: #0000bb;">2</span><span style="color: #007700;">); 

  return </span><span style="color: #0000bb;">$b64uuid</span><span style="color: #007700;">;
}
</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://pogopixels.com/blog/creating-a-short-unique-id-in-php/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Lost your widget?</title>
		<link>http://pogopixels.com/blog/lost-your-widget/</link>
		<comments>http://pogopixels.com/blog/lost-your-widget/#comments</comments>
		<pubDate>Mon, 30 Jun 2008 21:43:56 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
		
		<category><![CDATA[yahoo! widgets]]></category>

		<guid isPermaLink="false">http://pogopixels.com/blog/?p=20</guid>
		<description><![CDATA[Now and then it might happen that one of your Yahoo! widgets disappears, and no matter what you try - uninstalling the widget, the engine, restarting the computer, etc. - it won&#8217;t come back.
When this happens, there are a number of things you can try to get it back:
» Use Widget Cleaner
This is the simplest [...]]]></description>
			<content:encoded><![CDATA[<p>Now and then it might happen that one of your <a href="http://widgets.yahoo.com">Yahoo! widgets</a> disappears, and no matter what you try - uninstalling the widget, the engine, restarting the computer, etc. - it won&#8217;t come back.</p>
<p>When this happens, there are a number of things you can try to get it back:</p>
<h3>» Use Widget Cleaner</h3>
<p>This is the simplest solution. Just close the widget then clear the widget preferences using <a href="http://widgets.yahoo.com/widgets/widget-cleaner">Widget Cleaner</a>. This will reset all the widget preferences to their initial values, including the dimensions and positions of the windows, so the widget should be visible again.</p>
<p>However, it might not always work since Widget Cleaner currently can&#8217;t &#8220;detect&#8221; all the widgets. In that case, try the second solution.</p>
<h3>» Check the widget Preferences</h3>
<p>Some widget authors add an option in the Preferences to reset the window positions. You can access the Preferences by clicking on the Gear button in the Dock icon, then look for any option that might allow you to reset the windows. If such an option is available, use it and the widget should be visible again.</p>
<p><a href="http://pogopixels.com/blog/wp-content/uploads/2008/06/widgetpreferencebutton.png"><img class="alignnone size-medium wp-image-18" title="widgetpreferencebutton" src="http://pogopixels.com/blog/wp-content/uploads/2008/06/widgetpreferencebutton.png" alt="Widget preferences button" width="149" height="145" /></a></p>
<h3>» Delete the registry settings</h3>
<p>The last option is more complicated and only works on Windows, however it will definitely fix the issue in all cases. In order to reset the widget preferences (and therefore its visibility), you can open the registry editor and manually delete the appropriate settings. To do so, follow these instructions:</p>
<ol>
<li>Press the Windows Start button and <a href="http://martinz.wordpress.com/2006/11/23/start-run-commands/">click on Run</a></li>
<li>Type &#8220;regedit&#8221; (without the quotes)</li>
<li>Navigate to this folder: &#8220;HKEY_CURRENT_USER\Software\Yahoo\WidgetEngine\Widgets&#8221;</li>
<li>Here you will find a number of subfolders. Each of them contains the Preferences of a widget.</li>
<li>Find the name of the widget you are looking for, then right-click on its subfolder and select &#8220;Delete&#8221;.</li>
</ol>
<p>For example, this is what you should see if you wish to delete the preferences of the &#8220;Day Planner Calendar&#8221; widget:</p>
<p><a href="http://pogopixels.com/blog/wp-content/uploads/2008/06/deletewidgetpreferences.png"><img class="alignnone size-medium wp-image-19" title="Delete Yahoo widget preferences" src="http://pogopixels.com/blog/wp-content/uploads/2008/06/deletewidgetpreferences-300x285.png" alt="Delete Yahoo widget preferences" width="300" height="285" /></a></p>
<p>After doing so, restart your widget and normally it should be visible again.</p>
]]></content:encoded>
			<wfw:commentRss>http://pogopixels.com/blog/lost-your-widget/feed/</wfw:commentRss>
		</item>
		<item>
		<title>2D Polygon Collision Detection</title>
		<link>http://pogopixels.com/blog/2d-polygon-collision-detection/</link>
		<comments>http://pogopixels.com/blog/2d-polygon-collision-detection/#comments</comments>
		<pubDate>Fri, 27 Jun 2008 20:08:49 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
		
		<category><![CDATA[.NET / C#]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[2d game]]></category>

		<category><![CDATA[c#]]></category>

		<category><![CDATA[Collision Detection]]></category>

		<guid isPermaLink="false">http://pogopixels.com/blog/?p=10</guid>
		<description><![CDATA[This article describes how to detect the collision between two moving (2D) polygons. It&#8217;s not the first tutorial on the topic, however, the tutorials on the net tend to be a bit too complex for a relatively simple problem. The source codes I could find also had too many abbreviations that I don&#8217;t get, or [...]]]></description>
			<content:encoded><![CDATA[<p>This article describes how to detect the collision between two moving (2D) polygons. It&#8217;s not the first tutorial on the topic, however, the tutorials on the net tend to be a bit too complex for a relatively simple problem. The source codes I could find also had too many abbreviations that I don&#8217;t get, or were crippled with C optimizations. So here, I&#8217;ll try to keep it as simple as possible. In any case, it should be possible to include the functions presented here to your C# projects quite straightforwardly. The technique can be used to detect collisions between sprites as an alternative to pixel-perfect collisions which are usually too slow.</p>
<ul>
<li><a href="/blog/wp-content/uploads/2008/06/polygoncollision_src.zip">Download the .NET / C# source code</a></li>
<li><a href="/blog/wp-content/uploads/2008/06/polygoncollision_demo.zip">Download the .NET demo</a></li>
</ul>
<h3>Background</h3>
<p>To detect if two polygons are intersecting, we use the Separating Axis Theorem. The idea is to find a line that separates both polygons - if such a line exists, the polygons are not intersecting (Fig. 1). The implementation of this theorem is relatively simple, and could be summed up in this pseudo code:</p>
<ul>
<li><code>For each edge of both polygons:</code>
<ul>
<li><code>Find the axis perpendicular to the current edge.</code></li>
<li><code>Project both polygons on that axis.</code></li>
<li><code>If these projections don't overlap, the polygons don't intersect (exit the loop).</code></li>
</ul>
</li>
</ul>
<p>This can be easily extended to deal with moving polygons by adding one additional step. After having checked that the current projections do not overlap, project the relative velocity of the polygons on the axis. Extend the projection of the first polygon by adding to it the velocity projection (Fig. 2). This will give you the interval spanned by the polygon over the duration of the motion. From there, you can use the technique used for static polygons: if the projections of polygons A and B don&#8217;t overlap, the polygons won&#8217;t collide. (NB: However, remember that if the intervals <strong>do </strong>overlap, it doesn&#8217;t necessarily mean that the polygons will collide. We need to do the test for all the edges before knowing that.)</p>
<p>Once we have found that the polygons are going to collide, we calculate the translation needed to push the polygons apart. The axis on which the projection overlapping is minimum will be the one on which the collision will take place. We will push the first polygon along this axis. Then, the amount of translation will simply be the amount of overlapping on this axis (Fig. 3).</p>
<p>That is it! Now, each time a collision occurs, the first polygon will nicely slide along the surface of the other polygon.</p>
<p><a href="http://pogopixels.com/blog/wp-content/uploads/2008/06/polygoncollision01.png"><img class="alignnone size-medium wp-image-11" title="Projections of polygons onto an axis" src="http://pogopixels.com/blog/wp-content/uploads/2008/06/polygoncollision01.png" alt="Projections of polygons onto an axis" width="256" height="256" /></a></p>
<p><strong>Figure 1:</strong> Projections of the polygons onto an axis.</p>
<p><a href="http://pogopixels.com/blog/wp-content/uploads/2008/06/polygoncollision02.png"><img class="alignnone size-medium wp-image-12" title="Projections of moving polygons onto an axis" src="http://pogopixels.com/blog/wp-content/uploads/2008/06/polygoncollision02.png" alt="Projections of moving polygons onto an axis" width="256" height="256" /></a></p>
<p><strong>Figure 2</strong>: Projections for moving polygons.</p>
<p><a href="http://pogopixels.com/blog/wp-content/uploads/2008/06/polygoncollision03.png"><img class="alignnone size-medium wp-image-13" title="Polygon Collision" src="http://pogopixels.com/blog/wp-content/uploads/2008/06/polygoncollision03.png" alt="Polygon Collision" width="256" height="256" /></a></p>
<p><strong>Figure 3:</strong> Find the minimum interval overlapping, then calculate the translation required to push the polygons apart.</p>
<h3>Using the code</h3>
<p>The <code>PolygonCollision()</code> function does all of the above, and returns a <code>PolygonCollisionResult</code> structure containing all the necessary information to handle the collision:</p>
<pre style="background-color: #eeeeee; padding: 5px;"><span style="color: #008000;">// Structure that stores the results of the PolygonCollision function</span><span style="color: #000000;">

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">struct</span><span style="color: #000000;"> PolygonCollisionResult {
    </span><span style="color: #008000;">// Are the polygons going to intersect forward in time?</span><span style="color: #000000;">

    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">bool</span><span style="color: #000000;"> WillIntersect;
    </span><span style="color: #008000;">// Are the polygons currently intersecting?</span><span style="color: #000000;">

    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">bool</span><span style="color: #000000;"> Intersect;
    </span><span style="color: #008000;">// The translation to apply to the first polygon to push the polygons apart.</span><span style="color: #000000;">

    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Vector MinimumTranslationVector;
}</span></pre>
<p>Two helper functions are used by the <code>PolygonCollision</code> function. The first one is used to project a polygon onto an axis:</p>
<pre style="background-color: #eeeeee; padding: 5px;"><!--

Code highlighting produced by Actipro SyntaxEditor
http://www.ActiproSoftware.com/Products/DotNet/

--><span style="color: #008000;">// Calculate the projection of a polygon on an axis</span><span style="color: #000000;">

</span><span style="color: #008000;">// and returns it as a [min, max] interval</span><span style="color: #000000;">

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> ProjectPolygon(Vector axis, Polygon polygon,
                           </span><span style="color: #0000ff;">ref</span><span style="color: #000000;"> </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> min, </span><span style="color: #0000ff;">ref</span><span style="color: #000000;"> </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> max) {
    </span><span style="color: #008000;">// To project a point on an axis use the dot product</span><span style="color: #000000;">

    </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> dotProduct = axis.DotProduct(polygon.Points[</span><span style="color: #ff0000;">0</span><span style="color: #000000;">]);
    min = dotProduct;
    max = dotProduct;
    </span><span style="color: #0000ff;">for</span><span style="color: #000000;"> (</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> i = </span><span style="color: #ff0000;">0</span><span style="color: #000000;">; i &lt; polygon.Points.Count; i++) {
        dotProduct = polygon.Points[i].DotProduct(axis);
        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (d &lt; min) {
            min = dotProduct;
        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
            </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (dotProduct&gt; max) {
                max = dotProduct;
            }
        }
    }
}</span></pre>
<p>The second one returns the signed distance between two given projections:</p>
<pre style="background-color: #eeeeee; padding: 5px;"><!--

Code highlighting produced by Actipro SyntaxEditor
http://www.ActiproSoftware.com/Products/DotNet/

--><span style="color: #008000;">// Calculate the distance between [minA, maxA] and [minB, maxB]</span><span style="color: #000000;">

</span><span style="color: #008000;">// The distance will be negative if the intervals overlap</span><span style="color: #000000;">

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> IntervalDistance(</span><span style="color: #0000ff;">float</span><span style="color: #000000;"> minA, </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> maxA, </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> minB, </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> maxB) {
    </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (minA &lt; minB) {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> minB - maxA;
    } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> minA - maxB;
    }
}</span></pre>
<p>Finally, here is the main function:</p>
<pre style="background-color: #eeeeee; padding: 5px;"><!--

Code highlighting produced by Actipro SyntaxEditor
http://www.ActiproSoftware.com/Products/DotNet/

--><span style="color: #008000;">// Check if polygon A is going to collide with polygon B.</span><span style="color: #000000;">

</span><span style="color: #008000;">// The last parameter is the *relative* velocity </span><span style="color: #000000;">

</span><span style="color: #008000;">// of the polygons (i.e. velocityA - velocityB)</span><span style="color: #000000;">

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> PolygonCollisionResult PolygonCollision(Polygon polygonA,
                              Polygon polygonB, Vector velocity) {
    PolygonCollisionResult result = </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> PolygonCollisionResult();
    result.Intersect = </span><span style="color: #0000ff;">true</span><span style="color: #000000;">;
    result.WillIntersect = </span><span style="color: #0000ff;">true</span><span style="color: #000000;">;

    </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> edgeCountA = polygonA.Edges.Count;
    </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> edgeCountB = polygonB.Edges.Count;
    </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> minIntervalDistance = </span><span style="color: #0000ff;">float</span><span style="color: #000000;">.PositiveInfinity;
    Vector translationAxis = </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> Vector();
    Vector edge;

    </span><span style="color: #008000;">// Loop through all the edges of both polygons</span><span style="color: #000000;">

    </span><span style="color: #0000ff;">for</span><span style="color: #000000;"> (</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> edgeIndex = </span><span style="color: #ff0000;">0</span><span style="color: #000000;">; edgeIndex &lt; edgeCountA + edgeCountB; edgeIndex++) {
        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (edgeIndex &lt; edgeCountA) {
            edge = polygonA.Edges[edgeIndex];
        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
            edge = polygonB.Edges[edgeIndex - edgeCountA];
        }

        </span><span style="color: #008000;">// ===== 1. Find if the polygons are currently intersecting =====</span><span style="color: #000000;">

        </span><span style="color: #008000;">// Find the axis perpendicular to the current edge</span><span style="color: #000000;">

        Vector axis = </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> Vector(-edge.Y, edge.X);
        axis.Normalize();

        </span><span style="color: #008000;">// Find the projection of the polygon on the current axis</span><span style="color: #000000;">

        </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> minA = </span><span style="color: #ff0000;">0</span><span style="color: #000000;">; </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> minB = </span><span style="color: #ff0000;">0</span><span style="color: #000000;">; </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> maxA = </span><span style="color: #ff0000;">0</span><span style="color: #000000;">; </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> maxB = </span><span style="color: #ff0000;">0</span><span style="color: #000000;">;
        ProjectPolygon(axis, polygonA, </span><span style="color: #0000ff;">ref</span><span style="color: #000000;"> minA, </span><span style="color: #0000ff;">ref</span><span style="color: #000000;"> maxA);
        ProjectPolygon(axis, polygonB, </span><span style="color: #0000ff;">ref</span><span style="color: #000000;"> minB, </span><span style="color: #0000ff;">ref</span><span style="color: #000000;"> maxB);

        </span><span style="color: #008000;">// Check if the polygon projections are currentlty intersecting</span><span style="color: #000000;">

        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (IntervalDistance(minA, maxA, minB, maxB) &gt; </span><span style="color: #ff0000;">0</span><span style="color: #000000;">)\
            result.Intersect = </span><span style="color: #0000ff;">false</span><span style="color: #000000;">;

        </span><span style="color: #008000;">// ===== 2. Now find if the polygons *will* intersect =====</span><span style="color: #000000;">

        </span><span style="color: #008000;">// Project the velocity on the current axis</span><span style="color: #000000;">

        </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> velocityProjection = axis.DotProduct(velocity);

        </span><span style="color: #008000;">// Get the projection of polygon A during the movement</span><span style="color: #000000;">

        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (velocityProjection &lt; </span><span style="color: #ff0000;">0</span><span style="color: #000000;">) {
            minA += velocityProjection;
        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
            maxA += velocityProjection;
        }

        </span><span style="color: #008000;">// Do the same test as above for the new projection</span><span style="color: #000000;">

        </span><span style="color: #0000ff;">float</span><span style="color: #000000;"> intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (intervalDistance &gt; </span><span style="color: #ff0000;">0</span><span style="color: #000000;">) result.WillIntersect = </span><span style="color: #0000ff;">false</span><span style="color: #000000;">;

        </span><span style="color: #008000;">// If the polygons are not intersecting and won't intersect, exit the loop</span><span style="color: #000000;">

        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (!result.Intersect &amp;&amp; !result.WillIntersect) </span><span style="color: #0000ff;">break</span><span style="color: #000000;">;

        </span><span style="color: #008000;">// Check if the current interval distance is the minimum one. If so store</span><span style="color: #000000;">

        </span><span style="color: #008000;">// the interval distance and the current distance.</span><span style="color: #000000;">

        </span><span style="color: #008000;">// This will be used to calculate the minimum translation vector</span><span style="color: #000000;">

        intervalDistance = Math.Abs(intervalDistance);
        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (intervalDistance &lt; minIntervalDistance) {
            minIntervalDistance = intervalDistance;
            translationAxis = axis;

            Vector d = polygonA.Center - polygonB.Center;
            </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (d.DotProduct(translationAxis) &lt; </span><span style="color: #ff0000;">0</span><span style="color: #000000;">)
                translationAxis = -translationAxis;
        }
    }

    </span><span style="color: #008000;">// The minimum translation vector</span><span style="color: #000000;">

    </span><span style="color: #008000;">// can be used to push the polygons appart.</span><span style="color: #000000;">

    </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (result.WillIntersect)
        result.MinimumTranslationVector =
               translationAxis * minIntervalDistance;

    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> result;
}</span></pre>
<p>The function can be used this way:</p>
<pre style="background-color: #eeeeee; padding: 5px;"><!--

Code highlighting produced by Actipro SyntaxEditor
http://www.ActiproSoftware.com/Products/DotNet/

--><span style="color: #000000;">Vector polygonATranslation = </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> Vector();

PolygonCollisionResult r = PolygonCollision(polygonA, polygonB, velocity);

</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (r.WillIntersect) {
  </span><span style="color: #008000;">// Move the polygon by its velocity, then move</span><span style="color: #000000;">

  </span><span style="color: #008000;">// the polygons appart using the Minimum Translation Vector</span><span style="color: #000000;">

  polygonATranslation = velocity + r.MinimumTranslationVector;
} </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
  </span><span style="color: #008000;">// Just move the polygon by its velocity</span><span style="color: #000000;">

  polygonATranslation = velocity;
}

polygonA.Offset(polygonATranslation);</span></pre>
<h3>Reference</h3>
<ul>
<li><a href="http://gpwiki.org/index.php/Polygon_Collision">GPWiki - Polygon Collision</a></li>
<li><a href="http://uk.geocities.com/olivier_rebellion/">Olivier&#8217;s code junkyard</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://pogopixels.com/blog/2d-polygon-collision-detection/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
