<?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>Floorplanner Tech Blog &#187; Floorplanner</title>
	<atom:link href="http://techblog.floorplanner.com/category/floorplanner/feed/" rel="self" type="application/rss+xml" />
	<link>http://techblog.floorplanner.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 19 Nov 2009 04:00:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Debug your web service with HTTP Client</title>
		<link>http://techblog.floorplanner.com/2009/05/26/debug-your-web-service-with-http-client/</link>
		<comments>http://techblog.floorplanner.com/2009/05/26/debug-your-web-service-with-http-client/#comments</comments>
		<pubDate>Tue, 26 May 2009 09:51:42 +0000</pubDate>
		<dc:creator>Gert-Jan</dc:creator>
				<category><![CDATA[API]]></category>
		<category><![CDATA[Floorplanner]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[http client]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[web service]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=642</guid>
		<description><![CDATA[The last couple of weeks we&#8217;ve been working on a big integration project. The largest real estate portal of The Netherlands, Funda, uses Floorplanner to deliver interactive floor plans to their clients. They use our API&#8217;s to seamlessly integrate the Floorplanner into their back end system and front end website.
One of our API&#8217;s is our [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F05%2F26%2Fdebug-your-web-service-with-http-client%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F05%2F26%2Fdebug-your-web-service-with-http-client%2F" height="61" width="51" /></a></div><p>The last couple of weeks we&#8217;ve been working on a big integration project. The largest real estate portal of The Netherlands, <a href="http://www.funda.nl">Funda</a>, uses Floorplanner to deliver <a href="http://www.funda.nl/koop/dronten/huis-4217508-de-morinel-43-45/plattegrond/">interactive floor plans </a>to their clients. They use our API&#8217;s to seamlessly integrate the Floorplanner into their back end system and front end website.</p>
<p>One of our API&#8217;s is our RESTful web service. With it one can manage users, project, floors, designs etc. We set up a whole testing suite around it, but every now and then I wanted to test a single method by hand. For this I used the command line tool <a href="http://curl.haxx.se/">cURL</a> which looks something like this (getting all users):</p>

<div class="wp_syntax"><div class="code"><pre class="curl" style="font-family: Monaco,monospace;">curl -H &quot;Content-Type: application/xml&quot; 
-u &quot;username:password&quot; 
-X GET https://floorplanner.com/users.xml</pre></div></div>

<p>It works, but it&#8217;s kind of a hassle. One day <a href="https://twitter.com/whenyouneedmi">Michel</a> showed me <a href="http://ditchnet.org/httpclient/">HTTP Client</a>: </p>
<blockquote><p><i>A Mac OS X Leopard developer tool for debugging HTTP services by graphically creating &#038; inspecting complex HTTP messages.</i></p></blockquote>
<p>HTTP Client makes testing a web service by hand much easier. You can select any REST method you need from a pull down menu. Setting up your header is done by a few mouse clicks and the result is nicely formatted. </p>
<p><img src="http://techblog.floorplanner.com/wp-content/uploads/2009/05/afbeelding-1-600x421.png" alt="HTTP Client sample" title="HTTP Client sample" width="600" height="421" class="alignnone size-large wp-image-652" /></p>
<p>The only thing that didn&#8217;t seem to work out of the box was Basic HTTP Authentication. I found a workaround for this: add the authorization to the header myself. To do this use &#8220;Authorization&#8221; as header name. For the header value you have to encode the username and password with <a href="http://en.wikipedia.org/wiki/Base64">Base64</a> with a &#8220;:&#8221; as separator. For example in PHP: base64_encode(username:password). There are also a couple of websites around where you can encode a string to Base64. When you have the encoded string, you can add &#8220;Basic <i>encoded string here</i>&#8221; as a header value and you&#8217;re ready to roll.</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/05/26/debug-your-web-service-with-http-client/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unproject with useProjectionMatrix = true</title>
		<link>http://techblog.floorplanner.com/2009/04/29/unproject-with-useprojectionmatrix-true/</link>
		<comments>http://techblog.floorplanner.com/2009/04/29/unproject-with-useprojectionmatrix-true/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 00:45:40 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Collaboration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Flash+ActionScript]]></category>
		<category><![CDATA[Floorplanner]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[Papervision3D]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[unproject]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=580</guid>
		<description><![CDATA[I just updated Papervision3D to allow the CameraObject3D#unproject method to work when CameraObject3D#useProjectionMatrix = true.
Papervision3D has two methods of &#8216;projecting&#8217; vectors onto the screen:

useProjectionMatrix = false, this is the default &#8216;fast&#8217; method
useProjectionMatrix = true, this is the method where projection is done by a matrix

Note that Papervision3D switches to method #2 in &#8216;ortho mode&#8217;.
So what [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F04%2F29%2Funproject-with-useprojectionmatrix-true%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F04%2F29%2Funproject-with-useprojectionmatrix-true%2F" height="61" width="51" /></a></div><p>I just updated <a href="http://blog.papervision3d.org">Papervision3D</a> to allow the CameraObject3D#unproject method to work when CameraObject3D#useProjectionMatrix = true.</p>
<p>Papervision3D has two methods of &#8216;projecting&#8217; vectors onto the screen:</p>
<ol>
<li>useProjectionMatrix = false, this is the default &#8216;fast&#8217; method</li>
<li>useProjectionMatrix = true, this is the method where projection is done by a matrix</li>
</ol>
<p>Note that Papervision3D switches to method #2 in &#8216;ortho mode&#8217;.</p>
<p>So what is the difference exactly between these two kinds of projection? First we need to define what projection is. Projection is what adds &#8216;perspective&#8217; to a scene and makes sure your scene fits to the viewport. Its the last step in the so-called &#8216;render pipeline&#8217;. </p>
<p>We can derive the &#8216;fore shortening&#8217; effect of perspective in several ways. Method #1 is simple, effective and fast. It uses the camera&#8217;s focus and zoom values. Method #2 uses a more classic way of projection : it uses a dedicated matrix. Tech buffs: very much like OpenGL&#8217;s <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml">gluPerspective</a>.</p>
<p><a href="http://blog.zupko.info/">Andy Zupko</a> has a great <a href="http://blog.zupko.info/?p=143">post</a> on unproject using method #1.</p>
<p>We will discuss unproject using method #2, which works slightly different.</p>
<p>The difference is that when #useProjectionMatrix is set to true, then CameraObject3D#unproject  returns a point in world-space, rather then a ray. Let me explain with some code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="actionscript3" style="font-family: Monaco,monospace;"><span style="color: #009900;">// we want to use a projection matrix</span>
camera.useProjectionMatrix = <span style="color: #0033ff; font-weight: bold;">true</span>;
&nbsp;
<span style="color: #009900;">// '0' indicates we want a point on the near plane</span>
<span style="color: #6699cc; font-weight: bold;">var</span> pointOnNearPlane <span style="color: #000000; font-weight: bold;">:</span> Number3D = camera.unproject<span style="color: #000000;">&#40;</span> screenX, screenY, <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span>;
&nbsp;
<span style="color: #009900;">// '1' indicates we want a point on the far plane</span>
<span style="color: #6699cc; font-weight: bold;">var</span> pointOnFarPlane <span style="color: #000000; font-weight: bold;">:</span> Number3D = camera.unproject<span style="color: #000000;">&#40;</span> screenX, screenY, <span style="color: #000000; font-weight:bold;">1</span> <span style="color: #000000;">&#41;</span>;
&nbsp;
<span style="color: #009900;">// Construct the ray's direction</span>
<span style="color: #6699cc; font-weight: bold;">var</span> dir <span style="color: #000000; font-weight: bold;">:</span> Number3D = Number3D.sub<span style="color: #000000;">&#40;</span> pointOnFarPlane, pointOnNearPlane <span style="color: #000000;">&#41;</span>;
&nbsp;
<span style="color: #009900;">// Normalize</span>
dir.<span style="color: #004993;">normalize</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
&nbsp;
<span style="color: #009900;">// So, now you have a ray with its origin at 'pointOnNearPlane',</span>
<span style="color: #009900;">// and direction 'dir'</span></pre></td></tr></table></div>

<p>Optimization: could save some cycles by doing (*not* in ortho mode!, see below):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="actionscript3" style="font-family: Monaco,monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> camPosition <span style="color: #000000; font-weight: bold;">:</span> Number3D = <span style="color: #0033ff; font-weight: bold;">new</span> Number3D<span style="color: #000000;">&#40;</span> camera.<span style="color: #004993;">x</span>, camera.<span style="color: #004993;">y</span>, camera.z <span style="color: #000000;">&#41;</span>;
<span style="color: #009900;">// Construct the ray's direction</span>
<span style="color: #6699cc; font-weight: bold;">var</span> dir <span style="color: #000000; font-weight: bold;">:</span> Number3D = Number3D.sub<span style="color: #000000;">&#40;</span> pointOnFarPlane, camPosition <span style="color: #000000;">&#41;</span>;
<span style="color: #009900;">// Normalize</span>
dir.<span style="color: #004993;">normalize</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
<span style="color: #009900;">// So, now you have a ray with its origin at the camera's position</span>
<span style="color: #009900;">// and direction 'dir'</span></pre></td></tr></table></div>

<p>Why can&#8217;t we use above optimization in ortho mode?<br />
In perspective mode all &#8216;rays&#8217; originate from the camera&#8217;s position: the &#8216;view cone&#8217; has shape of a pyramid. Hence we can assume &#8216;pointOnNearPlane&#8217; to coincide with the camera&#8217;s position.<br />
In ortho mode however the &#8216;view cone&#8217; has the shape of a cube, all rays are parallel. Hence we need to unproject *two* points to construct our ray.</p>
<p>Now simply follow <a href="http://blog.zupko.info/?p=143">Andy Zupko &#8217;s post</a> to drag objects around.<br />
Or perform &#8216;picking&#8217;, or&#8230;</p>
<p>Update:<br />
Created a little demo to visualize what I&#8217;m ranting about, check it out <a href='http://techblog.floorplanner.com/wp-content/uploads/2009/04/unprojecttest1.swf'>here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/04/29/unproject-with-useprojectionmatrix-true/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Floorplanner API, ASP.NET and Authorization</title>
		<link>http://techblog.floorplanner.com/2009/03/14/floorplanner-api-aspnet-and-authorization/</link>
		<comments>http://techblog.floorplanner.com/2009/03/14/floorplanner-api-aspnet-and-authorization/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 04:41:50 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Floorplanner]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=530</guid>
		<description><![CDATA[For those struggling to (Basic) authenticate (as I have been&#8230;) with the Floorplanner API using ASP.NET, here&#8217;s a snip to get you going:
VB.NET:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
' This snip shows how to add a new user, 
' see floorplanner.com/api for details
Dim uri As Uri = new Uri&#40;ADD_USER_URL&#41;
Dim request as HttpWebRequest =  CType&#40;WebRequest.Create&#40;uri&#41;,HttpWebRequest&#41;
&#160;
' Build XML for the POST body [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F03%2F14%2Ffloorplanner-api-aspnet-and-authorization%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F03%2F14%2Ffloorplanner-api-aspnet-and-authorization%2F" height="61" width="51" /></a></div><p>For those struggling to (Basic) authenticate (as I have been&#8230;) with the <a href="http://www.floorplanner.com/api">Floorplanner API</a> using ASP.NET, here&#8217;s a snip to get you going:</p>
<p>VB.NET:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="code"><pre class="vbnet" style="font-family: Monaco,monospace;"><span style="color: #008080; font-style: italic;">' This snip shows how to add a new user, </span>
<span style="color: #008080; font-style: italic;">' see floorplanner.com/api for details</span>
<span style="color: #0600FF;">Dim</span> uri <span style="color: #FF8000;">As</span> Uri <span style="color: #008000;">=</span> <span style="color: #FF8000;">new</span> Uri<span style="color: #000000;">&#40;</span>ADD_USER_URL<span style="color: #000000;">&#41;</span>
<span style="color: #0600FF;">Dim</span> request <span style="color: #FF8000;">as</span> HttpWebRequest <span style="color: #008000;">=</span>  <span style="color: #0600FF;">CType</span><span style="color: #000000;">&#40;</span>WebRequest.<span style="color: #0000FF;">Create</span><span style="color: #000000;">&#40;</span>uri<span style="color: #000000;">&#41;</span>,HttpWebRequest<span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #008080; font-style: italic;">' Build XML for the POST body (in this case from a custom User class)</span>
<span style="color: #0600FF;">Dim</span> xmlStr <span style="color: #FF8000;">As</span> <span style="color: #FF8000;">String</span> <span style="color: #008000;">=</span> User.<span style="color: #0000FF;">ToXmlString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #008080; font-style: italic;">' Grab the bytes</span>
<span style="color: #0600FF;">Dim</span> xmlBytes <span style="color: #FF8000;">As</span> <span style="color: #FF0000;">Byte</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=</span> Encoding.<span style="color: #0000FF;">UTF8</span>.<span style="color: #0000FF;">GetBytes</span><span style="color: #000000;">&#40;</span>xmlStr<span style="color: #000000;">&#41;</span>
&nbsp;
request.<span style="color: #0600FF;">Method</span> <span style="color: #008000;">=</span> <span style="color: #808080;">&quot;POST&quot;</span>       
request.<span style="color: #0000FF;">ContentLength</span> <span style="color: #008000;">=</span> xmlBytes.<span style="color: #0000FF;">Length</span>
request.<span style="color: #0000FF;">ContentType</span> <span style="color: #008000;">=</span> <span style="color: #808080;">&quot;application/xml&quot;</span>
&nbsp;
<span style="color: #008080; font-style: italic;">' Basic Authorization</span>
<span style="color: #008080; font-style: italic;">' Make sure PreAuthenticate is set to True, else the </span>
<span style="color: #008080; font-style: italic;">' Authorization header will *not* be sent, and an error will be thrown</span>
request.<span style="color: #0000FF;">Credentials</span> <span style="color: #008000;">=</span> <span style="color: #FF8000;">New</span> NetworkCredential<span style="color: #000000;">&#40;</span>API_KEY, API_PASS<span style="color: #000000;">&#41;</span>
request.<span style="color: #0000FF;">PreAuthenticate</span> <span style="color: #008000;">=</span> <span style="color: #0600FF;">True</span>
&nbsp;
<span style="color: #008080; font-style: italic;">' Alternatively use a more old-fashioned method</span>
<span style="color: #008080; font-style: italic;">' Dim basicAuth As String = Convert.ToBase64String(Encoding.ASCII.GetBytes(API_KEY &amp; &quot;:&quot; &amp; API_PASS))</span>
<span style="color: #008080; font-style: italic;">' request.Headers.Add(&quot;Authorization&quot;, &quot;Basic &quot; &amp; basicAuth)</span>
&nbsp;
<span style="color: #008080; font-style: italic;">' Add our payload</span>
<span style="color: #0600FF;">Dim</span> reqStream <span style="color: #FF8000;">As</span> Stream <span style="color: #008000;">=</span> request.<span style="color: #0000FF;">GetRequestStream</span>
reqStream.<span style="color: #0600FF;">Write</span><span style="color: #000000;">&#40;</span>xmlBytes, <span style="color: #FF0000;">0</span>, xmlBytes.<span style="color: #0000FF;">Length</span><span style="color: #000000;">&#41;</span>
reqStream.<span style="color: #0600FF;">Close</span>
&nbsp;
<span style="color: #0600FF;">Try</span>
     <span style="color: #0600FF;">Dim</span> resp <span style="color: #FF8000;">As</span> HttpWebResponse <span style="color: #008000;">=</span> <span style="color: #0600FF;">CType</span><span style="color: #000000;">&#40;</span>request.<span style="color: #0000FF;">GetResponse</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>,HttpWebResponse<span style="color: #000000;">&#41;</span>
     <span style="color: #0600FF;">Dim</span> reader <span style="color: #FF8000;">As</span> StreamReader <span style="color: #008000;">=</span> <span style="color: #FF8000;">New</span> StreamReader<span style="color: #000000;">&#40;</span>resp.<span style="color: #0000FF;">GetResponseStream</span><span style="color: #000000;">&#41;</span>
     <span style="color: #008080; font-style: italic;">' do something with the result XML string</span>
     <span style="color: #0600FF;">Dim</span> userXml <span style="color: #FF8000;">As</span> <span style="color: #FF8000;">String</span> <span style="color: #008000;">=</span> reader.<span style="color: #0000FF;">ReadToEnd</span>
<span style="color: #0600FF;">Catch</span> e <span style="color: #FF8000;">As</span> WebException
     <span style="color: #008080; font-style: italic;">' handle the error</span>
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Try</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/03/14/floorplanner-api-aspnet-and-authorization/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Floorplanning in the Cloud, EC2</title>
		<link>http://techblog.floorplanner.com/2009/02/05/floorplanning-in-the-cloud-ec2/</link>
		<comments>http://techblog.floorplanner.com/2009/02/05/floorplanning-in-the-cloud-ec2/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 20:25:33 +0000</pubDate>
		<dc:creator>Gert-Jan</dc:creator>
				<category><![CDATA[Floorplanner]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[ec2]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=436</guid>
		<description><![CDATA[There is a lot of hype these day about being in &#8220;the cloud&#8221;. However, &#8220;the cloud&#8221; seems to mean a lot of different things. Tim O&#8217;Reilly sees three types of cloud computing.  His first type, utility computing, is the type I&#8217;m talking about here. 
Utility computing. Amazon&#8217;s success in providing virtual machine instances, storage, and computation at pay-as-you-go utility [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F02%2F05%2Ffloorplanning-in-the-cloud-ec2%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F02%2F05%2Ffloorplanning-in-the-cloud-ec2%2F" height="61" width="51" /></a></div><p>There is a lot of hype these day about being in &#8220;the cloud&#8221;. However, &#8220;the cloud&#8221; seems to mean a lot of different things. Tim O&#8217;Reilly sees <a href="http://radar.oreilly.com/2008/10/web-20-and-cloud-computing.html">three types of cloud computing</a>.  His first type, utility computing, is the type I&#8217;m talking about here. </p>
<blockquote><p><strong><em>Utility computing.</em></strong><em> Amazon&#8217;s success in providing virtual machine instances, storage, and computation at pay-as-you-go utility pricing was the breakthrough in this category, and now everyone wants to play. Developers, not end-users, are the target of this kind of cloud computing.</em></p></blockquote>
<p>Launched in July 2002, <a title="Amazon Web Services" href="http://aws.amazon.com" target="_blank">Amazon Web Services</a> provide online services for other web sites or client-side applications.<span style="text-decoration: underline;"> </span>Each individual product is interesting by itself, but all the services together made it just the solution we were looking for. In this and coming posts I will talk about our experiences with Amazon&#8217;s version of &#8220;the cloud&#8221;. The first service we started to use was <a href="http://aws.amazon.com/ec2/">Elastic Cloud Computing</a> (EC2).</p>
<p>Each day more than 2000 users from all over the world register at Floorplanner.com. At this moment we have over 800.000 registered users in our database. A lot of these users visit the site on a regular basis, which generates a lot of traffic. To meet this demand, we had a couple of dedicated servers running. When the demand rised above a certain level, we&#8217;d add a new one to spread the load. As logical as it might sound, it is far from ideal.</p>
<p>It takes a lot of time to install, configure and maintain a server. Precious time you can&#8217;t spend on the development of your product. It doesn&#8217;t scale fast. For example: when you are featured on a big site that generates a lot of additional traffic, your servers will probably have a very hard time (or crash) and there is nothing you can do about it. Buying additional servers takes too much time. Another thing about buying servers is that it&#8217;s an investment you have to finance up front. You have to pay the full price for it, but in the beginning you&#8217;ll only use a small part of it&#8217;s capacities. Once you&#8217;ve spend the money on a server, you can&#8217;t spend it on anything else. And maybe the biggest issue we had with dedicated servers was that it is hardware, and hardware gets old very fast. After a while you&#8217;re stuck with an outdated server, that you (a) won&#8217;t replace because &#8220;it&#8217;s still doing something&#8221; or (b) costs time (= money) to migrate to another server. This means a higher risk for failure, or just more work.   </p>
<p>Now with the EC2 service life has gotten better. Sure, we still had to install everything on the virtual instance, but only the first time. Once you&#8217;ve done this, you can add additional instances with a click of a button (based on an image of the first instance). When traffic spikes you can add instances within minutes instead of days. The pay-as-you-go model keeps us from financing every server up front. And because it&#8217;s a virtual server, we don&#8217;t have to think about the hardware anymore. Just deploy it and get on with the fun stuff!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/02/05/floorplanning-in-the-cloud-ec2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Papervision3D forum</title>
		<link>http://techblog.floorplanner.com/2009/01/20/papervision3d-forum/</link>
		<comments>http://techblog.floorplanner.com/2009/01/20/papervision3d-forum/#comments</comments>
		<pubDate>Tue, 20 Jan 2009 15:45:34 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[CAD]]></category>
		<category><![CDATA[Flash+ActionScript]]></category>
		<category><![CDATA[Floorplanner]]></category>
		<category><![CDATA[Papervision3D]]></category>
		<category><![CDATA[forum]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=415</guid>
		<description><![CDATA[On request of many: Papervision3D now has a forum : http://forum.papervision3d.org/
Read more at the Papervision3D blog.
]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F01%2F20%2Fpapervision3d-forum%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F01%2F20%2Fpapervision3d-forum%2F" height="61" width="51" /></a></div><p>On request of many: Papervision3D now has a forum : http://forum.papervision3d.org/</p>
<p>Read more at the <a href="http://blog.papervision3d.org/2009/01/19/forumpapervision3dorg/">Papervision3D blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/01/20/papervision3d-forum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Papervision3D wins Innovation Of The Year award</title>
		<link>http://techblog.floorplanner.com/2008/12/09/papervision3d-wins-innovation-of-the-year-award/</link>
		<comments>http://techblog.floorplanner.com/2008/12/09/papervision3d-wins-innovation-of-the-year-award/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 20:15:17 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Flash+ActionScript]]></category>
		<category><![CDATA[Floorplanner]]></category>
		<category><![CDATA[Papervision3D]]></category>
		<category><![CDATA[award]]></category>
		<category><![CDATA[papervisi]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=309</guid>
		<description><![CDATA[Papervision3D has won the INNOVATION OF THE YEAR in this year’s .net Awards!
Other nominees included Google Android and App Engine, Microsoft Telescope, Open Social and Silverlight 2. I&#8217;m very proud to be part of the Papervision3D team!

Read more on the Papervision3D blog.
]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2008%2F12%2F09%2Fpapervision3d-wins-innovation-of-the-year-award%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2008%2F12%2F09%2Fpapervision3d-wins-innovation-of-the-year-award%2F" height="61" width="51" /></a></div><p>Papervision3D has won the INNOVATION OF THE YEAR in this year’s <a href="http://www.thenetawards.com/">.net Awards</a>!<br />
Other nominees included Google Android and App Engine, Microsoft Telescope, Open Social and Silverlight 2. I&#8217;m very proud to be part of the Papervision3D team!</p>
<p><img title="dotnet innovation award 2008" src="http://papervision3d.files.wordpress.com/2008/12/web_rgb_logo2.gif?w=240&amp;h=198" alt="dotnet innovation award 2008" width="240" height="198" /></p>
<p>Read more on the <a href="http://blog.papervision3d.org/2008/12/09/innovation-of-the-year/">Papervision3D blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2008/12/09/papervision3d-wins-innovation-of-the-year-award/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Generating thumbnails</title>
		<link>http://techblog.floorplanner.com/2008/11/26/generating-thumbnails/</link>
		<comments>http://techblog.floorplanner.com/2008/11/26/generating-thumbnails/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 06:27:05 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Floorplanner]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[client-side]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[S3]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=271</guid>
		<description><![CDATA[I would like to thank you all for helping us build our thumbnail database!  I presume this statement might be in need of some clarification, so bear with me when I go into the technical details on this one.
For every design that is saved on Floorplanner, we create a thumbnail in JPEG format. We [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2008%2F11%2F26%2Fgenerating-thumbnails%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2008%2F11%2F26%2Fgenerating-thumbnails%2F" height="61" width="51" /></a></div><p>I would like to thank you all for helping us build our thumbnail database! <br /> I presume this statement might be in need of some clarification, so bear with me when I go into the technical details on this one.</p>
<p>For every design that is saved on Floorplanner, we create a thumbnail in JPEG format. We use these thumbnails for the <a href="http://beta.floorplanner.com/gallery">gallery</a>, and now we have included them on everyone&#8217;s <a href="http://beta.floorplanner.com/dashboard">dashboard</a>. However, for various reasons, we do not have a thumbnail available for every design. However, with your help, we are improving the thumbnail database while you our browsing the site!</p>
<p>The thumbnail images are stored on <a href="http://aws.amazon.com/s3/">Amazon AWS S3</a>. We know the URL that a thumbnail of a design should have, but we do not know if it actually is available. In the latter case, the result is a nasty <em>image not found</em> placeholder on the dashboard. This of course is not acceptable! We cannot know if a thumbnail exists other than doing a request to the URL and see whether we get an image back from Amazon, or a HTTP 404 status. This is a very time-consuming procedure to run server side so we chose to find a client-side solution.</p>
<p>We found that javascript can be used to check if an image exist. An AJAX call cannot be used, because cross-site calls are not supported. However, the javascript <code>Image</code> object <em>can</em> be used for this purpose.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family: Monaco,monospace;"><span style="color: #003366; font-weight: bold;">var</span> img <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Image<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
img.<span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// image was found and loaded successfully</span>
  document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'img-tag'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> img.<span style="color: #660066;">src</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
img.<span style="color: #000066;">onerror</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// An error occured while loading the image</span>
  document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'img-tag'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'/images/thumb-unavailable.jpg'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Setting the src property will trigger the events.</span>
img.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'http://link.to.amazon.s3/design/thumbnail.jpg'</span><span style="color: #339933;">;</span></pre></div></div>

<p>A nice <em>thumbnail not available</em> image will be shown if the thumbnail file cannot be found on S3. This is much nicer, and the check is completely done client-side! However, we found a way this could even be better by changing the <code>onerror</code> event handler. Instead of displaying a <em>thumbnail not available</em> image, we can simply load a small instance of the Floorplanner application to display a small version of the design. Moreover, we can instruct it to generate a thumbnail JPEG and save it to S3!</p>
<p>So, every time you see a small Floorplanner loading on your dashboard, you are creating a missing thumbnail. Next time, the thumbnail will be available on S3 and there will be no need to start the Floorplanner application. A nice example of <a href="http://en.wikipedia.org/wiki/Distributed_computing">distributed computing</a>, mixed with a hint of <a href="http://setiathome.berkeley.edu/">SETI@home</a>. I like it!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2008/11/26/generating-thumbnails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alchemy &#8211; first looks</title>
		<link>http://techblog.floorplanner.com/2008/11/23/alchemy-first-looks/</link>
		<comments>http://techblog.floorplanner.com/2008/11/23/alchemy-first-looks/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 15:30:26 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[CAD]]></category>
		<category><![CDATA[Flash+ActionScript]]></category>
		<category><![CDATA[Floorplanner]]></category>
		<category><![CDATA[Papervision3D]]></category>
		<category><![CDATA[alchemy flash as3 swc triangulation]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=261</guid>
		<description><![CDATA[Adobe has recently released a preview version of Alchemy. From their site:
Welcome the preview release of codename &#8220;Alchemy.&#8221; Alchemy is a research project that allows users to compile C and C++ code that is targeted to run on the open source ActionScript Virtual Machine (AVM2). The purpose of this preview is to assess the level [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2008%2F11%2F23%2Falchemy-first-looks%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2008%2F11%2F23%2Falchemy-first-looks%2F" height="61" width="51" /></a></div><p>Adobe has recently released a preview version of <a href="http://labs.adobe.com/technologies/alchemy/">Alchemy</a>. From their site:</p>
<blockquote><p>Welcome the preview release of codename &#8220;Alchemy.&#8221; Alchemy is a research project that allows users to compile C and C++ code that is targeted to run on the open source ActionScript Virtual Machine (AVM2). The purpose of this preview is to assess the level of community interest in reusing existing C and C++ libraries in Web applications that run on Adobe® Flash® Player and Adobe AIR®.</p></blockquote>
<p>So, what does this mean? This means that we can use existing C/C++ code and compile that down to AS3. Initially I though that this implied a hefty increase in code execution speed, but as all is compiled down to AS3 this is <strong>not</strong> true in most cases. Code will only run faster if you &#8217;stay&#8217; on the C-side and only return to &#8216;AS3&#8242; when your C code is done processing. The reason is that AS3 method-calls are sloooow (params need to be &#8216;unboxed&#8217; etc.)! When in C this slowness doesn&#8217;t occur and hence execution speed will be faster (Adobe claims a potential speed increase by a factor 2 to 10 I beleive). Wow! That of course made me wonder whether Alchemy would be usefull for 3D engines like Papervision3D, more soon! <img src='http://techblog.floorplanner.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://www.automatastudios.com">Branden Hall</a> did a nice <a href="http://www.automatastudios.com/2008/11/21/understanding-adobe-alchemy/">writeup</a> on Alchemy explaining above better then me.</p>
<p>I couldn&#8217;t resist myself and started off immediately with something I always wanted to code for our 3D engine: <a href="http://en.wikipedia.org/wiki/Polygon_triangulation">Polygon Triangulation</a> with support for holes.</p>
<p>I installed the <a href="http://labs.adobe.com/downloads/alchemy.html">Alchemy Toolkit</a>, got the Flex 3.2 SDK and got some C code from the <a href="http://www.cs.unc.edu/~dm/CODE/GEM/chapter.html">Department of Computer Science, UNC Chapel Hill</a>.</p>
<p>Setting up the toolkit was bit tricky, but with help from <a href="http://labs.adobe.com/wiki/index.php/Alchemy:Documentation:Getting_Started">this page</a> I finally succeeded to get my environment right (OSX). Then I hit &#8216;make&#8217; and presto! Got my swc! <a href="http://www.assembla.com/spaces/floorplanner-alchemy/documents">Download the swc and sample code</a> or <a href="http://www.assembla.com/spaces/floorplanner-alchemy/documents/agZ5W8Uxir3y-mab7jnrAJ/download/TriangulationTest.swf">view a live example</a>.</p>
<p>Some notes on swc usage:<br />
1] &#8216;outer&#8217; polygons must be defined anti-clockwise<br />
2] &#8216;inner&#8217; polygons (holes) must be defined clock-wise</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="actionscript3" style="font-family: Monaco,monospace;"><span style="color: #009900;">// import</span>
<span style="color: #0033ff; font-weight: bold;">import</span> cmodule.triangulation.CLibInit;
&nbsp;
<span style="color: #009900;">// initialize</span>
<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">loader</span><span style="color: #000000; font-weight: bold;">:</span>CLibInit = <span style="color: #0033ff; font-weight: bold;">new</span> CLibInit;
<span style="color: #6699cc; font-weight: bold;">var</span> lib<span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">Object</span> = <span style="color: #004993;">loader</span>.<span style="color: #004993;">init</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
&nbsp;
<span style="color: #009900;">// @vertices is an array of XY-pairs: [ [], [x0, y0], [x1, y1], ...]</span>
<span style="color: #009900;">//                NOTE: @vertices[0] should always be [] </span>
<span style="color: #009900;">// @contours is an array containing the number of points of each polygon</span>
<span style="color: #009900;">//                =&gt; [4, 3, 3, 3] indicates 4 polygons with the first poly having 4 points, the second 3, etc.</span>
<span style="color: #009900;">// @ncontours is the number of polygons (in our example: 4)</span>
<span style="color: #009900;">//</span>
<span style="color: #009900;">// @return An array of indices into the vertices array in form: [ [p0, p1, p2], [p0, p1, p2], ...]</span>
<span style="color: #6699cc; font-weight: bold;">var</span> indices <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Array</span> = lib.triangulate<span style="color: #000000;">&#40;</span> vertices, contours, ncontours <span style="color: #000000;">&#41;</span>;</pre></td></tr></table></div>

<p>Here&#8217;s the relevant C code which was simply added to tri.c :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
</pre></td><td class="code"><pre class="c" style="font-family: Monaco,monospace;"><span style="color: #993333;">static</span> AS3_Val triangulate<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #339933;">*</span> self<span style="color: #339933;">,</span> AS3_Val args<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> ncontours <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> ccount<span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> npoints<span style="color: #339933;">,</span> first<span style="color: #339933;">,</span> last<span style="color: #339933;">,</span> n<span style="color: #339933;">,</span> nmonpoly<span style="color: #339933;">;</span>
	<span style="color: #993333;">register</span> <span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> op<span style="color: #009900;">&#91;</span>SEGSIZE<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> ntriangles<span style="color: #339933;">;</span>
	AS3_Val dataVal<span style="color: #339933;">;</span>
	AS3_Val contourVal<span style="color: #339933;">;</span>
	AS3_Val retVal<span style="color: #339933;">;</span>
	AS3_Val temp<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;">/* initialze the AS3 values */</span>
	dataVal <span style="color: #339933;">=</span> AS3_Undefined<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	contourVal <span style="color: #339933;">=</span> AS3_Undefined<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	retVal <span style="color: #339933;">=</span> AS3_Undefined<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	temp <span style="color: #339933;">=</span> AS3_Undefined<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//parse the arguments.</span>
	AS3_ArrayValue<span style="color: #009900;">&#40;</span> args<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;AS3ValType, AS3ValType, IntType&quot;</span><span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>dataVal<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>contourVal<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>ncontours <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//if no argument is specified</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>dataVal <span style="color: #339933;">==</span> NULL <span style="color: #339933;">||</span> contourVal <span style="color: #339933;">==</span> NULL <span style="color: #339933;">||</span> ncontours <span style="color: #339933;">&lt;=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		AS3_Trace<span style="color: #009900;">&#40;</span> AS3_String<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Invalid input data!&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">return</span> AS3_Null<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	ccount <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	i <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>ccount <span style="color: #339933;">&lt;</span> ncontours<span style="color: #009900;">&#41;</span>
   	<span style="color: #009900;">&#123;</span>
		<span style="color: #993333;">int</span> j<span style="color: #339933;">;</span>
		<span style="color: #993333;">int</span> k<span style="color: #339933;">;</span>
		<span style="color: #666666; font-style: italic;">//fscanf(infile, &quot;%d&quot;, &amp;npoints);</span>
&nbsp;
		npoints <span style="color: #339933;">=</span> AS3_IntValue<span style="color: #009900;">&#40;</span> AS3_Get<span style="color: #009900;">&#40;</span>contourVal<span style="color: #339933;">,</span> AS3_Int<span style="color: #009900;">&#40;</span>ccount<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		first <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
		last <span style="color: #339933;">=</span> first <span style="color: #339933;">+</span> npoints <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>j <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> k <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;</span> npoints<span style="color: #339933;">;</span> j<span style="color: #339933;">++,</span> i<span style="color: #339933;">++,</span> k <span style="color: #339933;">+=</span> <span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">//fscanf(infile, &quot;%lf%lf&quot;, &amp;seg[i].v0.x, &amp;seg[i].v0.y);</span>
			temp <span style="color: #339933;">=</span> AS3_Get<span style="color: #009900;">&#40;</span>dataVal<span style="color: #339933;">,</span> AS3_Int<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">v0</span>.<span style="color: #202020;">x</span> <span style="color: #339933;">=</span> AS3_NumberValue<span style="color: #009900;">&#40;</span> AS3_Get<span style="color: #009900;">&#40;</span>temp<span style="color: #339933;">,</span> AS3_Int<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">v0</span>.<span style="color: #202020;">y</span> <span style="color: #339933;">=</span> AS3_NumberValue<span style="color: #009900;">&#40;</span> AS3_Get<span style="color: #009900;">&#40;</span>temp<span style="color: #339933;">,</span> AS3_Int<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">==</span> last<span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">next</span> <span style="color: #339933;">=</span> first<span style="color: #339933;">;</span>
				seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">prev</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
				seg<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #202020;">v1</span> <span style="color: #339933;">=</span> seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">v0</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">==</span> first<span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">next</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
				seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">prev</span> <span style="color: #339933;">=</span> last<span style="color: #339933;">;</span>
				seg<span style="color: #009900;">&#91;</span>last<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">v1</span> <span style="color: #339933;">=</span> seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">v0</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #b1b100;">else</span>
			<span style="color: #009900;">&#123;</span>
				seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">prev</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
				seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">next</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
				seg<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #202020;">v1</span> <span style="color: #339933;">=</span> seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">v0</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			seg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">is_inserted</span> <span style="color: #339933;">=</span> FALSE<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		ccount<span style="color: #339933;">++;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	n <span style="color: #339933;">=</span> i <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
	initialise<span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	construct_trapezoids<span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	nmonpoly <span style="color: #339933;">=</span> monotonate_trapezoids<span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	ntriangles <span style="color: #339933;">=</span> triangulate_monotone_polygons<span style="color: #009900;">&#40;</span>n<span style="color: #339933;">,</span> nmonpoly<span style="color: #339933;">,</span> op<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	retVal <span style="color: #339933;">=</span> AS3_Array<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;AS3ValType&quot;</span><span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> ntriangles<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
   	<span style="color: #009900;">&#123;</span>
		AS3_Val data <span style="color: #339933;">=</span> AS3_Array<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;IntType, IntType, IntType&quot;</span><span style="color: #339933;">,</span> op<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> op<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> op<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		AS3_Set<span style="color: #009900;">&#40;</span>retVal<span style="color: #339933;">,</span> AS3_Int<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> retVal<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//entry point for code</span>
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//define the methods exposed to ActionScript</span>
	<span style="color: #666666; font-style: italic;">//typed as an ActionScript Function instance</span>
	AS3_Val echoMethod <span style="color: #339933;">=</span> AS3_Function<span style="color: #009900;">&#40;</span> NULL<span style="color: #339933;">,</span> echo <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	AS3_Val triMethod <span style="color: #339933;">=</span> AS3_Function<span style="color: #009900;">&#40;</span> NULL<span style="color: #339933;">,</span> triangulate <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// construct an object that holds references to the functions</span>
	AS3_Val result <span style="color: #339933;">=</span> AS3_Object<span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;echo: AS3ValType&quot;</span><span style="color: #339933;">,</span> echoMethod <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	AS3_SetS<span style="color: #009900;">&#40;</span>result<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;triangulate&quot;</span><span style="color: #339933;">,</span> triMethod<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Release</span>
	AS3_Release<span style="color: #009900;">&#40;</span> echoMethod <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	AS3_Release<span style="color: #009900;">&#40;</span> triMethod <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// notify that we initialized -- THIS DOES NOT RETURN!</span>
	AS3_LibInit<span style="color: #009900;">&#40;</span> result <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// should never get here!</span>
	<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2008/11/23/alchemy-first-looks/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Printing &amp; Big Bitmaps</title>
		<link>http://techblog.floorplanner.com/2008/10/22/printing-and-big-bitmaps/</link>
		<comments>http://techblog.floorplanner.com/2008/10/22/printing-and-big-bitmaps/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 20:28:27 +0000</pubDate>
		<dc:creator>Rinde van Lon</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Flash+ActionScript]]></category>
		<category><![CDATA[Floorplanner]]></category>
		<category><![CDATA[bitmapdata]]></category>
		<category><![CDATA[printing]]></category>
		<category><![CDATA[printjob]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=219</guid>
		<description><![CDATA[Last week I started working on a new version of the print functionality in Floorplanner. The problem with the previous version was that it didn&#8217;t print shadows, it was impossible to rotate the plan to landscape and textures didn&#8217;t look very well. Overall it produced a very mediocre image compared to the visual quality of [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2008%2F10%2F22%2Fprinting-and-big-bitmaps%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2008%2F10%2F22%2Fprinting-and-big-bitmaps%2F" height="61" width="51" /></a></div><p>Last week I started working on a new version of the print functionality in Floorplanner. The problem with the previous version was that it didn&#8217;t print shadows, it was impossible to rotate the plan to landscape and textures didn&#8217;t look very well. Overall it produced a very mediocre image compared to the visual quality of a plan on the screen. As can be seen below:</p>
<div id="attachment_223" class="wp-caption alignleft" style="width: 221px"><a href="http://techblog.floorplanner.com/wp-content/uploads/2008/10/huidig1.png" target="_blank"><img class="size-medium wp-image-223" style="border: 1px solid black;" title="Old print output" src="http://techblog.floorplanner.com/wp-content/uploads/2008/10/huidig1-211x300.png" alt="Old print output" width="211" height="300" /></a><p class="wp-caption-text">Old print output</p></div>
<p>For printing we use the <a href="http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&amp;file=00002065.html" target="_blank">AS2 PrintJob class</a>, which works really easy, with a small disadvantage: <em>it doesn&#8217;t print Floorplans properly</em>. I tried all kinds of settings for this class, with as input just a MovieClip with a drawing of the plan on it. I tried setting the printAsBitmap to true and false, both giving the exact same result. So although being stuck with it, the printAsBitmap boolean inspired me to investigate the Bitmap thing. We already had an image export utility, which produces images of a Floorplan with the same quality as it is shown in the FlashPlayer. The funny thing is that when I printed this exported image, the print quality was really good, at least a lot better than our own printing functionality. So for some reason, even if I used the printAsBitmap functionality, it still didn&#8217;t produce the same quality as using a real bitmap.<br />
Of course we could have stopped here and just tell the users of Floorplanner to print the exported image. But since we are Floorplanner, we didn&#8217;t want to introduce another step requiring user action in the printing process, after all, we are the &#8220;easiest way&#8221; <img src='http://techblog.floorplanner.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .<br />
So I decided to use the same BitmapData created for the image export as basis for the printing. The first results where rather disappointing, I attached the created BitmapData to a MovieClip which in turn was given to the PrintJob. The produced print was of really low quality, you could easily see pixels all over the place. I tried using more pixels but now I bumped into the pixel limit of BitmapData (2880&#215;2880 pixels). To work around this I invented the BigBitmapData class, this is a wrapper class that mimics the functionality of the BitmapData class, but which doesn&#8217;t have an upper limit of the number of pixels which can be used. When an instance of BitBitmapData is created which is bigger than 2880 by 2880, it creates additional BitmapDatas to store the additional pixels needed. So in fact the BigBitmapData internally stores an two dimensional array of BitmapDatas to bypass the pixel limit.<br />
So with this new class I was able to scale up the created image to unprecedented sizes. I did a lot of printing experiments with scaling of the input, I tried scaling settings from 2 times to more than 10 times! This huge bitmap was attached to a MovieClip which in turn had to be scaled to fit on one single page of the printer. These values did give a better result, but still not good enough. It turned out that I had to take the <a href="http://en.wikipedia.org/wiki/Dots_per_inch" target="_blank">DPI</a> of the printer into account. The optimal scale factor turned out to be (1 / 72) * 300. The 72 is the DPI of the screen, and the 300 is the DPI of the printer. Furthermore a &#8216;point&#8217; (print unit of measurement) is 1/72 inch, while the size of a pixel (screen unit of measurement) is dependent on the resolution of the screen.<br />
So what this method actually does is creating a big image (which is resized to the paper contents) with enough quality to be printable on a 300 DPI printer.</p>
<div id="attachment_227" class="wp-caption alignleft" style="width: 310px"><a href="http://techblog.floorplanner.com/wp-content/uploads/2008/10/new.png" target="_blank"><img class="size-medium wp-image-227" style="border: 1px solid black;" title="New print output" src="http://techblog.floorplanner.com/wp-content/uploads/2008/10/new-300x231.png" alt="New print output" width="300" height="231" /></a><p class="wp-caption-text">New print output</p></div>
<p>So as you can see in the second image above, the new print looks a lot better, and since the new print uses bitmaps it is really easy to rotate it to always produce a print that tries to fill the entire paper.</p>
<p>A disadvantage of this method is that it takes quite some computational power to compute all the pixels for the bitmap that is created in memory, so as a result the FlashPlayer and sometimes even the browser freezes for a moment. Although this isn&#8217;t very good, we thought this behavior is acceptable since the quality of the prints is much better than the previous ones and the freeze time is actually really short. If you are not convinced by the images (which is understandable since the quality difference can only be seen on paper), just <a href="http://beta.floorplanner.com/demo" target="_blank">check it out</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2008/10/22/printing-and-big-bitmaps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Welcome back!</title>
		<link>http://techblog.floorplanner.com/2008/07/14/welcome-back/</link>
		<comments>http://techblog.floorplanner.com/2008/07/14/welcome-back/#comments</comments>
		<pubDate>Mon, 14 Jul 2008 18:53:08 +0000</pubDate>
		<dc:creator>Gert-Jan</dc:creator>
				<category><![CDATA[Floorplanner]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=94</guid>
		<description><![CDATA[Welcome to our brand new Floorplanner tech blog! Here we will be posting all our little technical adventures while working on the Floorplanner. This blog focusses mainly on the technical side of the Floorplanner, so you can expect stories about Flash/Flex, Ruby on Rails, Papervision 3D, JavaScript and all other kinds of thingies we run into [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2008%2F07%2F14%2Fwelcome-back%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2008%2F07%2F14%2Fwelcome-back%2F" height="61" width="51" /></a></div><p>Welcome to our brand new Floorplanner tech blog! Here we will be posting all our little technical adventures while working on the <a title="Floorplanner" href="http://beta.floorplanner.com">Floorplanner</a>. This blog focusses mainly on the technical side of the Floorplanner, so you can expect stories about Flash/Flex, Ruby on Rails, Papervision 3D, JavaScript and all other kinds of thingies we run into on a daily basis. </p>
<p>You might know that we did a similar thing at a <a title="Suite75 Tech Blog" href="http://suite75.net/blog/dev">tech blog</a> on Suite75, but a couple of things have changed over the last year. As <a title="Suite75" href="http://www.suite75.com">Suite75</a> we developed rich internet applications for all kinds of clients. Instead of doing a lot of different projects for clients, we wanted to build and sell our own product. Our mission: to be the easiest, quickest and best looking way to create and share interactive floor plans online. Floorplanner was born.</p>
<p>Along with the mission came a huge amount of technical challenges in the world that is know as the World Wide Web. It will be our pleasure to tell you about all the technical problems (and hopefully the solutions) we had to overcome to achieve our goal. So buckle up and join us on the bumpy road!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2008/07/14/welcome-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
