<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>Teehan+LaxLabs | Teehan+Lax</title>
	
	<link>http://www.teehanlax.com</link>
	<description>We define and design custom experiences in the digital channel</description>
	<lastBuildDate>Mon, 22 Apr 2013 15:09:38 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/tllabs" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="tllabs" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Google Street View Hyperlapse</title>
		<link>http://www.teehanlax.com/labs/hyperlapse/</link>
		<comments>http://www.teehanlax.com/labs/hyperlapse/#comments</comments>
		<pubDate>Tue, 09 Apr 2013 15:20:50 +0000</pubDate>
		<dc:creator>Peter Nitsch</dc:creator>
		
		<guid isPermaLink="false">http://www.teehanlax.com/?post_type=labs&amp;p=9311</guid>
		<description><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wordpress/wp-content/uploads/lead-740x350.jpg' /><br /><br />Create a Hyperlapse. Hyper-lapse photography &#8211; a technique combining time-lapse and sweeping camera movements typically focused on a point-of-interest &#8211; has been a growing trend...
]]></description>
			<content:encoded><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wordpress/wp-content/uploads/lead-740x350.jpg' /><br /><br /><p><a href="http://hyperlapse.tllabs.io">Create a Hyperlapse.</a></p>
<p>Hyper-lapse photography &#8211; a technique combining time-lapse and sweeping camera movements typically focused on a point-of-interest &#8211; has been a growing trend on video sites. It&#8217;s not hard to find <a href="https://vimeo.com/search?q=hyperlapse">stunning examples on Vimeo</a>. Creating them requires <a href="http://www.youtube.com/watch?v=PFUyxbh_ed0#!">precision and many hours stitching</a> together photos taken from carefully mapped locations. We aimed at making the process simpler by using Google Street View as an aid, but quickly discovered that it could be used as the source material. It worked so well, we decided to design a very usable UI around our engine and release <a href="http://hyperlapse.tllabs.io">Google Street View Hyperlapse</a>. </p>
<p>The site settings are purposely low (like having a maximum of 60 frames per animation) for greater accessibility. However, all the source code is <a href="https://github.com/TeehanLax/Hyperlapse.js">available on Github</a> (including examples and documentation) so developers can play with higher frame rates, better image quality, and more complicated camera movements.  </p>
<p><a href="http://hyperlapse.tllabs.io"><img src="http://teehanlax.com.s3.amazonaws.com/wordpress/wp-content/uploads/site.jpg" alt="" title="site" width="740" height="505" class="alignnone size-full wp-image-9347" /></a></p>
<p>The idea for this project came from one of our motion designers, Jonas, as part of his Labs experiment. He wanted to explore a tool that could help him create hyper-lapse videos with the assistance of available data sets and emerging technology. We built the tool &#8211; he built a video with it. The results are pretty stunning.</p>
<p><iframe src="http://player.vimeo.com/video/63653873?title=0&amp;byline=0&amp;portrait=0" width="740" height="417" frameborder="0"></iframe></p>

]]></content:encoded>
			<wfw:commentRss>http://www.teehanlax.com/labs/hyperlapse/feed/</wfw:commentRss>
		<slash:comments>123</slash:comments>
		</item>
		<item>
		<title>What Should Connected Appliances Do?</title>
		<link>http://www.teehanlax.com/labs/connected-appliances/</link>
		<comments>http://www.teehanlax.com/labs/connected-appliances/#comments</comments>
		<pubDate>Thu, 14 Feb 2013 19:51:21 +0000</pubDate>
		<dc:creator>Peter Nitsch</dc:creator>
		
		<guid isPermaLink="false">http://www.teehanlax.com/?post_type=labs&amp;p=9074</guid>
		<description><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/lead5-740x350.jpg' /><br /><br />&#8220;Simplicity is the ultimate sophistication.&#8221; ― Leonardo da Vinci Let&#8217;s take a moment to think about connected appliances (or &#8220;Smart&#8221; appliances if you&#8217;re a marketer)...
]]></description>
			<content:encoded><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/lead5-740x350.jpg' /><br /><br /><h2>&#8220;Simplicity is the ultimate sophistication.&#8221;<br />
― Leonardo da Vinci</h2>
</p>
<p>Let&#8217;s take a moment to think about connected appliances (or &#8220;Smart&#8221; appliances if you&#8217;re a marketer) &#8211; those expensive, futuristic home units with touchscreen LCD&#8217;s and an overabundance of software features. At least, that&#8217;s what <a href="http://www.theverge.com/2013/1/16/3867932/evernote-on-your-fridge-ces-home-appliance-insanity">we saw plenty of at this years CES</a>. Should a connected fridge really have Evernote integration? Should it track expiry dates, or tell you what foods are in season? Should it tweet, sync with Google Apps, or play Star Wars Angry Birds in HD? Increasingly, those are the kind of innovations we&#8217;ve seen demoed by the large appliance manufacturers &#8211; and it&#8217;s exactly the wrong approach they should be taking when designing these products.</p>
<p><span id="more-9074"></span></p>
<p>A refrigerator has a simple purpose &#8211; prolonged food storage. The data associated with storage is inventory. So naturally the core function of an internet-connected fridge is to provide us with a tally of its contents. That&#8217;s it. Luckily, we already have a good model for taking a quick inventory &#8211; <strong>opening the door</strong> and <strong>looking inside</strong>. Our eyes and memory do the rest. A brief glimpse immediately tells us if we forgot to buy eggs last week, how many bags of milk are left (<a href="http://en.wikipedia.org/wiki/Milk_bag">a Canadian thing</a>), and if the fruit looks spoiled.</p>
<p>The most basic connected fridge that fulfills its purpose is one that takes a picture of its contents and pushes them to your devices. It provides you the opportunity to take a glimpse inside the unit wherever you are (probably the grocery store), just like you were at home. This approach is so brain-dead simple and easy to implement with some basic components, and yet we haven&#8217;t seen it from manufacturers. Instead, <a href="http://live.wsj.com/video/can-you-tweet-from-your-fridge/0E6425EB-DAD8-4ED2-8821-AF32729524CF.html#!0E6425EB-DAD8-4ED2-8821-AF32729524CF">we can tweet</a>.</p>
<p>We hacked together our own connected fridge that snaps shots every time the door opens and uploads them to the cloud. It took barely any time to construct (since it was patched together with masking tape and rubber bands) and used some very basic components. In actuality, the site to host the images took longer. The result is very rudimentary and ugly, but it works and communicates exactly what it should &#8211; inventory. <a href="http://fridge.teehanlax.com/">Take a peek inside.</a></p>
<h3>Build your own connected fridge.</h3>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/parts.jpg" alt="" title="Parts" width="680" height="408" class="alignnone size-full wp-image-9099" /></p>
<p>
<strong>Necessary Parts:</strong><br />
2 HD webcams (we used <a href="http://www.logitech.com/en-us/product/hd-webcam-c615?crid=34">Logitech c615</a>)<br />
1 <a href="http://www.raspberrypi.org/">Raspberry Pi</a><br />
1 <a href="http://en.wikipedia.org/wiki/Reed_switch">Reed Switch</a><br />
1 Magnet<br />
Bunch of wires (USB, jumper, ethernet)
</p>
<p>Wire a reed switch (ground, vcc, and signal) to the Raspberry Pi. We used GPIO4 for signal. Attach the switch to the door hinge at the top of the fridge. Glue a magnet to the top of the door such that when the door is at an open position, it&#8217;s directly under the reed switch. This will send a signal to the Pi.</p>
<p>Connect the cameras to the Pi and embed them in the fridge. We were lucky enough to have an opposing wall so the cameras could be mounted outside, but that&#8217;s an unusual setup. Embedding inside would be a lot more time consuming and would involve drilling through door for wire passthrough, plus resealing so cold air does not escape.</p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/assembled.jpg" alt="" title="Assembled" width="680" height="724" class="alignnone size-full wp-image-9103" /></p>
<p>Next, you need to program the Raspberry Pi to watch for the signal from the reed switch, take photos, and send them up to the cloud. There are many ways to do this, but ours was with <a href="http://manpages.ubuntu.com/manpages/lucid/man1/fswebcam.1.html">fswebcam</a>, and some basic <a href="http://nodejs.org/">node.js</a>.</p>
<p>Install fswebcam:</p>
<pre class="brush: bash; title: ;">
$ sudo apt-get update
$ sudo apt-get install fswebcam
</pre>
</p>
<p>Install node.js:</p>
<pre class="brush: bash; title: ;">
$ wget http://nodejs.org/dist/v0.8.19/node-v0.8.19.tar.gz
$ tar -zxf node-v0.8.19.tar.gz
$ cd node-v0.8.19
$ ./configure
$ make
$ sudo make install
</pre>
</p>
<p>
Install the <a href="https://github.com/EnotionZ/GpiO">GPIO</a> package in your project directory:</p>
<pre class="brush: bash; title: ;">
$ npm install gpio
</pre>
</p>
<p>
Write a simple node program that takes photos from the cameras when GPIO reads the value 1 from pin 4. After the photos are taken you can upload them wherever you want. We push ours to S3 using <a href="https://github.com/LearnBoost/knox">knox</a>.</p>
<pre class="brush: jscript; title: ;">
var gpio = require(&quot;gpio&quot;);

function takeShot(device) {
	var filename = device + '.jpg';

	// Spawn the webcam child process.
 	var spawn = require('child_process').spawn,
		fswebcam = spawn('fswebcam', [
			'--device', '/dev/' + device, 
			'--no-banner', 
			'--resolution', '800x480', 
			'--rotate', '90',
			'--jpeg', '95', 
			'--save', shots_path + filename
		]);

	// Log fswebcam output.
	fswebcam.stdout.on('data', function (data) {
		console.log('stdout: ' + data);
	});

	// Log any errors.
	fswebcam.stderr.on('data', function (data) {
		console.log('stderr: ' + data);
	});

	// continue processing after it has taken photos
	fswebcam.on('exit', function (code) {
		// Do stuff, like saving/hosting your images.
		// We used knox (https://github.com/LearnBoost/knox)
		// to push the photos to S3.
	});
}

var gpio4 = gpio.export(4, {
   direction: &quot;in&quot;,
   ready: function() {

		gpio4.on(&quot;change&quot;, function(val) {
			if(val == 1) {
				takeShot('video0');
				takeShot('video1');
			}
		});

	}
});
</pre>
</p>
<p>
That&#8217;s it! Our office fridge is now open for public scrutiny: <a href="http://fridge.teehanlax.com/">fridge.teehanlax.com</a>.
</p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/inside.jpg" alt="" title="Inside" width="680" height="428" class="alignnone size-full wp-image-9133" /></p>
<p>This is a simple project, but it opens some great questions for discussion &#8211; namely, how should we be designing our appliances? What value can we add to them? When is adding features actually a detriment? <a href="http://branch.com/b/what-should-connected-appliances-do">Let&#8217;s talk.</a></p>
<p><script type="text/javascript" src="http://embed-script.branch.com/assets/embed/embed.m.js?body=0" data-branch-embedid="U78ryWGtqZQ" ></script><br />
<noscript><a href="http://branch.com/b/what-should-connected-appliances-do">What should connected appliances do?</a></noscript></p>

]]></content:encoded>
			<wfw:commentRss>http://www.teehanlax.com/labs/connected-appliances/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Painting with a digital brush</title>
		<link>http://www.teehanlax.com/labs/painting-with-a-digital-brush/</link>
		<comments>http://www.teehanlax.com/labs/painting-with-a-digital-brush/#comments</comments>
		<pubDate>Mon, 30 Jul 2012 18:50:54 +0000</pubDate>
		<dc:creator>Peter Nitsch</dc:creator>
		
		<guid isPermaLink="false">http://www.teehanlax.com/?post_type=labs&amp;p=8601</guid>
		<description><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/lead2.jpg' /><br /><br />Lines of light ranged in the nonspace of the mind, clusters and constellations of data. Like city lights, receding. - William Gibson, Neuromancer It&#8217;s no...
]]></description>
			<content:encoded><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/lead2.jpg' /><br /><br /><h2>Lines of light ranged in the nonspace of the mind, clusters and constellations of data.  Like city lights, receding.<br />
- William Gibson, Neuromancer</h2>
</p>
<p>It&#8217;s no secret that &#8211; in some eternal quest to palliate my nostalgia &#8211; I&#8217;ve developed a mild obsession with text-mode art. Years ago, I learned all the relavent algorithms, techniques, and code pages in order to best simulate text-mode in modern browsers &#8211; an effort that resulted in (long since abandoned) projects like <a href="http://www.asciimeo.com/">ASCIImeo</a> and <a href="http://flashterm.com/">Flashterm</a>. Recent explorations in bridging the digital-physical divide (plus a sense of withdrawal) have caused me to revisit image-to-text conversion with a quick experiment.</p>
<p>For many of us that have grown up with computers, text-mode art represents something deeper than nostalgia. It is an artform manifested from technological constraints, inspired by the same hacker ethos that build the early machines used to produce and view it. Fundamentally, it is both an expression and prisoner of the system it inhabits. This latest experiment attempts to free ASCII art from the confines of the screen and enable it to exist in physical space &#8211; with light and paint.</p>
<p><iframe src="http://player.vimeo.com/video/46636045?title=0&amp;byline=0&amp;portrait=0" width="680" height="383" frameborder="0"></iframe></p>
<p><span id="more-8601"></span>I wanted to approach image-to-text conversion a bit differently this time around, focusing primarily on speed. In order to achieve this, all the real-time conversion work was moved to the GPU. The resulting program (<a href="https://github.com/TeehanLax/ofxAsciiArt">available as an openFrameworks add-on</a>) can scale to huge dimensions with little strain. </p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/Screen-shot-2012-07-25-at-9.31.18-AM1.png" alt="" title="Screen-shot-2012-07-25-at-9.31.18-AM" width="680" height="400" class="alignnone size-full wp-image-8653" /></p>
<p>A nice side-effect of writing the new library in OpenGL was easy portability to WebGL, enabling a unique twist on exploring the physical world:</p>
<p><a href="http://tllabs.io/asciistreetview/">Ascii Streetview<br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/Screen-shot-2012-07-24-at-5.01.04-PM2.png" alt="" title="Screen-shot-2012-07-24-at-5.01.04-PM" width="681" height="296" class="alignnone size-full wp-image-8649" /></a></p>

]]></content:encoded>
			<wfw:commentRss>http://www.teehanlax.com/labs/painting-with-a-digital-brush/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Do We Have Milk?</title>
		<link>http://www.teehanlax.com/labs/do-we-have-milk/</link>
		<comments>http://www.teehanlax.com/labs/do-we-have-milk/#comments</comments>
		<pubDate>Thu, 10 May 2012 14:23:27 +0000</pubDate>
		<dc:creator>Christina Truong</dc:creator>
		
		<guid isPermaLink="false">http://www.teehanlax.com/?post_type=labs&amp;p=8408</guid>
		<description><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/header-milk.jpg' /><br /><br />Advances in physical computing are changing the way we interact with our environment. These changes can influence how we go about doing our day-to-day activities,...
]]></description>
			<content:encoded><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/header-milk.jpg' /><br /><br /><h2>Advances in physical computing are changing the way we interact with our environment. These changes can influence how we go about doing our day-to-day activities, such as food organization. To explore the connection between the physical world and the digital world, we focused on a single universal question to find a way to merge these two worlds more intuitively into everyday life.</h2>
</p>
<p><iframe src="http://player.vimeo.com/video/41917421?title=0&amp;byline=0&amp;portrait=0" width="680" height="383" frameborder="0"></iframe></p>
<p>We&#8217;ve all been there. You pour a bowl of cereal, or a cup of coffee. Go to the fridge. No milk. Maybe you&#8217;re already at the grocery store in the dairy aisle and wonder, &#8220;How much milk do I have left at home?&#8221; What if you could take a peek into your fridge anytime, anywhere?</p>
<p>To monitor the amount of the remaining milk, we attached a weight sensor to the bottom of a milk jug to send the weight values to your phone. When the milk reaches dangerously low levels, you get an alert on your phone reminding you to get milk while using your current location to map nearby grocery stores.<br />
<span id="more-8408"></span><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/notification-map.jpg" alt="" title="milk notification and map" width="680" height="460" class="alignnone size-full wp-image-8432" /></p>
<p>But sometimes you need milk for more than just a bowl of cereal. You can also use the app to check the remaining levels of milk before you receive the alert.</p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/milk-levels.jpg" alt="" title="milk levels" width="680" height="375" class="aligncenter size-full wp-image-8424" /></p>
<p>Done. Got milk.</p>
<p>Why did we use a milk jug?  For our non-Canadian friends that may be unfamiliar with the phenomenon known as milk bags, a 4-litre package comes with three milk bags that are usually stored in either a jug or a pitcher.</p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/arduino-milk-jug11.jpg" alt="" title="arduino-milk-jug1" width="680" height="453" class="alignnone size-full wp-image-8492" /></p>
<p>With this in mind, we also prototyped a companion weight sensor to monitor a drawer in the fridge used to hold the additional milk bags to get the combined weight of the remaining milk.  </p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/milk-jugs.jpg" alt="" title="milk jugs" width="680" height="383" class="alignnone size-full wp-image-8429" /></p>
<p>It&#8217;s easy to imagine all of the different ways to implement this idea. The natural inclination would be to track multiple items, or incorporate other elements like a recipe database. There are already &#8220;smart fridges&#8221; on the market that have various food management features. The downside is the features are built into the fridge itself, which makes it expensive and sometimes complicated to set up.  In addition, while the smart fridges do have some features that interact with the mobile phone, there isn&#8217;t much communication with the person and their environment.</p>
<p>By using phone notifications and maps in the Milk? app, it goes from being just an organizational tool to interacting with the person by &#8220;reminding&#8221; you to get more milk and using your physical location to show you where to get it.</p>
<p>Although this experiment revolved around milk, the idea has broader implications that extend beyond the milk itself.  How can this idea impact the way we organize our lives and the way we interact with objects using the digital capabilities available to us? The possibilities are as endless as our imagination.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.teehanlax.com/labs/do-we-have-milk/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Generating Typographic Portraits</title>
		<link>http://www.teehanlax.com/labs/generating-typographic-portraits/</link>
		<comments>http://www.teehanlax.com/labs/generating-typographic-portraits/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 15:39:18 +0000</pubDate>
		<dc:creator>Peter Nitsch</dc:creator>
		
		<guid isPermaLink="false">http://www.teehanlax.com/?post_type=labs&amp;p=7809</guid>
		<description><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/lead1-740x350.gif' /><br /><br />Recently, I gave a talk about the development of a typographic portrait generation engine we built for Bell Social Portrait. It&#8217;s a story that explores...
]]></description>
			<content:encoded><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/lead1-740x350.gif' /><br /><br /><p>Recently, I gave a <a href="http://www.fitc.ca/events/presentations/presentation.cfm?event=127&#038;presentation_id=1747">talk</a> about the development of a typographic portrait generation engine we built for <a href="http://portrait.bell.ca/">Bell Social Portrait</a>. It&#8217;s a story that explores some of the challenges of building a complex web application meant to be experienced on many different screen sizes and platforms. The project taught us valuable lessons that will surely influence future work.</p>
<p><a href="http://portrait.bell.ca/">Bell Social Portrait</a> is a site that pulls a users social feeds and programatically generates artwork from an associated profile or user-submitted image. <a href="http://www.google.ca/search?q=typographic+portrait&#038;hl=en&#038;prmd=imvns&#038;source=lnms&#038;tbm=isch&#038;ei=mTbdTvnTDoji0QHlxLmNDQ&#038;sa=X&#038;oi=mode_link&#038;ct=mode&#038;cd=2&#038;ved=0CBgQ_AUoAQ&#038;biw=991&#038;bih=609">Traditional typographic portraits</a> are normally constructed in graphic design software like Illustrator or Photoshop. We knew it&#8217;d be a challenge to simulate the process programatically &#8211; never mind deploying it to as many browsers and devices as possible (a self-imposed requirement).</p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/devices1.jpg" alt="" title="devices" width="680" height="375" class="alignnone size-full wp-image-7820" /></p>
<p><span id="more-7809"></span>Early research and prototyping was all done using the Canvas tag as a drawing surface &#8211; probably the most ubiquitous and well supported API&#8217;s in HTML5. Our intent was to generate as much reusable code as we could for the finished implementation. This meant that all image segmentation routines were written in Javascript &#8211; a task made easy by some <a href="http://peternitsch.net/bitmapdata.js/">groundwork I&#8217;d laid a few months earlier</a>.  </p>
<p><a href="http://en.wikipedia.org/wiki/ASCII_art">ASCII art</a> (specifically image to text conversion) was a major source of inspiration for this project, and its basic implementation served as a good starting point. Typical ASCII art uses a quadrant (one region evenly split into four) based color weighted lookup to match character glyphs. The process is actually quite simple. Take, for example, the letter &#8220;L&#8221; &#8211; it could be mapped to a region with bright color (lots of white) in the top-left/bottom-right/bottom-left quadrants. If you&#8217;re interested in the full process (and more than just the most basic implementation), I highly recommend reading <a href="http://sol.gfxile.net/textfx/index.html">The Art and Science of Text Mode Conversion</a> by Jari Komppa. </p>
<p>We used this same quadrant splitting practice in order to segment images into a cell grid of varying sizes. This type of structure is commonly known as a <a href="http://en.wikipedia.org/wiki/Quadtree">quadtree</a>, and involves recursively splitting an image with one simple condition: <strong>stop splitting if the region contains only one color</strong>. You can see the results illustrated below at different iteration (number of times to recursively split) values.</p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/quadtree.png" alt="" title="Quadtree" width="680" height="680" class="alignnone size-full wp-image-7811" /></p>
<p>Next, we merged all adjacent cells of the same dimensions. This produced a useful grid for mapping words, but we weren&#8217;t pleased with them aesthetically. Cells appeared too organized and symmetrically positioned. We wanted an element of chaos, and this meant a new approach was required. </p>
<p>We began investigating various <a href="http://en.wikipedia.org/wiki/Packing_problem">box fitting</a> strategies, and quickly began building our own algorithm. The approach was simple:</p>
<ol>
<li>Pick a random point from an array of <strong>active</strong> pixels (not white).
<li>Move that point horizontally left or right until a null pixel (edge of the image, white pixel, or another cell) is hit.
<li>Move vertically up or down until the same condition is true.
<li>Expand a rectangle, with a width/height ratio chosen randomly from a predetermined set, until any of its pixels hits a null pixel. Mark that rectangle as a cell.
</ol>
<p>&nbsp;<br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/box.png" alt="" title="box" width="680" height="255" class="alignnone size-full wp-image-7823" /><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/octo.gif" alt="" title="octo" width="680" height="386" class="alignnone size-full wp-image-7884" /></p>
<p>Aesthetically, the resulting grids had the right amount of randomness and produced visually appealing portraits. They looked great, but a couple problems arose &#8211; average computation time of 30 seconds in Chrome, and huge performance variability across difference platforms. iOS (pre 5.1) performed particularly poorly, with the worst cases fully locking up devices. We needed to find a workaround, and that meant moving image segmentation to the cloud.</p>
<p>For a number of unrelated reasons which included tight application and web serving integration, an easy interface to <a href="http://www.mongodb.org/">mongodb</a>, and the need for an event based architecture, we had already decided to implement the server portion of Social Portrait in <a href="http://nodejs.org/">Node.js</a>. And since Node is basically &#8220;Javascript for networking&#8221;, the task of porting the image segmentation routines written for the browser was relatively easy. Thanks to Learnboost&#8217;s <a href="https://github.com/learnboost/node-canvas">node-canvas</a> package, we were able to simply copy and paste most of our code.</p>
<p>Recreating the portrait generation process on the server meant we could free the browser from any application level computation and have it narrowly focus on UI. This was a huge deal. The browser experience became light and responsive to different devices and platforms. Also, since we prototyped portrait generation in the browser, we could comfortably pass off a small JSON UI properties object along with the unaltered original image to the server. Bandwidth usage became very light &#8211; an important factor when accounting for mobile devices. Finally, we knew exactly what hardware the code was running on, which established a uniform performance metric. The performance variability problem had been solved.</p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/props.png" alt="" title="props" width="680" height="246" class="alignnone size-full wp-image-7818" /></p>
<p>Our decision to move image segmentation to the server also meant we had some new powerful tools at our disposal. One of these was <a href="http://www.imagemagick.org/script/index.php">imagemagick</a> &#8211; a very mature, fast, and well supported graphics software suite that we could access through a child process. It allowed us to preprocess our input images with very little overhead. One technique we leveraged with imagemagick was down-up-sizing images before grid generation inorder to produce a blocky canvas. This resulted in an easier image to fit rectangles on, which reduced noise and improved segmentation speed.</p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/sizing.png" alt="" title="sizing" width="680" height="415" class="alignnone size-full wp-image-7819" /></p>
<p>The real fix to our speed problem came from having the ability to write our own native programs in C++ &#8211; specifically the ability to use data structures that do not exist in Javascript. When iterating over an array of active pixels (not white), we had no way of skipping over elements that were already assigned to cells. We tried many tricks in Javascript including overly complicated dynamic lookup tables, and splicing arrays. Nothing worked well. Then we found <a href="http://www.boost.org/doc/libs/1_48_0/libs/dynamic_bitset/dynamic_bitset.html">dynamic_bitset from Boost C++</a> &#8211; a data structure that only contains bits (on/off) and more importantly <strong>does not iterate over &#8220;off&#8221; elements</strong>. This means that as cells get progressively marked unavailable, iterating over the active pixels array gets faster. We rewrote our grid generation code as a C++ program and wrapped it in a Node child process. The result was a <strong>10x</strong> speed increase &#8211; an average of 3 seconds! </p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/pix.png" alt="" title="pix" width="640" height="166" class="alignnone size-full wp-image-7817" /></p>
<p>It may seem like this story is a glowing endorsement of Node.js, but that&#8217;s not necessarily the case. Node was a very valuable tool in this project for a number of reasons &#8211; the ability to prototype directly on our drawing canvas and seamlessly port code over to the server, the access to a native environment that solved huge performance problems, and the access to powerful tools like imagemagick for preprocessing. But had we done the project over again, I&#8217;m not sure we would have implemented our entire server environment in Node. Static web serving is better handled in tried-and-tested environments like Apache or nginx, and worker management for multiple CPU cores can be daunting. </p>
<p>Nonetheless, the most important lesson we learned is that cloud technology and the new breed of server-side environments are necessary tools to utilize in modern-day web applications. With the variability of devices and platforms users move between, we can no longer solely rely on client-side environments to deliver rich experiences. Frame your UI&#8217;s in the browser &#8211; let the cloud do the work.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.teehanlax.com/labs/generating-typographic-portraits/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Arduino Hack-day at T+L</title>
		<link>http://www.teehanlax.com/labs/arduino-hack-day-at-tl/</link>
		<comments>http://www.teehanlax.com/labs/arduino-hack-day-at-tl/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 19:11:22 +0000</pubDate>
		<dc:creator>Derek Kinsman</dc:creator>
		
		<guid isPermaLink="false">http://www.teehanlax.com/?post_type=labs&amp;p=7512</guid>
		<description><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/feature-740x350.jpg' /><br /><br />Yesterday we (Labs) ran a half-day hardware hacking workshop internally for all of the Teehan+Lax employees (everyone from designers and developers to the project managers...
]]></description>
			<content:encoded><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/feature-740x350.jpg' /><br /><br /><p>Yesterday we (Labs) ran a half-day hardware hacking workshop internally for all of the Teehan+Lax employees (everyone from designers and developers to the project managers and the &#8220;HR&#8221; people). It was meant as a light introduction to physical prototyping. Here are some of the creative, fantastic (and horrifying) results. We were very excited to see everyone&#8217;s results at the end of the day. The great thing was that everyone had successfully created something by the end of the workshop from scratch.</p>
<p><iframe src="http://player.vimeo.com/video/30148022?title=0&amp;byline=0&amp;portrait=0" width="680" height="383" frameborder="0"></iframe></p>
<p><span id="more-7512"></span><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/DSC0223.jpg" alt="" title="_DSC0223" width="680" height="452" class="alignnone size-full wp-image-7517" /><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/DSC0229.jpg" alt="" title="_DSC0229" width="680" height="452" class="alignnone size-full wp-image-7518" /><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/IMG_1705.png" alt="" title="IMG_1705" width="680" height="701" class="alignnone size-full wp-image-7521" /><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/DSC0216.jpg" alt="" title="_DSC0216" width="680" height="452" class="alignnone size-full wp-image-7516" /><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/DSC0151-3.jpg" alt="" title="_DSC0151-3" width="680" height="452" class="alignnone size-full wp-image-7514" /><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/DSC0250.jpg" alt="" title="_DSC0250" width="680" height="452" class="alignnone size-full wp-image-7520" /><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/DSC0243.jpg" alt="" title="_DSC0243" width="680" height="452" class="alignnone size-full wp-image-7519" /><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/DSC0194.jpg" alt="" title="_DSC0194" width="680" height="452" class="alignnone size-full wp-image-7531" /></p>

]]></content:encoded>
			<wfw:commentRss>http://www.teehanlax.com/labs/arduino-hack-day-at-tl/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Touch Vision Interface</title>
		<link>http://www.teehanlax.com/labs/tvi/</link>
		<comments>http://www.teehanlax.com/labs/tvi/#comments</comments>
		<pubDate>Fri, 09 Sep 2011 17:06:34 +0000</pubDate>
		<dc:creator>Peter Nitsch</dc:creator>
		
		<guid isPermaLink="false">http://www.teehanlax.com/?post_type=labs&amp;p=7324</guid>
		<description><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/TVI.png' /><br /><br />“The perception of system output must be greater than the perceived user input, and within that range there is a sweet spot where [user experience]...
]]></description>
			<content:encoded><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/TVI.png' /><br /><br /><h2>“The perception of system output must be greater than the perceived user input, and within that range there is a sweet spot where [user experience] is delightful and magical.”<br />
- <a href="http://www.webdirections.org/resources/august-de-los-reyes-predicting-the-past/">August de los Reyes</a><br />
</h2>
</p>
<p><iframe src="http://player.vimeo.com/video/28792538?title=0&amp;byline=0&amp;portrait=0" width="680" height="383" frameborder="0"></iframe></p>
<p>I can still recall the first time I saw an Augmented Reality demo. There was a sense of wonderment from the illusion of 3D models living within the video feed. Of course, the real magic was the fact that the application was not only viewing its surrounding environment, but also <strong>understanding</strong> it. AR has proven to be an incredible tool for enhancing perception of the real world. Despite this, I’ve always felt that the technology was somewhat limited in its application. It is typically implemented as output in the form of visual overlays or filters. But could it also be used for user input? We decided to explore that question by pairing the principles of AR (like real-time marker detection and tracking) with a natural user interface (specifically, touch on a mobile phone) to create an entirely new interactive experience. </p>
<p>The outcome of this examination is something we’re calling <strong>Touch Vision Interface</strong> &#8211; a tool that enables touch interaction on many different connected surfaces through a mobile phones’ camera view. The translation of touch input coordinates to the captured video feed creates the illusion of being able to directly manipulate a distant surface. As a result, the interaction feels natural and almost invisible.<br />
<span id="more-7324"></span><br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/exmple.png" alt="" title="Touch input translation" width="680" height="337" class="alignnone size-full wp-image-7382" /></p>
<p>Future applications of this technology are more than compelling. The barrier of cross device communication is lessened, whether in the living room or in large open spaces. Brands could crowd-source easier with billboard polls. Group participation on large installations could feel more natural. The possibilities become even more exciting when considering the most compelling aspect of the tool &#8211; the ability to interact with multiple surfaces without interruption. No need to switch devices through a secondary UI &#8211; simply touch your target. You could imagine a wall of digital billboards that users seamlessly paint across with a single gesture.</p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/idea_1.png" alt="" title="Digital billboard wall" width="680" height="337" class="alignnone size-full wp-image-7383" /></p>
<p>Other applications could enhance the collaborative creative process. Imagine a music creation experience where each screen becomes an instrument. Pitch and tone could be changed by moving your finger across the instruments surface allowing for natural gesture controls. Rather than being paired with an instrument, a band member simply plays what they’re “looking” at.</p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/ideas_21.png" alt="" title="Music creation" width="680" height="337" class="alignnone size-full wp-image-7388" /></p>
<p>There are flaws with this technology, surface discovery and pairing being the most obvious. But along with the problems, it’s easy to see how this idea could be extended &#8211; moving past simple planar interaction and deeper into the world of real-world object manipulation. We’re excited to see how far we can take it. </p>

]]></content:encoded>
			<wfw:commentRss>http://www.teehanlax.com/labs/tvi/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>On Passive Interaction.</title>
		<link>http://www.teehanlax.com/labs/on-passive-interaction/</link>
		<comments>http://www.teehanlax.com/labs/on-passive-interaction/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 15:15:10 +0000</pubDate>
		<dc:creator>Derek Kinsman</dc:creator>
		
		<guid isPermaLink="false">http://www.teehanlax.com/?post_type=labs&amp;p=7229</guid>
		<description><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/arduino-rfid.png' /><br /><br />&#8220;It&#8217;s clear that simplifying and physically tailoring input to output with tech like NFC is a good way to enhance user experience and can lead...
]]></description>
			<content:encoded><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/arduino-rfid.png' /><br /><br /><h2>&#8220;It&#8217;s clear that simplifying and physically tailoring input to output with tech like NFC is a good way to enhance user experience and can lead to some unique interactions. We plan on taking this idea further by experimenting with other platforms and input devices.&#8221;<br />
—<a href="http://www.teehanlax.com/labs/physical-and-frictionless-input/">Physical and Frictionless Input</a>. 7 June 2011.<br />
</h2>
</p>
<h4>It should be about the experience. Not the technology.</h4>
<p>Continuing on with physical interaction we&#8217;ve been experimenting with Arduinos, RFID/NFC, social network APIs, and dreaming up various other end uses that we will discuss in a minute and end off with a really quick (but verbose) demo. When dealing with technology for novel interaction we really want to make sure that the interaction is put before the technology. <a href="http://www.youtube.com/watch?v=NwVBzx0LMNQ">A tech demo for tech sake isn&#8217;t always the best approach</a>. Inventing solutions to problems that don&#8217;t exist doesn&#8217;t make much sense. Products (specifically tools — and digital or physical) are meant to service something and then get out of the way. If we take this approach to using RFID/NFC then whatever that tool ends up being should show up, do the job, then completely disappear so you can get on with living life. Without you needing to do anything. You don&#8217;t give the plumber step by step instructions do you? You just call and tell them to come fix something.<br />
<span id="more-7229"></span><br />
Imagine being at a Jay&#8217;s game and being able to swipe your ticket on your arm rest to +1 or like a big swing by José Bautista (or rather to +1 his <a href="http://mlb.com/video/play.jsp?content_id=18490021">childish temper tantrum over the weekend</a>). Or maybe this winter we&#8217;ll finally be able to tweet that we witnessed the first <a href="http://grooveshark.com/s/Fifty+Mission+Cap/CQM5S?src=5">Leafs Stanley Cup win since 1966/67</a> just by having your ticket in your pocket and your chair knowing it&#8217;s you. Because, obviously, there&#8217;s no way any of us are gonna stop cheering to get our phones out of our pockets to tweet about it.</p>
<p>Let&#8217;s face it though, that won&#8217;t happen anytime soon so maybe  you could <a href="http://www.flickr.com/photos/tllabs/5727199076/in/set-72157626735181380">check in on Foursquare at a conference</a> by swiping your conference pass at the entry gate. That could be extended into checking in anywhere. Check in at your work, the various rooms in your house, or check in at your toaster or fridge or at your computer for an all night Minecraft marathon.</p>
<p>We can even microchip ourselves — the same as microchipping your pet — and use that to send tweets for various appliances and pieces of furniture we end up using. Or more practically that microchip could be used to engage a locking mechanism on the front door or store personal identity/health info. It would be pretty rad if you could keep your health records stored in the fleshy bit between your thumb and index finger. The use cases for RFID/NFC are quite varied from really practical to kinda shady, whimsical, and fun.</p>
<p>The idea of this kind of passive interaction; and passive data logging, tracking, and publishing is both frightening and exciting. It could go down the scary big brother road where every action we take is recorded and posted somewhere publicly and used for ad streams and evil. Remember when your significant other could see the lovely purchases you made in secret for them on <a href="http://bits.blogs.nytimes.com/2007/11/29/the-evolution-of-facebooks-beacon/">Amazon showing up on their Facebook wall</a>, or when robbers used <a href="http://pleaserobme.com/">Foursquare to track good targets because they checked</a> in somewhere that wasn&#8217;t their own home? Yeah that wasn&#8217;t cool. </p>
<p>I don&#8217;t see that happening…much. I see the nice green pastures of passive interaction for the betterment of humanity. <a href="http://nearfield.org/">There have already been many projects from around the world that prove this true many times over</a>. More and more of these projects are moving away from tracking offline activities on social networking sites and are moving towards (actually a bit backwards — think remote controls and animal microtagging) friendly tangible interfaces and controllers for a variety of different products.</p>
<p>Before we get into the demo proper, a quick technical breakdown. An RFID is hooked up to an <a href="http://arduino.cc/">Arduino</a> (or any microcontroller, we picked Arduino). That Arduino is in turn hooked up to a wifi or ethernet shield (a custom breadboard that adds additional functionality to the Arduino, in this case, the whole Internet) which sends information (a string containing an RFID Tag serial number, or in the case it&#8217;s rewritable, whatever we can squeeze into 1K of data) to a server (actually it sends a Serial communication across TCP/IP). The server is running a Python script that is listening for data coming from the Arduino and uses that serial number which is synced to a person&#8217;s OAuth access tokens to validate them and post some action to their account on a social network.</p>
<p>This setup can very quickly bring the offline world into the online world.</p>
<h4>The part where we get to make something.</h4>
<p>So, we&#8217;ve put together this simple system together that can send messages to a twitter account whenever you swipe a certain RFID tag over the Arduino. For the sake of keeping the demo as cost efficient as possible and simple, we won&#8217;t be doing any TCP stuff. Save that for next time. Plus, adding internet to your Arduino starts at about $50. We&#8217;ll just send serial from the Arduino to the laptop via the USB cable. Just pretend it&#8217;s an ethernet cable.</p>
<p>The prequel to the steps is to acquire a bunch of Arduino parts. You can get all this stuff from <a href="http://www.sparkfun.com/">Sparkfun</a> or <a href="http://www.makershed.com/">Makershed</a> and it&#8217;ll take maybe a week to ship.</p>
<p>1 x Arduino<br />
1 x RFID Reader (breakout board or usb reader, we used the usb version)<br />
1 x ID-12 or ID-20 RFID Reader<br />
1 x RFID 125kHz Tag</p>
<p>Other things you&#8217;ll need are a bundle of Breadboard Jumper Wires and a Breadboard. You&#8217;ll probably also need some 6-pin and 8-pin headers (for the breakout board). If you need the headers you&#8217;ll need a soldering iron and solder. If you&#8217;ve never soldered before<a id="a1" href="#b1">¹</a> you may also want a Solder Sucker and a Solder Wick for clean ups and fix ups. If you drink a lot of coffee I would also recommend a Helping Hand Vice.</p>
<p>Now that that is out of the way let&#8217;s build something. The first step is to assemble the Arduino. We&#8217;re using an Arduino Uno, Sparkfun&#8217;s RFID USB Reader board, and an ID-20<a id="a2" href="#b2">²</a> RFID Reader. If you&#8217;re using an RFID breakboard the PIN mapping is a bit different but will be explained as well.</p>
<p>For the USB Board we soldered a 6-pin header and stuck it on a solderless breadboard. From the Arduino attach digital pin 6 (marked ~6 on the Uno) to TX-0 on the USB Reader, 5V to VCC, and GND to GND and GNDT.<br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/fritzing-0001.png" alt="Wiring diagram for use with RFID USB Reader" title="Fritzing Schematic Arduino/RFID USB Reader" width="680" height="440" class="alignnone size-full wp-image-7241" /><br />
<em>—Made with <a href="http://fritzing.org/">Fritzing</a>. Showing wiring for RFID USB Reader.</em></p>
<p>With a breakout board you attach ~6 to D0 (pin 9), 5V to RES (pin 2) and 5V (pin 11), and GND to GNDT (pin 1) and +/- (pin 7).<br />
<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/fritzing-0002.png" alt="Wiring diagram for use with RFID Breakout Board" title="Fritzing Schematic Arduino/RFID Breakout Board" width="680" height="380" class="alignnone size-full wp-image-7242" /><br />
<em>—Made with Fritzing. Showing wiring for RFID Breakout Board.</em></p>
<p>The wiring is really easy if you plug the 5V and the GND from the Arduino into the + and &#8211; rails down the edge of your breadboard. You can then plug the various powers and grounds into the RFID reader from there. That completes setting up the hardware. It&#8217;s not too complex a set up.</p>
<p>There are two different pieces of code. One is Arduino<a id="a3" href="#b3">³</a> and the other is some very simple Python<a id="a4" href="#b4">⁴</a>. We&#8217;ll set up the Arduino software first so that we can send a message out over serial.</p>
<p>For Arduino we also need the third party library called <a href="http://arduiniana.org/libraries/newsoftserial/">NewSoftSerial</a>.</p>
<p>First we&#8217;re going to define a bunch of things that we&#8217;ll need later on and import the NewSoftSerial library.</p>
<pre class="brush: cpp; title: ;">
#include &lt;NewSoftSerial.h&gt;

NewSoftSerial rfidSerial(6, 7); // (RX - pin 7 on usb rfid board, TX - pin 6 on usb rfid board)
String rfidTag, rfidTagClean;

int i = -1;

// Henry V Tweets
char* tweetStrings[] = {
  &quot;O, pardon! since a crooked figure may Attest in little place a million;&quot;,
  &quot;And let us, ciphers to this great accompt, on your imaginary forces work.&quot;,
  &quot;Turning the accomplishment of many years Into an hour-glass:&quot;,
  &quot;for the which supply, Admit me Chorus to this history;&quot;,
  &quot;Who prologue-like your humble patience pray, Gently to hear, kindly to judge, our play.&quot;
};
</pre>
<p>The next thing we need to do is set up the communication over serial. void setup() is a special function that runs once when the application starts. </p>
<pre class="brush: cpp; title: ;">
void setup() {
  Serial.begin(9600);
  Serial.flush();
  rfidSerial.begin(9600);
}</pre>
<p>So all we want to do is open some ports and make sure there that anything that is currently there is flushed out of the system.</p>
<p>Next we need to build the rest of the application. Another special function in Arduino is void loop(), this function constantly runs, looping back to the start of the code when it reaches the end.</p>
<pre class="brush: cpp; title: ;">
void loop() {
  if (rfidSerial.available()) {
    
    char incoming = (char)rfidSerial.read(); 
    // Packet structure, see ID-12 datasheet.
    // STX A B C D E F G H I J Y Z CR LF ETX
    //   2 - - - - - - - - - - - - 13 10 3
    
    // If the last character of the packet is 3, move on.
    if(incoming == 3) {
      
      // Skip the first character and take the next 12
      rfidTagClean = rfidTag.substring(1, 13);
      rfidTag = &quot;&quot;;         
      
      // Shakespeare's Henry V Prologue/Act 1. You'll need to change the tag number to one of your own tags. See the final else statement on how that happens.
      if(rfidTagClean == &quot;4500B89EC1A2&quot;) {
        i++;
        Serial.println(vStrings[i]);
        delay(500);
        // Reset counter so we can start reusing the already used tweets. 0 - 4.
        if (i == 4) {
          i = -1;
        }  
      }
      
    } else {
      
      rfidTag = String (rfidTag + incoming);
      Serial.print(incoming); // Prints the the 12 digit number we want to use for the rfidTagClean if condition.
      
    }
 
  }
}
</pre>
<p>Inside the loop the first thing we want to do is make sure that the code only runs if we can detect that the RFID reader is available. From there we say if the scanned RFID Tag matches this 12 digit number print one of the tweets, and every time this tag is read move to the next tweet. On the 5th tweet go back to the start of the list. If the RFID tag does not match print the tag number to the serial monitor so that we can track it. Either add it to a list of approved tags or not.</p>
<p>That&#8217;s it for the Arduino. You can upload that sketch to the board and run it. Open the serial monitor, swipe your RFID tag and see what happens. Don&#8217;t worry, we&#8217;re not tweeting yet, so have at it.</p>
<p>The final step is to write a super small <a href="http://www.python.org/">Python</a> script that monitors the serial port that Arduino is communicating on and if it gets a message send it to Twitter. Unfortunately, before we do that we have to register an application with Twitter so we can get OAuth out of the way. That is probably the pain point of the set up. OAuth is also why I&#8217;m not showing you how to like on Facebook, or check in on Foursquare. Dealing with OAuth and social network APIs is full of no documentation or worse… bad documentation. Okay, go log in to your Twitter account, hit up the developer section and register your applicaiton. Make sure to give your app Read &#038; Write privledges and finally authenticate your account with your app. This way not only will you have the Consumer Token and Consumer Secret, you&#8217;ll also have the Access Token and Access Secret which is a unique pair for every account registered.</p>
<p>Okay, one more caveat. There are 3 additional python libraries. <a href="http://tweepy.github.com/">Tweepy</a>, <a href="http://pyserial.sourceforge.net/">pySerial</a>, and Time. I&#8217;m also using the Python 2.7 build not Python 3.x.</p>
<pre class="brush: python; title: ;">
import tweepy
import serial
import time

# make sure this is your arduino. Open Arduino &gt; Tools &gt; Board
arduino = serial.Serial('/dev/tty.usbmodemfd121', 9600) 
status = arduino.readline()

auth = tweepy.OAuthHandler(&quot;XXXXXXXXXXXXXXXXXXXXXX&quot;, &quot;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&quot;)
auth.set_access_token(&quot;XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&quot;, &quot;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&quot;)

api = tweepy.API(auth)

while 1:  						# Infinite Loop
	status = arduino.readline() 	# Wait for new line to come across Serial
	api.update_status(status) 		# Post message to Twitter with Tweepy
	time.sleep(20) 				# Wait 20 seconds
	del status					# Clear status so we can start over with a clean slate
</pre>
<p>Okay, what&#8217;s going on here. We import the libraries we need to handle everything we&#8217;re about to do. Next we set up the serial so Python is listening to the Arduino so that it can send each line as a new tweet. The println function in the Arduino code sends each string with a new line (\n) at the end. After that we set up the Twitter authentication and tell Twitter&#8217;s API to use those specific credentials which will post to that account. The while function continously monitors serial data and each new line that comes across it posts to Twitter.</p>
<p>Upload the Arduino sketch to the board, leave the Arduino plugged into your computer via USB and run the python sketch in Terminal:</p>
<p>cd /path/to/python/sketch/<br />
python twitter.py</p>
<p>[download id="14"]</p>
<p>And you&#8217;re set. Swipe the card and impress your followers with your new powers.</p>
<p>Taking it a few steps further we could move this back into the ethernet/wifi world. But something that might be more interesting is to attach the unique access tokens/secrets to an RFID card so that if Card 1 is swiped use my unique credentials and post to my account OR if Card 2 is swiped use your unique credentials to post to your account. This way you could have one piece of hardware posting for everyone that has a valid RFID card. Which becomes more compelling. More soon.</p>
<p>&#8211;</p>
<ol>
<li id="b1">A few notes on electronics. If you&#8217;re buying a soldering iron for the purposes of hobby electronics I don&#8217;t recommend the &#8216;cold heat&#8217; style soldering tools. They work by producing an electrical current that could possibly short out your circuits. Stick to the regular soldering iron that just heats up the tip. Just be careful to not burn yourself. And possibly get adult supervision. <a href="#a1">↑</a></li>
<li id="b2">The ID-2, ID-12, and ID-20 all have the same PIN mappings. However, the ID-2 does not have an internal antenna so you&#8217;ll have to build one. Which is painfully complex. The ID-12 and ID-20 both have pins exposed for adding an external antenna but this will cause all kinds of reception problems. <a href="#a2">↑</a></li>
<li id="b3">Arduino is both a hardware platform and a programming language. Actually the language is based on Processing which is built on Java. Arduino is built on C/C++ but maintains most of the syntax styling of Processing. So bits are written like Java and other bits are written like C/C++. Don&#8217;t worry it&#8217;s not as confusing as that makes it sound. <a href="#a3">↑</a></li>
<li id="b4">Python is like Ruby but better. <a href="#a4">↑</a></li>
</ol>

]]></content:encoded>
			<wfw:commentRss>http://www.teehanlax.com/labs/on-passive-interaction/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Responsive Design (pt.1)</title>
		<link>http://www.teehanlax.com/labs/responsive-design-pt-1/</link>
		<comments>http://www.teehanlax.com/labs/responsive-design-pt-1/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 18:36:32 +0000</pubDate>
		<dc:creator>Jason Sao Bento</dc:creator>
		
		<guid isPermaLink="false">http://www.teehanlax.com/?post_type=labs&amp;p=7049</guid>
		<description><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/header2.png' /><br /><br />In the last years, with the advent of new web enabled devices — smartphones, tablets, connected TVs and more — our digital landscape has been...
]]></description>
			<content:encoded><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/header2.png' /><br /><br /><h2>In the last years, with the advent of new web enabled devices — smartphones, tablets, connected TVs and more — our digital landscape has been rapidly expanding beyond the borders of traditional desktop/laptop screens. As mobile devices are increasingly becoming the primary way we access online content, responsive design has emerged as a popular design strategy.</h2>
<p><h4>Designing for all devices: apps and mobile websites</h4>
<p>Smartphones and tablets have complicated the task of digital strategy and design by adding new resolutions and technical constraints. With plenty of different mobile devices around, dealing with this complexity—in particular, reconsidering the traditional 960px fixed width viewport—has been approached in two ways: </p>
<ol>
<li>Create complimentary (native) mobile apps (a trend fostered by manufacturers with their ad hoc SDKs and app stores); </li>
<li>Create multiple mobile versions of websites and try to cover as many variations as possible.</li>
</ol>
<p>
&nbsp;<span id="more-7049"></span><br />
Both of these options aim to create experiences that are perfectly adapted to the context of the device they appear on. Although they might look ideal from a coverage and support perspective, the problems with both these options are that:
<ol>
<li>They require an additional financial, design and maintenance effort that may be overwhelming for clients. </li>
<li>They may well prove to be a Pandora’s box in the long run as an endless number of new devices will appear with their own specificities.</li>
</ol>
<p>&nbsp;</p>
<h4>Designing for any device: responsive web design</h4>
<p>In parallel, another strategy emerged last year in the shape of a seminal article written by Ethan Marcotte, entitled <a href="http://www.alistapart.com/articles/responsive-web-design/">Responsive Web Design</a>. To avoid these drawbacks and based on the assumption that a web experience should (and could) be the same no matter the device (“one web”), Marcotte defended the idea of a single fluid website rendering different layouts per device.<br />
His point was that a website designed following responsive principles would be more “future proof” as its layout would adapt to any device, content being smoothly rearranged and transformed to fit the device in question:</p>
<blockquote><p>“Rather than tailoring disconnected designs to each of an ever-increasing number of web devices, we can treat them as facets of the same experience. We can design for an optimal viewing experience, but embed standards-based technologies into our designs to make them not only more flexible, but more adaptive to the media that renders them. In short, we need to practice responsive web design.”</p></blockquote>
<p>To achieve this new ideal of “responsive design”, Marcotte defined three integrated features: </p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/mediea.png" alt="" title="flexible" width="680" height="337" class="aligncenter size-full wp-image-7068" /></p>
<p>Many websites (including this one) launched in the last few months embraced this new approach and jumped on the responsive bandwagon with more or less success. Responsive web design is certainly a step forward towards a better and more flexible web, but it should not be accepted as the only way to go.</p>
<h4>Our experiments with responsive web design</h4>
<p>Recently, we experimented with responsive design for the new T+L website and thought it could offer an appropriate solution to supporting multiple devices.</p>
<p>We decided to prolong the experimentation with an internal challenge: T+L designers and developers were asked to come up with a series of layouts that would respond to changes in screen size. Ultimately we analyzed the outcome of this challenge and spent time breaking down responsive frameworks to figure out what were the pros and cons of using the responsive approach.</p>
<p>We identified two methods to initiate the design process: </p>
<ul>
<li>Either as a “progressive enhancement”, with mobile layout first and desktop layout at last. </li>
<li>Or as a “graceful degradation”, with the full desktop website as a basis to design the other layouts.</li>
</ul>
<p>&nbsp;<img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/pro.png" alt="" title="pro" width="680" height="383" class="aligncenter size-full wp-image-7111" /></p>
<h4>So, what’s good in this?</h4>
<p>Responsive web design is a valid approach as it requires a single effort to support a multitude of devices. Content leads the way and can be increased, reduced, shrunk or removed on demand and depending on context.</p>
<h4>Then where’s the issue?</h4>
<p>Actually there are a few…<br />
Responsive design is based on the assumption that the substantive features of online content should not vary across devices. When we consider how much the user’s context can depend on where and how they are accessing online content, we see that this assumption may not be true all the time. If we use the case of a contact page as an example, it makes sense to display only a map or driving directions for the mobile context (since users are likely to be on the road), while displaying office photography and detailed contact information for the desktop context (since users are stationary and can afford to browse longer). A responsive design approach is too undifferentiated for these situations.</p>
<p>Creating a responsive layout is not easy and requires a lot of preparation &#8211; it must accommodate a series of grids on both portrait and landscape modes, as opposed to a fixed width layout with a single vertical view that adheres to a single grid system. This effort could be substantial, and might be a waste if the intended targets are explicitly defined (like in our contact page example). Ultimately, it&#8217;s important to ask: should my design be responsive or adaptive? </p>
<p><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/end.png" alt="" title="end" width="680" height="500" class="aligncenter size-full wp-image-7064" /></p>
<p>Another consideration we identified with responsive designs was their difficulty to treat type contextually. We observed that they were often too deterministic in trying to replicate typographic elements on small screens that were of minor importance for mobile usage. Conversely, we noticed some responsive designs were so fluid that they became too loose (excessively wide text columns, margins, etc.). </p>
<p>There are many solutions you can consider when trying to tackle varying screen sizes, but picking the right one depends on your projects&#8217; goals and device context. Trying to find a golden solution might not be the right approach. Responsive design is just one of many solutions that can help with that problem, but it’s not the miracle solution that many are hoping for.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.teehanlax.com/labs/responsive-design-pt-1/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Getting started with Paper.js</title>
		<link>http://www.teehanlax.com/labs/getting-started-with-paper-js/</link>
		<comments>http://www.teehanlax.com/labs/getting-started-with-paper-js/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 15:03:32 +0000</pubDate>
		<dc:creator>Peter Nitsch</dc:creator>
		
		<guid isPermaLink="false">http://www.teehanlax.com/?post_type=labs&amp;p=6755</guid>
		<description><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/lead-740x350.png' /><br /><br />UPDATE 07/20/11: Updated the demo to take better advantage of built-in Paper.js features. UPDATE 07/27/11: Compacted the demo even further utilizing the active layer object....
]]></description>
			<content:encoded><![CDATA[<img src='http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/lead-740x350.png' /><br /><br /><p><strong>UPDATE 07/20/11:</strong> Updated the demo to take better advantage of built-in Paper.js features.<br />
<strong>UPDATE 07/27/11:</strong> Compacted the demo even further utilizing the active layer object. </p>
<p>Recently, we&#8217;ve been exploring various vector graphics libraries in an order to craft some more compelling data visualizations. I&#8217;ll admit, we weren&#8217;t too enthusiastic about the prospect of manipulating SVG or learning some strange custom syntax. Fortunately for us, <a href="http://paperjs.org/">Paper.js</a> was released a few weeks back.<br />
<span id="more-6755"></span><br />
Paper.js is a brand new open source vector graphics scripting framework with two important distinctions. First, it&#8217;s actually nothing new. Paper.js is entirely based off <a href="http://scriptographer.org/">Scriptographer</a>, the ten year old scripting framework for Adobe Illustrator, complete with its own mature and battle-tested display hierarchy and Object Model. This is welcome news for any developer familiar with Illustrator or &#8211; more importantly &#8211; Flash. Second, it uses the Canvas element as opposed to SVG. Besides the speed boost this grants, it also means we can take advantage of the rasterization and bitmap manipulation features of Canvas. </p>
<p>We’ve put together a simple example that showcases some of the structure and features of Paper.js including debugging guidelines, smoothing, and path manipulation. Additionally, it demonstrates simple interactions and event handling.</p>
<p><a href="http://tllabs.io/paper/">Click to view our tutorial example.</a></p>
<p><a href="http://tllabs.io/paper/"><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/guides.png" alt="Guideline handles" title="Guidelines" width="680" height="344" class="alignnone size-full wp-image-6774" /></a></p>
<p>Paperscript (the Paper.js extension of Javascript) is an important differentiation from other vector graphic libraries in that it provides a sand-boxed scope for Paper.js scripts. It treats objects such as <a href="http://paperjs.org/reference/point">Point</a> and <a href="http://paperjs.org/reference/size">Size</a> like native data structures with operator overloaders in full effect. For example, you can add two points by simply performing: <strong>point1 + point2</strong>. Contrast this to a similar framework like <a href="http://raphaeljs.com/">Raphael</a>, which requires the cumbersome <a href="http://raphaeljs.com/reference.html#path">manipulation of SVG strings</a>, and you can start seeing the benefits of paperscript.</p>
<p>The first step in our demo is to declare our paperscript and tie a canvas instance to its scope. We’ll also declare some built-in handlers for resize, keyboard, and mouse movement events. The handlers are automatically bound once declared &#8211; no need to attach them to an element.</p>
<pre class="brush: jscript; title: ;">
&lt;canvas id=&quot;canvas&quot; resize keepalive=&quot;true&quot;&gt;&lt;/canvas&gt;
&lt;script type=&quot;text/paperscript&quot; canvas=&quot;canvas&quot;&gt;
	function onResize() {
		//
	}
	
	function onMouseMove(event) {
		//
	}

	function onKeyUp(e) {
		//
	}
&lt;/script&gt; 
</pre>
<p>Let&#8217;s construct a simple fake terrain effect with depth being simulated by brightness. In this case we’re building a series of paths stacked vertically with an equal number of segments across each path resulting in a square grid (<strong>gridSize x gridSize</strong>). First we need to declare our grid dimensions.</p>
<pre class="brush: jscript; title: ;">
var gridSize = 20;
</pre>
<p><a href="http://paperjs.org/reference/path">Path</a> is the core visual building block in Paper.js that is used to construct other vector graphics objects in its display hierarchy. We’ll be using them directly to build our grid. Every row in our grid represents a new Path object with columns being represented by that object’s segments. We&#8217;ll instantiate each path on every loop iteration. Next we&#8217;ll use the Path method <strong>add()</strong> to add the segment points. </p>
<pre class="brush: jscript; title: ;">
for (var j = 0; j &lt;= gridSize; j++) {
	var path = new Path();
	
	for (var i = 0; i &lt;= gridSize; i++) {  
		path.add(new Segment());
	}
}
</pre>
<p>Let’s change some of the rendering properties of each Path so we can visually differentiate them. As we loop over each row, we assign a stroke color to the path which becomes brighter as increments get higher. Paper.js has built in color objects for handling RGB, HSB, HSL, and Grayscale. We’ll use <a href=”http://paperjs.org/reference/hslcolor”>HSLColor</a> to display a range of greens. The stroke width can be set globally and inherited by every newly instantiated path. Paper.js has a base <a href="http://paperjs.org/reference/project">Project</a> object which acts as our &#8220;document&#8221;. We set the stroke width of our projects&#8217; current style to a value proportional to the canvas dimensions.</p>
<pre class="brush: jscript; title: ;">
project.currentStyle.strokeWidth = (view.size.height + view.size.width) / 0.8 / gridSize;

for (var j = 0; j &lt;= gridSize; j++) {
	var path = new Path();
	var brightness = j / gridSize * 0.608;
	path.strokeColor = new HSLColor(155, 1, brightness);
	
	for (var i = 0; i &lt;= gridSize; i++) {  
		path.add(new Segment());
	}
}
</pre>
<p>It&#8217;s important to note that once a visual object is created, it will be rendered as part of the display hierarchy. There is no manual <strong>draw()</strong> or <strong>render()</strong> method to call. Paper.js has several structures for managing the display hierarchy including <a href="http://paperjs.org/reference/project">Project</a>, <a href="http://paperjs.org/reference/link">Symbol</a>, and <a href="http://paperjs.org/reference/layer">Layer</a> objects. In our example, when we want to iterate over each segment, we reference the child nodes (the path objects) of our project&#8217;s active layer. </p>
<pre class="brush: jscript; title: ;">
var layer = project.activeLayer;
</pre>
<p>Now we can start doing the fun stuff &#8211; segment manipulation. Inside the <strong>onMouseMove</strong> event handler, we construct our reference loop. Here we use a nested <strong>for</strong> loop for simplicity. It should be noted that this is a very inefficient method for performance. Structures such as linked lists would be more appropriate if we were dealing with a large number of segments.</p>
<pre class="brush: jscript; title: ;">
function onMouseMove(event) {
	for (var j = 0; j &lt;= gridSize; j++) {
		var path = layer.children[j];

		for (var i = 0; i &lt;= gridSize; i++) {
			var segment = path.segments[i];
		}
	}
}
</pre>
<p>Next, we move the segments&#8217; point. For our demo, we apply some force vectors to each grid point. These vectors are generated by offsetting the segment coordinates (<strong>point</strong>) by a normalized vector (<strong>delta</strong>) pointing to our mouse position (<strong>event.point</strong>). Recall that paperscript has operator overloaders. This means that we can simply subtract the mouse point object from the grid point (<strong>event.point &#8211; point</strong>). Additionally, points have a built-in normalize method, which means we can write the entire vector operation in one line (<strong>(event.point &#8211; o).normalize()</strong>). The normals are amplified by force (<strong>force</strong>) to give us a smoother bump effect and then applied to the grid point. Finally, we use the built-in <strong>smooth()</strong> method on each path so we don’t have to worry about bezier handle adjustments.</p>
<pre class="brush: jscript; title: ;">
function onMouseMove(event) {
	mousePoint = event.point;
	for (var j = 0; j &lt;= gridSize; j++) {
		var path = layer.children[j];
		for (var i = 0; i &lt;= gridSize; i++) {
			var segment = path.segments[i];
			
			var point = view.size * 1.2 * (new Point(i, j) / gridSize);
			var delta = (event.point - point).normalize();
			var force = ((view.size.height + view.size.width) / 2) * 0.2;
			segment.point = point + delta * [force / -2, force];
		}
		path.smooth();
	}
}
</pre>
<p>The last interaction we want to apply is a toggle for the debugger guidelines. These guidelines visually look like a selected path in Illustrator, complete with bezier handles (non-interactive at the moment). The <strong>fullySelected</strong> property on our project&#8217;s active layer will trigger guidelines an all its children &#8211; another example of the robust display hierarchy in Paper.js. Now we can see how the path handles change in real-time. </p>
<pre class="brush: jscript; title: ;">
function onKeyUp(event) {
	layer.fullySelected = !layer.selected;
}
</pre>
<p>The finished demo can be viewed <a href="http://tllabs.io/paper/">here</a>. Make sure to view the source for better documentation and the complete flow. We took this demo a little bit farther and tied it to the <a href="https://wiki.mozilla.org/Audio_Data_API">Audio Data API</a> (currently only available in FireFox 4+) and created an <a href="http://tllabs.io/audiopaper/">audio visualizer</a> written purely in Paper.js. </p>
<p><a href="http://tllabs.io/audiopaper/"><img src="http://teehanlax.com.s3.amazonaws.com/wp-content/uploads/audio2.png" alt="" title="Audio Visualizer" width="680" height="315" class="alignnone size-full wp-image-6788" /></a></p>
<p>We&#8217;re excited about the possibilities Paper.js creates &#8211; particularly when applied to data visualizations. Support and development of the library seems to be healthy, and the roadmap includes some very interesting future features. <a href="http://paperjs.org/about/roadmap/">Paper.js + Node.js</a>, anybody?</p>

]]></content:encoded>
			<wfw:commentRss>http://www.teehanlax.com/labs/getting-started-with-paper-js/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
