<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xml:lang="en">
  <title type="text">Antoine Leclair's Blog</title>
  <subtitle type="text">This is my blog</subtitle>

  <updated>2011-12-14T04:31:57Z</updated>
  <generator uri="http://blogofile.com/">Blogofile</generator>

  <link rel="alternate" type="text/html" href="http://antoineleclair.ca" />
  <id>http://antoineleclair.ca/feed/atom/</id>
  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/AntoineLeclairsBlog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="antoineleclairsblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <author>
      <name />
      <uri>http://antoineleclair.ca</uri>
    </author>
    <title type="html"><![CDATA[Generating Country List For HTML Select]]></title>
    <link rel="alternate" type="text/html" href="http://antoineleclair.ca/2011/12/13/generating-country-list-for-html-select/" />
    <id>http://antoineleclair.ca/2011/12/13/generating-country-list-for-html-select/</id>
    <updated>2011-12-13T23:25:00Z</updated>
    <published>2011-12-13T23:25:00Z</published>
    <category scheme="http://antoineleclair.ca" term="Uncategorized" />
    <summary type="html"><![CDATA[Generating Country List For HTML Select]]></summary>
    <content type="html" xml:base="http://antoineleclair.ca/2011/12/13/generating-country-list-for-html-select/"><![CDATA[<p>During a client project using Paypal DirectPayment API, I had to make a <code>&lt;select&gt;</code> with all the countries with their country codes as the value. For example:</p>
<div class="pygments_default"><pre><span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;US&quot;</span><span class="nt">&gt;</span>United States<span class="nt">&lt;/option&gt;</span><br/><span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;CA&quot;</span><span class="nt">&gt;</span>Canada<span class="nt">&lt;/option&gt;</span><br/></pre></div>

<p>Paypal already gives <a href="https://www.paypalobjects.com/en_US/ebook/PP_NVPAPI_DeveloperGuide/countrycodes_new.html">this list</a>.</p>
<p>Problem is that it's only in English and all in caps. What I needed is a French version and an English version, not in caps.</p>
<p><a href="http://geonames.org/">Geonames.org</a> just happens to have what I needed. This Python script is what I coded to generate what I needed:</p>
<div class="pygments_default"><pre><span class="kn">import</span> <span class="nn">urllib</span><span class="o">,</span> <span class="nn">json</span><span class="o">,</span> <span class="nn">unicodedata</span><br/><br/><span class="k">def</span> <span class="nf">get_list</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="s">&#39;demo&#39;</span><span class="p">,</span> <span class="n">lang</span><span class="o">=</span><span class="s">&#39;en&#39;</span><span class="p">):</span><br/>    <span class="sd">&quot;&quot;&quot;Fetches the json of all countries from geonames.org.&quot;&quot;&quot;</span><br/>    <span class="n">params</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">urlencode</span><span class="p">({</span><span class="s">&#39;lang&#39;</span><span class="p">:</span> <span class="n">lang</span><span class="p">,</span> <span class="s">&#39;username&#39;</span><span class="p">:</span> <span class="n">username</span><span class="p">})</span><br/>    <span class="n">url</span> <span class="o">=</span> <span class="s">&#39;http://api.geonames.org/countryInfoJSON?</span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="n">params</span><br/>    <span class="n">f</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><br/>    <span class="n">response_text</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><br/>    <span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response_text</span><span class="p">)[</span><span class="s">&quot;geonames&quot;</span><span class="p">]</span><br/><br/><span class="k">def</span> <span class="nf">country_list_generator</span><span class="p">(</span><span class="n">country_list</span><span class="p">,</span> <span class="n">func</span><span class="p">):</span><br/>    <span class="sd">&quot;&quot;&quot;Returns a generator of countries.</span><br/><span class="sd">    They are sorted alphabetically,</span><br/><span class="sd">    and the func passed as argument is applied to each of them.&quot;&quot;&quot;</span><br/>    <span class="n">ordered</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">country_list</span><span class="p">,</span><br/>        <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">k</span><span class="p">:</span> <span class="n">strip_accents</span><span class="p">(</span><span class="n">k</span><span class="p">[</span><span class="s">&#39;countryName&#39;</span><span class="p">]))</span><br/>    <span class="k">return</span> <span class="p">(</span><span class="n">func</span><span class="p">(</span><span class="n">country</span><span class="p">)</span> <span class="k">for</span> <span class="n">country</span> <span class="ow">in</span> <span class="n">ordered</span><span class="p">)</span><br/><br/><span class="k">def</span> <span class="nf">country_to_option</span><span class="p">(</span><span class="n">country</span><span class="p">):</span><br/>    <span class="sd">&quot;&quot;&quot;Transforms a country dict to an html option tag,</span><br/><span class="sd">    The country code is used for the value.&quot;&quot;&quot;</span><br/>    <span class="k">return</span> <span class="p">(</span><span class="s">&#39;&lt;option value=&quot;</span><span class="si">%s</span><span class="s">&quot;&gt;</span><span class="si">%s</span><span class="s">&lt;/option&gt;</span><span class="se">\n</span><span class="s">&#39;</span> <span class="o">%</span> \<br/>        <span class="p">(</span><span class="n">country</span><span class="p">[</span><span class="s">&#39;countryCode&#39;</span><span class="p">],</span> <span class="n">country</span><span class="p">[</span><span class="s">&#39;countryName&#39;</span><span class="p">]))</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;utf-8&#39;</span><span class="p">)</span><br/><br/><span class="k">def</span> <span class="nf">country_to_csharp_dict_pair</span><span class="p">(</span><span class="n">country</span><span class="p">):</span><br/>    <span class="sd">&quot;&quot;&quot;Transforms a country dict to a C# Dictionary pair.&quot;&quot;&quot;</span> <br/>    <span class="k">return</span> <span class="p">(</span><span class="s">&#39;{&quot;</span><span class="si">%s</span><span class="s">&quot;, &quot;</span><span class="si">%s</span><span class="s">&quot;},</span><span class="se">\n</span><span class="s">&#39;</span> <span class="o">%</span> \<br/>        <span class="p">(</span><span class="n">country</span><span class="p">[</span><span class="s">&#39;countryCode&#39;</span><span class="p">],</span> <span class="n">country</span><span class="p">[</span><span class="s">&#39;countryName&#39;</span><span class="p">]))</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;utf-8&#39;</span><span class="p">)</span><br/>    <br/><span class="k">def</span> <span class="nf">strip_accents</span><span class="p">(</span><span class="n">s</span><span class="p">):</span><br/>    <span class="sd">&quot;&quot;&quot;Removes the accents from a unicode string.</span><br/><span class="sd">    This function is used for sorting.&quot;&quot;&quot;</span><br/>    <span class="k">return</span> <span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">c</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">unicodedata</span><span class="o">.</span><span class="n">normalize</span><span class="p">(</span><span class="s">&#39;NFD&#39;</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span> \<br/>                        <span class="k">if</span> <span class="n">unicodedata</span><span class="o">.</span><span class="n">category</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="o">!=</span> <span class="s">&#39;Mn&#39;</span><span class="p">))</span><br/><br/><span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span><br/>    <span class="n">country_list</span> <span class="o">=</span> <span class="n">get_list</span><span class="p">(</span><span class="s">&#39;demo&#39;</span><span class="p">,</span> <span class="n">lang</span><span class="o">=</span><span class="s">&#39;en&#39;</span><span class="p">)</span><br/>    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;output.txt&#39;</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span><br/>        <span class="n">gen</span> <span class="o">=</span> <span class="n">country_list_generator</span><span class="p">(</span><span class="n">country_list</span><span class="p">,</span> <span class="n">country_to_option</span><span class="p">)</span><br/>        <span class="n">f</span><span class="o">.</span><span class="n">writelines</span><span class="p">(</span><span class="n">gen</span><span class="p">)</span><br/></pre></div>

<p>Hope it's useful to someone else.</p>
<p>The code is on <a href="https://github.com/antoineleclair/country-list-with-country-code">Github</a>.</p>]]></content>
  </entry>
  <entry>
    <author>
      <name />
      <uri>http://antoineleclair.ca</uri>
    </author>
    <title type="html"><![CDATA[Styling Google Maps]]></title>
    <link rel="alternate" type="text/html" href="http://antoineleclair.ca/2011/08/29/styling-google-maps/" />
    <id>http://antoineleclair.ca/2011/08/29/styling-google-maps/</id>
    <updated>2011-08-29T22:54:00Z</updated>
    <published>2011-08-29T22:54:00Z</published>
    <category scheme="http://antoineleclair.ca" term="Uncategorized" />
    <summary type="html"><![CDATA[Styling Google Maps]]></summary>
    <content type="html" xml:base="http://antoineleclair.ca/2011/08/29/styling-google-maps/"><![CDATA[<p>It seems to be a little known fact that you can add custom styles to Google
Maps using the Javascript API.</p>
<p>It's really not that complex and we use it often for client sites.</p>
<div id="styled-maps-example-1"></div>

<p>First thing to do is create the JSON to use for the style. You can use
<a href="http://gmaps-samples-v3.googlecode.com/svn/trunk/styledmaps/wizard/index.html">this wizard</a>,
it's a great tool for that.</p>
<p>Then you use the JSON in your Javascript like so:</p>
<div class="pygments_default"><pre><span class="c1">// your JSON</span><br/><span class="kd">var</span> <span class="nx">mapStyle</span> <span class="o">=</span> <span class="p">[</span><br/>  <span class="p">{</span><br/>      <span class="nx">featureType</span><span class="o">:</span> <span class="s2">&quot;landscape&quot;</span><span class="p">,</span><br/>      <span class="nx">elementType</span><span class="o">:</span> <span class="s2">&quot;all&quot;</span><span class="p">,</span><br/>      <span class="nx">stylers</span><span class="o">:</span> <span class="p">[</span><br/>      <span class="p">{</span> <span class="nx">hue</span><span class="o">:</span> <span class="s2">&quot;#ff4d00&quot;</span> <span class="p">},</span><br/>      <span class="p">{</span> <span class="nx">lightness</span><span class="o">:</span> <span class="o">-</span><span class="mi">72</span> <span class="p">},</span><br/>      <span class="p">{</span> <span class="nx">saturation</span><span class="o">:</span> <span class="o">-</span><span class="mi">74</span> <span class="p">}</span><br/>    <span class="p">]</span><br/>  <span class="p">}</span><br/><span class="p">];</span><br/><br/><span class="c1">// usual Google Maps code, plus styling</span><br/><span class="kd">var</span> <span class="nx">map</span><span class="p">;</span><br/><br/><span class="nx">$</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span><br/>    <span class="kd">var</span> <span class="nx">mapOptions</span> <span class="o">=</span> <span class="p">{</span><br/>        <span class="nx">zoom</span><span class="o">:</span> <span class="mi">12</span><span class="p">,</span><br/>        <span class="nx">mapTypeId</span><span class="o">:</span> <span class="s1">&#39;MapStyle&#39;</span><span class="p">,</span><br/>        <span class="nx">mapTypeControlOptions</span><span class="o">:</span> <span class="p">{</span><br/>            <span class="nx">mapTypeIds</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;MapStyle&#39;</span><span class="p">,</span> <span class="nx">google</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="nx">MapTypeId</span><span class="p">.</span><span class="nx">SATELLITE</span><span class="p">]</span><br/>        <span class="p">}</span><br/>    <span class="p">};</span><br/>    <br/>    <span class="kd">var</span> <span class="nx">styledMapOptions</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Map&quot;</span> <span class="p">};</span><br/><br/>    <span class="nx">map</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">google</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="nx">Map</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">&quot;styled-maps-example-1&quot;</span><span class="p">),</span> <span class="nx">mapOptions</span><span class="p">);</span><br/>    <span class="nx">map</span><span class="p">.</span><span class="nx">setCenter</span><span class="p">(</span><span class="k">new</span> <span class="nx">google</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="nx">LatLng</span><span class="p">(</span><span class="mf">46.8</span><span class="p">,</span><span class="o">-</span><span class="mf">71.25</span><span class="p">));</span><br/>    <span class="kd">var</span> <span class="nx">mapType</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">google</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="nx">StyledMapType</span><span class="p">(</span><span class="nx">mapStyle</span><span class="p">,</span> <span class="nx">styledMapOptions</span><span class="p">);</span><br/>    <span class="nx">map</span><span class="p">.</span><span class="nx">mapTypes</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;MapStyle&#39;</span><span class="p">,</span> <span class="nx">mapType</span><span class="p">);</span><br/>    <span class="nx">map</span><span class="p">.</span><span class="nx">setMapTypeId</span><span class="p">(</span><span class="s1">&#39;MapStyle&#39;</span><span class="p">);</span><br/><span class="p">});</span><br/></pre></div>

<p>It's even in the <a href="http://code.google.com/apis/maps/documentation/javascript/styling.html">docs</a>.
I don't see any reason why there's so little use of this feature.</p>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>

<script type="text/javascript">
var mapStyle = [
  {
      featureType: "landscape",
      elementType: "all",
      stylers: [
      { hue: "#ff4d00" },
      { lightness: -72 },
      { saturation: -74 }
    ]
  }, {
      featureType: "water",
      elementType: "all",
      stylers: [
      { hue: "#ff3c00" },
      { saturation: -67 },
      { lightness: -80 }
    ]
  }, {
      featureType: "administrative",
      elementType: "all",
      stylers: [
      { invert_lightness: true },
      { gamma: 2.51 },
      { lightness: 23 },
      { saturation: 6 }
    ]
  }, {
      featureType: "poi",
      elementType: "all",
      stylers: [
      { visibility: "off" }
    ]
  }, {
      featureType: "road.highway",
      elementType: "all",
      stylers: [
      { hue: "#ff4400" },
      { saturation: -90 }
    ]
  }, {
      featureType: "transit",
      elementType: "all",
      stylers: [
      { visibility: "off" },
      { saturation: -81 }
    ]
  }, {
      featureType: "road.arterial",
      elementType: "all",
      stylers: [
      { lightness: -32 },
      { hue: "#ff4400" },
      { saturation: -93 },
      { invert_lightness: true },
      { gamma: 0.73 }
    ]
  }, {
      featureType: "road.local",
      elementType: "all",
      stylers: [
      { saturation: -70 },
      { invert_lightness: true },
      { lightness: -17 },
      { gamma: 0.56 }
    ]
  }
];

var map;

$(function () {
    $('#styled-maps-example-1').css('height', '400px');

var mapOptions = {
        zoom: 12,
        mapTypeId: 'MapStyle',
        mapTypeControlOptions: {
            mapTypeIds: ['MapStyle', google.maps.MapTypeId.SATELLITE]
        }
    };

var styledMapOptions = { name: "Map" };

map = new google.maps.Map(document.getElementById("styled-maps-example-1"), mapOptions);
    map.setCenter(new google.maps.LatLng(46.8,-71.25));
    var mapType = new google.maps.StyledMapType(mapStyle, styledMapOptions);
    map.mapTypes.set('MapStyle', mapType);
    map.setMapTypeId('MapStyle');
});
</script>]]></content>
  </entry>
  <entry>
    <author>
      <name />
      <uri>http://antoineleclair.ca</uri>
    </author>
    <title type="html"><![CDATA[Understanding Quadratic Bézier Curves]]></title>
    <link rel="alternate" type="text/html" href="http://antoineleclair.ca/2011/08/27/understanding-quadratic-bezier-curves/" />
    <id>http://antoineleclair.ca/2011/08/27/understanding-quadratic-bezier-curves/</id>
    <updated>2011-08-27T11:30:00Z</updated>
    <published>2011-08-27T11:30:00Z</published>
    <category scheme="http://antoineleclair.ca" term="Uncategorized" />
    <summary type="html"><![CDATA[Understanding Quadratic Bézier Curves]]></summary>
    <content type="html" xml:base="http://antoineleclair.ca/2011/08/27/understanding-quadratic-bezier-curves/"><![CDATA[<p>In a client project I had to draw by hand a quadratic Bézier curve, because the
html5 canvas quadraticCurveTo does not return the information about the path
drawn and I needed it.</p>
<p>Some basic explanation of a quadratic Bézier curve. You have a
start point <code>P1</code>, an end point <code>P2</code> and a control point <code>C</code>. Both the <code>x</code> and
<code>y</code> of each point on the path is dependant on <code>t</code>, which will vary from
0 to 1. <code>t=0</code> at the begining of the curve and <code>t=1</code> and the end of the curve.</p>
<p>You draw an imaginary line between <code>P1</code> and <code>C</code> (<code>P1C</code> line) and
another one between <code>C</code> and <code>P2</code> (<code>CP2</code> line). For each value of <code>t</code>, you mark
an imaginary point on <code>P1C</code> and <code>CP2</code>. The point on <code>P1C</code> is at <code>t</code> of the line,
starting at <code>P1</code>, and the point on the <code>CP2</code> line is at <code>t</code> of the line,
starting at <code>C</code>. Let's call those points <code>C1</code> and <code>C2</code>.</p>
<p>Then, you draw an imaginary line between <code>C1</code> and <code>C2</code>, and you mark a real
point at <code>t</code> of the <code>C1C2</code> line.</p>
<p>You repeat the procedure for every value of <code>t</code>, where <code>t</code> varies from 0 to 1.
All the points you marked on the line <code>C1C2</code> are showing the quadratic Bézier
curve.</p>
<p>Here's a little animation I made to explain it better:</p>
<div id="bezier-example-1" style="position:relative;">
    <canvas class="curve" style="position:absolute;top:0;left:0;z-index:4;"></canvas>
    <canvas class="animation" style="position:absolute;top:0;left:0;z-index:3;"></canvas>
    <canvas class="points" style="position:absolute;top:0;left:0;z-index:2;"></canvas>
    <canvas class="grid" style="position:absolute;top:0;left:0;z-index:1;"></canvas>
</div>

<p id="bezier-example-1-t">t = <span>0</span></p>

<script type="text/javascript">
    $(function() {

var CANVAS_WIDTH = 301;
        var CANVAS_HEIGHT = 301;
        var p1x = 20;
        var p1y = 200;
        var cx = 140;
        var cy = 20;
        var p2x = 280;
        var p2y = 280;
        if (Modernizr.canvas) {
            var $t = $('#bezier-example-1-t span');
            $('#bezier-example-1').css({
                width: CANVAS_WIDTH + 'px',
                height: CANVAS_HEIGHT + 'px'
            });
            var gridCanvas = $('#bezier-example-1 .grid').get(0);
            var gridContext = gridCanvas.getContext('2d');
            gridCanvas.width = CANVAS_WIDTH;
            gridCanvas.height = CANVAS_HEIGHT;

var pointsCanvas = $('#bezier-example-1 .points').get(0);
            var pointsContext = pointsCanvas.getContext('2d');
            pointsCanvas.width = CANVAS_WIDTH;
            pointsCanvas.height = CANVAS_HEIGHT;

var animationCanvas = $('#bezier-example-1 .animation').get(0);
            var animationContext = animationCanvas.getContext('2d');
            animationCanvas.width = CANVAS_WIDTH;
            animationCanvas.height = CANVAS_HEIGHT;

var curveCanvas = $('#bezier-example-1 .curve').get(0);
            var curveContext = curveCanvas.getContext('2d');
            curveCanvas.width = CANVAS_WIDTH;
            curveCanvas.height = CANVAS_HEIGHT;
            curveContext.strokeStyle = "#777";
            curveContext.lineWidth = 2;
            curveContext.beginPath();
            curveContext.moveTo(p1x, p1y);
            curveContext.stroke();

drawGrid();
            drawSetup();
            setInterval(updateDemo, 1000/30);
        } else {
            $('#bezier-example-1').html('Your browser does not support Canvas.');
            $('#bezier-example-1-t').remove();
        }
        var t = 0;
        var d = 1; // direction

function updateDemo() {
            if (t > 1 || t < 0) {
                d *= -1; // change direction
                curveContext.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
                curveContext.beginPath();
            }
            t += 0.01 * d; // continue moving
            $t.html(Math.round(t*100)/100);
            // update values
            var c1x = p1x + (cx - p1x) * t;
            var c1y = p1y + (cy - p1y) * t;
            var c2x = cx + (p2x - cx) * t;
            var c2y = cy + (p2y - cy) * t;
            var tx = c1x + (c2x - c1x) * t;
            var ty = c1y + (c2y - c1y) * t;

animationContext.save();
            // clear old sketch
            animationContext.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
            // draw new line
            animationContext.beginPath();
            animationContext.strokeStyle = '#aaa';
            animationContext.lineWidth = 1;
            animationContext.moveTo(c1x, c1y);
            animationContext.lineTo(c2x, c2y);
            animationContext.stroke();
            // draw points on lines
            drawPoint(animationContext, c1x, c1y, 2, '#0f0');
            drawPoint(animationContext, c2x, c2y, 2, '#0f0');
            // draw point on curve
            drawPoint(animationContext, tx, ty, 3, '#f0f');
            animationContext.restore();

// draw the Bézier curve by hand
            curveContext.lineTo(tx, ty);
            curveContext.stroke();         
        }

function drawSetup() {

pointsContext.save();
            // lines between p1, c and p2
            pointsContext.strokeStyle = "#ddd";
            pointsContext.lineWidth = 2;
            pointsContext.beginPath();
            pointsContext.moveTo(p1x, p1y);
            pointsContext.lineTo(cx, cy);
            pointsContext.lineTo(p2x, p2y);
            pointsContext.stroke();
            pointsContext.closePath();
            // quadratic Bézier curve
            pointsContext.beginPath();
            pointsContext.strokeStyle = '#999';
            pointsContext.lineWidth = 1;
            pointsContext.moveTo(p1x, p1y);
            pointsContext.quadraticCurveTo(cx,cy, p2x, p2y);
            pointsContext.stroke();                
            pointsContext.restore();

// circles marking p1, c and p2
            drawPoint(pointsContext, p1x, p1y, 5, '#00f');
            drawPoint(pointsContext, cx, cy, 5, '#f00');
            drawPoint(pointsContext, p2x, p2y, 5, '#00f');
            pointsContext.fillText("P1", p1x+10, p1y+10);                
            pointsContext.fillText("C", cx+10,  cy-5);                
            pointsContext.fillText("P2", p2x-20, p2y+10);                
        }

function drawPoint(ctx, x, y, radius, color) {
            ctx.save();
            ctx.fillStyle = color;
            ctx.beginPath();
            ctx.arc(x, y, radius, 2 * Math.PI, false);
            ctx.fill();
            ctx.closePath();
            ctx.restore();
        }

function drawGrid() {
            gridContext.save();
            gridContext.strokeStyle = '#ddd';
            gridContext.lineWidth = 1;
            for (var i = 0; i < CANVAS_HEIGHT; i += 20) {
                gridContext.beginPath();
                gridContext.moveTo(0, i);
                gridContext.lineTo(CANVAS_WIDTH, i);
                gridContext.stroke();
            }
            for (var i = 0; i < CANVAS_WIDTH; i += 20) {
                gridContext.beginPath();
                gridContext.moveTo(i, 0);
                gridContext.lineTo(i, CANVAS_HEIGHT);
                gridContext.stroke();
                gridContext.closePath();
            }
            gridContext.restore();
        }
    });
</script>

<p>You can have a look at the source for a complete understanding, but here's the
important part, edited for clarity:</p>
<div class="pygments_default"><pre><span class="c1">// constants</span><br/><span class="kd">var</span> <span class="nx">CANVAS_WIDTH</span> <span class="o">=</span> <span class="mi">301</span><span class="p">;</span><br/><span class="kd">var</span> <span class="nx">CANVAS_HEIGHT</span> <span class="o">=</span> <span class="mi">301</span><span class="p">;</span><br/><span class="kd">var</span> <span class="nx">p1x</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span><br/><span class="kd">var</span> <span class="nx">p1y</span> <span class="o">=</span> <span class="mi">200</span><span class="p">;</span><br/><span class="kd">var</span> <span class="nx">cx</span> <span class="o">=</span> <span class="mi">140</span><span class="p">;</span><br/><span class="kd">var</span> <span class="nx">cy</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span><br/><span class="kd">var</span> <span class="nx">p2x</span> <span class="o">=</span> <span class="mi">280</span><span class="p">;</span><br/><span class="kd">var</span> <span class="nx">p2y</span> <span class="o">=</span> <span class="mi">280</span><span class="p">;</span><br/><br/><span class="c1">// basic setup</span><br/><span class="kd">var</span> <span class="nx">$t</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#bezier-example-1-t span&#39;</span><span class="p">);</span><br/><br/><span class="kd">var</span> <span class="nx">animationCanvas</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#bezier-example-1 .animation&#39;</span><span class="p">).</span><span class="nx">get</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span><br/><span class="kd">var</span> <span class="nx">animationContext</span> <span class="o">=</span> <span class="nx">animationCanvas</span><span class="p">.</span><span class="nx">getContext</span><span class="p">(</span><span class="s1">&#39;2d&#39;</span><span class="p">);</span><br/><span class="nx">animationCanvas</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">CANVAS_WIDTH</span><span class="p">;</span><br/><span class="nx">animationCanvas</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">CANVAS_HEIGHT</span><span class="p">;</span><br/><br/><span class="kd">var</span> <span class="nx">curveCanvas</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#bezier-example-1 .curve&#39;</span><span class="p">).</span><span class="nx">get</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span><br/><span class="kd">var</span> <span class="nx">curveContext</span> <span class="o">=</span> <span class="nx">curveCanvas</span><span class="p">.</span><span class="nx">getContext</span><span class="p">(</span><span class="s1">&#39;2d&#39;</span><span class="p">);</span><br/><span class="nx">curveCanvas</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">CANVAS_WIDTH</span><span class="p">;</span><br/><span class="nx">curveCanvas</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">CANVAS_HEIGHT</span><span class="p">;</span><br/><span class="nx">curveContext</span><span class="p">.</span><span class="nx">strokeStyle</span> <span class="o">=</span> <span class="s2">&quot;#777&quot;</span><span class="p">;</span><br/><span class="nx">curveContext</span><span class="p">.</span><span class="nx">lineWidth</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span><br/><span class="nx">curveContext</span><span class="p">.</span><span class="nx">beginPath</span><span class="p">();</span><br/><span class="nx">curveContext</span><span class="p">.</span><span class="nx">moveTo</span><span class="p">(</span><span class="nx">p1x</span><span class="p">,</span> <span class="nx">p1y</span><span class="p">);</span><br/><span class="nx">curveContext</span><span class="p">.</span><span class="nx">stroke</span><span class="p">();</span><br/><br/><span class="nx">setInterval</span><span class="p">(</span><span class="nx">updateDemo</span><span class="p">,</span> <span class="mi">1000</span><span class="o">/</span><span class="mi">30</span><span class="p">);</span><br/><br/><span class="kd">var</span> <span class="nx">t</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span><br/><span class="kd">var</span> <span class="nx">d</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// direction</span><br/><br/><span class="kd">function</span> <span class="nx">updateDemo</span><span class="p">()</span> <span class="p">{</span> <span class="c1">// called 30 times/second to animate</span><br/>    <span class="k">if</span> <span class="p">(</span><span class="nx">t</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="o">||</span> <span class="nx">t</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span><br/>        <span class="nx">d</span> <span class="o">*=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="c1">// change direction</span><br/>        <span class="nx">curveContext</span><span class="p">.</span><span class="nx">clearRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">CANVAS_WIDTH</span><span class="p">,</span> <span class="nx">CANVAS_HEIGHT</span><span class="p">);</span><br/>        <span class="nx">curveContext</span><span class="p">.</span><span class="nx">beginPath</span><span class="p">();</span><br/>    <span class="p">}</span><br/>    <span class="nx">t</span> <span class="o">+=</span> <span class="mf">0.01</span> <span class="o">*</span> <span class="nx">d</span><span class="p">;</span> <span class="c1">// continue moving</span><br/>    <span class="nx">$t</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">(</span><span class="nx">t</span><span class="o">*</span><span class="mi">100</span><span class="p">)</span><span class="o">/</span><span class="mi">100</span><span class="p">);</span><br/>    <span class="c1">// update values</span><br/>    <span class="kd">var</span> <span class="nx">c1x</span> <span class="o">=</span> <span class="nx">p1x</span> <span class="o">+</span> <span class="p">(</span><span class="nx">cx</span> <span class="o">-</span> <span class="nx">p1x</span><span class="p">)</span> <span class="o">*</span> <span class="nx">t</span><span class="p">;</span><br/>    <span class="kd">var</span> <span class="nx">c1y</span> <span class="o">=</span> <span class="nx">p1y</span> <span class="o">+</span> <span class="p">(</span><span class="nx">cy</span> <span class="o">-</span> <span class="nx">p1y</span><span class="p">)</span> <span class="o">*</span> <span class="nx">t</span><span class="p">;</span><br/>    <span class="kd">var</span> <span class="nx">c2x</span> <span class="o">=</span> <span class="nx">cx</span> <span class="o">+</span> <span class="p">(</span><span class="nx">p2x</span> <span class="o">-</span> <span class="nx">cx</span><span class="p">)</span> <span class="o">*</span> <span class="nx">t</span><span class="p">;</span><br/>    <span class="kd">var</span> <span class="nx">c2y</span> <span class="o">=</span> <span class="nx">cy</span> <span class="o">+</span> <span class="p">(</span><span class="nx">p2y</span> <span class="o">-</span> <span class="nx">cy</span><span class="p">)</span> <span class="o">*</span> <span class="nx">t</span><span class="p">;</span><br/>    <span class="kd">var</span> <span class="nx">tx</span> <span class="o">=</span> <span class="nx">c1x</span> <span class="o">+</span> <span class="p">(</span><span class="nx">c2x</span> <span class="o">-</span> <span class="nx">c1x</span><span class="p">)</span> <span class="o">*</span> <span class="nx">t</span><span class="p">;</span><br/>    <span class="kd">var</span> <span class="nx">ty</span> <span class="o">=</span> <span class="nx">c1y</span> <span class="o">+</span> <span class="p">(</span><span class="nx">c2y</span> <span class="o">-</span> <span class="nx">c1y</span><span class="p">)</span> <span class="o">*</span> <span class="nx">t</span><span class="p">;</span><br/>    <br/>    <span class="nx">animationContext</span><span class="p">.</span><span class="nx">save</span><span class="p">();</span><br/>    <span class="c1">// clear old sketch</span><br/>    <span class="nx">animationContext</span><span class="p">.</span><span class="nx">clearRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">CANVAS_WIDTH</span><span class="p">,</span> <span class="nx">CANVAS_HEIGHT</span><span class="p">);</span><br/>    <span class="c1">// draw new line</span><br/>    <span class="nx">animationContext</span><span class="p">.</span><span class="nx">beginPath</span><span class="p">();</span><br/>    <span class="nx">animationContext</span><span class="p">.</span><span class="nx">strokeStyle</span> <span class="o">=</span> <span class="s1">&#39;#aaa&#39;</span><span class="p">;</span><br/>    <span class="nx">animationContext</span><span class="p">.</span><span class="nx">lineWidth</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span><br/>    <span class="nx">animationContext</span><span class="p">.</span><span class="nx">moveTo</span><span class="p">(</span><span class="nx">c1x</span><span class="p">,</span> <span class="nx">c1y</span><span class="p">);</span><br/>    <span class="nx">animationContext</span><span class="p">.</span><span class="nx">lineTo</span><span class="p">(</span><span class="nx">c2x</span><span class="p">,</span> <span class="nx">c2y</span><span class="p">);</span><br/>    <span class="nx">animationContext</span><span class="p">.</span><span class="nx">stroke</span><span class="p">();</span><br/>    <span class="c1">// draw points on lines</span><br/>    <span class="nx">drawPoint</span><span class="p">(</span><span class="nx">animationContext</span><span class="p">,</span> <span class="nx">c1x</span><span class="p">,</span> <span class="nx">c1y</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="s1">&#39;#0f0&#39;</span><span class="p">);</span><br/>    <span class="nx">drawPoint</span><span class="p">(</span><span class="nx">animationContext</span><span class="p">,</span> <span class="nx">c2x</span><span class="p">,</span> <span class="nx">c2y</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="s1">&#39;#0f0&#39;</span><span class="p">);</span><br/>    <span class="c1">// draw point on curve</span><br/>    <span class="nx">drawPoint</span><span class="p">(</span><span class="nx">animationContext</span><span class="p">,</span> <span class="nx">tx</span><span class="p">,</span> <span class="nx">ty</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="s1">&#39;#f0f&#39;</span><span class="p">);</span><br/>    <span class="nx">animationContext</span><span class="p">.</span><span class="nx">restore</span><span class="p">();</span><br/>    <br/>    <span class="c1">// draw the new Bezier curve segment</span><br/>    <span class="nx">curveContext</span><span class="p">.</span><span class="nx">lineTo</span><span class="p">(</span><span class="nx">tx</span><span class="p">,</span> <span class="nx">ty</span><span class="p">);</span><br/>    <span class="nx">curveContext</span><span class="p">.</span><span class="nx">stroke</span><span class="p">();</span><br/><span class="p">}</span><br/></pre></div>

<p>The code is on
<a href="https://github.com/antoineleclair/Understanding-Bezier-Curve">Github</a>.</p>]]></content>
  </entry>
  <entry>
    <author>
      <name />
      <uri>http://antoineleclair.ca</uri>
    </author>
    <title type="html"><![CDATA[Some Fun With Android and Python]]></title>
    <link rel="alternate" type="text/html" href="http://antoineleclair.ca/2011/07/11/some-fun-with-android-and-python/" />
    <id>http://antoineleclair.ca/2011/07/11/some-fun-with-android-and-python/</id>
    <updated>2011-07-11T22:30:00Z</updated>
    <published>2011-07-11T22:30:00Z</published>
    <category scheme="http://antoineleclair.ca" term="Uncategorized" />
    <summary type="html"><![CDATA[Some Fun With Android and Python]]></summary>
    <content type="html" xml:base="http://antoineleclair.ca/2011/07/11/some-fun-with-android-and-python/"><![CDATA[<p>For those who don't know, the
<a href="http://code.google.com/p/android-scripting/">Android Scripting Environment</a>
allows you to use scripting languages to experiment with Android.</p>
<p>I wanted to try it, so I wrote this little web server that takes pictures
when you make an HTTP request to it.</p>
<div class="pygments_default"><pre><span class="kn">import</span> <span class="nn">BaseHTTPServer</span><span class="o">,</span> <span class="nn">android</span><br/><span class="kn">from</span> <span class="nn">os</span> <span class="kn">import</span> <span class="n">path</span> <br/><br/><span class="n">droid</span> <span class="o">=</span> <span class="n">android</span><span class="o">.</span><span class="n">Android</span><span class="p">()</span> <br/><span class="n">FILENAME</span> <span class="o">=</span> <span class="s">&quot;/sdcard/sl4a/spy/pic.jpg&quot;</span> <br/><span class="n">PORT</span> <span class="o">=</span> <span class="mi">9090</span><br/><br/><span class="k">class</span> <span class="nc">Handler</span><span class="p">(</span><span class="n">BaseHTTPServer</span><span class="o">.</span><span class="n">BaseHTTPRequestHandler</span><span class="p">):</span> <br/>    <span class="k">def</span> <span class="nf">do_GET</span><span class="p">(</span><span class="n">s</span><span class="p">):</span> <br/>        <span class="sd">&quot;&quot;&quot;Respond to a GET request.&quot;&quot;&quot;</span> <br/>        <span class="n">droid</span><span class="o">.</span><span class="n">cameraCapturePicture</span><span class="p">(</span><span class="n">FILENAME</span><span class="p">)</span> <br/>        <span class="n">picture</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">FILENAME</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span>            <br/>        <span class="n">s</span><span class="o">.</span><span class="n">send_response</span><span class="p">(</span><span class="mi">200</span><span class="p">)</span> <br/>        <span class="n">s</span><span class="o">.</span><span class="n">send_header</span><span class="p">(</span><span class="s">&quot;Content-Type&quot;</span><span class="p">,</span> <span class="s">&quot;image/jpeg&quot;</span><span class="p">)</span> <br/>        <span class="n">s</span><span class="o">.</span><span class="n">end_headers</span><span class="p">()</span> <br/>        <span class="n">s</span><span class="o">.</span><span class="n">wfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">picture</span><span class="o">.</span><span class="n">read</span><span class="p">())</span> <br/><br/><span class="n">server_class</span> <span class="o">=</span> <span class="n">BaseHTTPServer</span><span class="o">.</span><span class="n">HTTPServer</span> <br/><span class="n">httpd</span> <span class="o">=</span> <span class="n">server_class</span><span class="p">((</span><span class="s">&#39;&#39;</span><span class="p">,</span> <span class="n">PORT</span><span class="p">),</span> <span class="n">Handler</span><span class="p">)</span> <br/><span class="n">httpd</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span><br/></pre></div>

<p>The code is on
<a href="https://github.com/antoineleclair/Android-Python-Camera-Web-Server">Github</a>.</p>]]></content>
  </entry>
</feed>

