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

<channel>
	<title>Flying memes &#187; Algoritmi</title>
	<atom:link href="http://sandropaganotti.com/categoria/algoritmi/feed/" rel="self" type="application/rss+xml" />
	<link>http://sandropaganotti.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Sun, 08 Jan 2012 16:00:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Handling thousands of pics from a mobile device</title>
		<link>http://sandropaganotti.com/2011/11/27/handling-thousands-of-pics-from-a-mobile-device/</link>
		<comments>http://sandropaganotti.com/2011/11/27/handling-thousands-of-pics-from-a-mobile-device/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 21:25:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Approfondimenti]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[lot of images]]></category>
		<category><![CDATA[mobile safari]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=561</guid>
		<description><![CDATA[Lately I&#8217;ve been involved into a fascinating project called PepperTweet which consist in extract and visualize streams of pics from twitter starting from some search keywords. While working on a new visualization algorithm I discovered how easy it is to make mobile browsers crash trying to display a relative small amount of images.  I&#8217;ve used an [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been involved into a fascinating project called <a href="http://peppertweet.com/" target="_blank">PepperTweet</a> which consist in extract and visualize streams of pics from twitter starting from some search keywords.</p>
<p><span id="more-561"></span>While working on a new visualization algorithm I discovered how easy it is to make mobile browsers crash trying to display a relative small amount of images.  I&#8217;ve used an IPad 1 with IOs 5 for my tests, so with other devices the results may vary but I think the point is the same, there are two main problems while handling a lot of images from a mobile browser:</p>
<h3>Loading rate:</h3>
<p>If I load <a href="http://jsfiddle.net/sandro_paganotti/GMs4d/embedded/result/" target="_blank">this simple javascript code</a> in my IPad mobile safari just crash, this is because (imho) the device is not able to handle such a big image loading rate and goes into some form of buffer overflow.</p>
<p><iframe style="width: 100%; height: 300px;" src="http://jsfiddle.net/sandro_paganotti/GMs4d/embedded/js" frameborder="0" width="320" height="240"></iframe></p>
<h3>Image quantity:</h3>
<p>Using the same image (notice how in the previous example I&#8217;ve appended a random number after each image URL in order to force its download) I was able to hit another limit, the maximum number of images a mobile device can display simultaneously, <a href="http://jsfiddle.net/sandro_paganotti/brj6m/2/embedded/result/" target="_blank">this code</a> which tries to print 500 images made my mobile browser freeze:</p>
<p><iframe style="width: 100%; height: 300px;" src="http://jsfiddle.net/sandro_paganotti/brj6m/2/embedded/js" frameborder="0" width="320" height="240"></iframe></p>
<h3>A workaround:</h3>
<p>I&#8217;ve managed to load and show thousands of images using canvas, in the following example each image is loaded, printed on canvas and the discarded, also the number of concurrent loads is limited to avoid browser crash, <a href="http://jsfiddle.net/sandro_paganotti/rrdFt/4/embedded/result/" target="_blank">this example</a> uses 10000 images but I think higher image quantities can be easily reached:</p>
<p><iframe style="width: 100%; height: 300px;" src="http://jsfiddle.net/sandro_paganotti/rrdFt/4/embedded/js,result" frameborder="0" width="320" height="240"></iframe></p>
<h3>Some refinements:</h3>
<p>It seems that mobile Safari cannot handle canvas bigger than a certain value (<a href="http://jsfiddle.net/sandro_paganotti/rrdFt/5/embedded/result/" target="_blank">try this</a>), to handle this problem one solution could be using the &#8216;<a href="http://www.w3.org/TR/html5/the-canvas-element.html#dom-canvas-todataurl" target="_blank">toDataUrl</a>&#8216; method when the canvas is full of pics in order to extract a screenshot. Then this screnneshot can be added to the page before the canvas so the canvas can be cleaned and reused for the upcoming pics.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2011/11/27/handling-thousands-of-pics-from-a-mobile-device/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Augmented Reality: fuzzy results</title>
		<link>http://sandropaganotti.com/2011/05/12/html5-augmented-reality-fuzzy-results/</link>
		<comments>http://sandropaganotti.com/2011/05/12/html5-augmented-reality-fuzzy-results/#comments</comments>
		<pubDate>Thu, 12 May 2011 21:34:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Augmented Reality]]></category>
		<category><![CDATA[DeviceOrientationAPI]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=491</guid>
		<description><![CDATA[I spent a few hours trying to figure out how to deal with the brand new deviceorientation API in order to obtain a nice Augmented Reality effect. First I searched on how to convert Euler Angles to Cartesian Coordinates and I found a nice article about that, then I downloaded the very nice Sylvester library [...]]]></description>
			<content:encoded><![CDATA[<p>I spent a few hours trying to figure out how to deal with the brand new <a href="http://dev.w3.org/geo/api/spec-source-orientation.html">deviceorientation API</a> in order to obtain a nice Augmented Reality effect. First I searched on how to convert Euler Angles to Cartesian Coordinates and I found a <a href="http://www.euclideanspace.com/maths/geometry/rotations/euler/index.htm">nice article about that</a>, then I downloaded the very nice <a href="http://sylvester.jcoglan.com/">Sylvester</a> library which lets you compute matrix operations in Javascript.</p>
<p><span id="more-491"></span></p>
<p>Then I write this code:</p>
<pre><code class="javascript">
Demo1 = function(){
  var demo1 = {};

  demo1.generatePoints = function(numero,dimensioni_box){
    var points = [];
    for(var i=0;i < numero; i++){
      var x0 = Math.floor((Math.random()-0.5)*(dimensioni_box)),
          y0 = Math.floor((Math.random()-0.5)*(dimensioni_box)),
          z0 = Math.floor((Math.random()-0.5)*(dimensioni_box)),
          x1 = x0 + 5;
          y1 = x1 + 5;
          z1 = z0;

      points.push(
        [$M([[x0],[y0],[z0]]), $M([[x1],[y1],[z1]])]
      );
    }
    return points;
  }

  demo1.init = function(evento){
    // #drawboard is a canvas element
    demo1.canvas = document.querySelector('#drawboard');
    demo1.canvas.width  = 320;
    demo1.canvas.height = 480;
    demo1.context = demo1.canvas.getContext('2d');
    demo1.points =  demo1.generatePoints(200, 100);
  };

  demo1.resetCanvas = function(){
     demo1.context.fillStyle = '#FFFFFF';
     demo1.context.fillRect(0,0, demo1.canvas.width, demo1.canvas.height);
     demo1.context.fillStyle = '#000000';
  }

  demo1.cambioOrientamento = function(evento){
    demo1.resetCanvas();

    var heading  = ((evento.alpha > 180 ? evento.alpha - 360 : evento.alpha) * Math.PI) / 180.0;
    var attitude = (evento.beta  *  Math.PI)     / 180.0;
    var bank     = (evento.gamma * (Math.PI/2.0)) / 90.0;

    var ch = Math.cos(heading),     sh = Math.sin(heading),
        ca = Math.cos(attitude),    sa = Math.sin(attitude),
        cb = Math.cos(bank),        sb = Math.sin(bank);

    var rotation_matrix = $M([
          [ch*ca  , -ch*sa*cb + sh*sb , ch*sa*sb + sh*cb    ],
          [sa      , ca*cb             , -ca*sb             ],
          [-sh*ca , sh*sa*cb + ch*sb  , -sh*sa*sb + ch*cb   ]
    ]);

    for(var i=0; i < demo1.points.length; i++){
      var pr  = rotation_matrix.x(demo1.points[i][0]);
      var x   = 160 + ((640*pr.e(1,1)) / (pr.e(3,1)));
          y   = 240 - ((640*pr.e(2,1)) / (pr.e(3,1)));
      demo1.context.fillRect(x,y,10,10);
    }
  };
  return demo1;
}();

window.addEventListener('load',Demo1.init,false);
window.addEventListener('deviceorientation',Demo1.cambioOrientamento,false);
</code></pre>
<p>If you have a device which supports the deviceorientation API (eg: iPhone4) you can test the running example here: <a href="http://sandropaganotti.com/wp-content/goodies/mobile/demo1.html">http://sandropaganotti.com/wp-content/goodies/mobile/demo1.html</a> as you might notice is still far from perfect but at the moment I've no time to refine it and so I have to leave it 'as is' ( still somehow nice IMHO ).</p>
<p>If someone got a clues on this please e-mail me at: &#115;&#097;&#110;&#100;&#114;&#111;&#046;&#112;&#097;&#103;&#097;&#110;&#111;&#116;&#116;&#105;&#064;&#103;&#109;&#097;&#105;&#108;&#046;&#099;&#111;&#109;</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2011/05/12/html5-augmented-reality-fuzzy-results/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I&#8217;ve just checked in at WC2010 Johannesburg Stadium from home</title>
		<link>http://sandropaganotti.com/2010/06/12/foursquare-easy-hacking/</link>
		<comments>http://sandropaganotti.com/2010/06/12/foursquare-easy-hacking/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 23:05:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[foursquare]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=393</guid>
		<description><![CDATA[Thanks to Uncle Pear suggestion I realized that you can easily check-in in every Foursquare venue simply invoking its id using the API, to try this behavior I checked in at Johannesburg  WC2010 stadium from my home in Italy. Here&#8217;s the simple snippet of code you can use (from a linux shell): curl -u sandro.paganotti@gmail.com:my_password [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to <a href="http://unclepear.com/" target="_blank">Uncle Pear</a> suggestion I realized that you can easily check-in in every Foursquare venue simply invoking its id using the API, to try this behavior <a href="http://foursquare.com/user/-1098756" target="_blank">I checked in at Johannesburg  WC2010 stadium</a> from my home in Italy.</p>
<p><span id="more-393"></span> Here&#8217;s the simple snippet of code you can use (from a linux shell):</p>
<pre><code>curl -u sandro.paganotti@gmail.com:my_password -d "vid=4762107" http://api.foursquare.com/v1/checkin
</code></pre>
<p><a href="http://groups.google.com/group/foursquare-api/web/api-documentation" target="_blank">Foursquare api</a> are really easy to use and lets you invoke up to 200 times each method each hour, so a quite simple exercise can be write a simple program that automatically check-in a selected account in a given array of locations:</p>
<pre><code class="ruby">
require 'rubygems'
require 'restclient'
require 'nokogiri'

counter = -1
debug   = true

travel = [
            # minutes to wait, venue to check-in
            [5 ,4762107],
            [10,2335319]
         ]

RestClient.add_before_execution_proc do |req, params|
    req.basic_auth 'sandro.paganotti@gmail.com', 'my_password'
end

loop do
    time, venue_id = travel[counter = ((counter + 1) % travel.size)]
    puts "sleeping #{time} minutes.." if debug
    sleep time * 60
    response = RestClient.post "http://api.foursquare.com/v1/checkin", :vid=&gt;venue_id
    puts  ['checkin','message'].inject(Nokogiri::XML(response.body)) { |s,r| s.send(:at, r) }.inner_text
end
</code></pre>
<p>By invoking this code an infinite loop will check-in the provided account into each of the given venues waiting a configurable amount of time between each of them.</p>
<p>Here&#8217;s the result:</p>
<pre><code>sandropaganotti$ ruby venue.rb
sleeping 5 minutes..
OK! We've got you @ WC2010 Soccer City Stadium. This is your 2nd checkin here!
sleeping 10 minutes..
OK! We've got you @ Service Station Cafe. This is your 1st checkin here!
sleeping 5 minutes..
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2010/06/12/foursquare-easy-hacking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A semantic experiment for separate good from bad.</title>
		<link>http://sandropaganotti.com/2010/05/04/a-semantic-experiment-for-separate-good-from-bad/</link>
		<comments>http://sandropaganotti.com/2010/05/04/a-semantic-experiment-for-separate-good-from-bad/#comments</comments>
		<pubDate>Tue, 04 May 2010 11:37:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Semantic Relations]]></category>
		<category><![CDATA[wordnet]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=379</guid>
		<description><![CDATA[Yesterday was sunday and I came up with a fascinating idea: what happens if I use wordnet to measure the distance between two words ? By assigning weights to all the relation types and by navigate this relations graph I thought to be able to measure the distance between a word and the others in [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday was sunday and I came up with a fascinating idea: what happens if I use <a href="http://github.com/roja/words">wordnet</a> to measure the distance between two words ? By assigning  weights to all the relation types and by navigate this relations graph I  thought to be able to measure the distance between a word and the others  in terms of the minimum sum of weights of the edges between each pair made of the chosen word and another.</p>
<p><span id="more-379"></span><br />
So I tried to assign weights using the relation type as discriminator, to make an example take the word &#8216;sword&#8217; and its relations:</p>
<pre><code>
related-term        relation type           assigned weight
weapon:             hypernym                5
backsword:          hyponym                 2
blade:              part_meronym            3
broadsword:         hyponym                 2
cavalry sword:      hyponym                 2
cutlas:             hyponym                 2
Excalibur:          instance_hyponym        2
falchion:           hyponym                 2
fencing sword:      hyponym                 2
foible:             part_meronym            3
forte:              part_meronym            3
haft:               part_meronym            3
hilt:               part_meronym            3
rapier:             hyponym                 2
point:              part_meronym            3
</code></pre>
<p>The weight I choose for each of the relation types tried to follow the statement<br />
&#8216;The more the words are related the less greater the number is&#8217;; so weapon is less<br />
related to sword than broadsword because the first express a concept broader than sword<br />
(also a nuclear bomb is a weapon); the second instead detail the word &#8216;sword&#8217; and<br />
make true the statement &#8216;A broadsword is always a sword&#8217; so it&#8217;s more related to the<br />
chosen word.</p>
<p>By following this general rule I associated a weight to each of the most common  relation types and wrote down a few lines of code in order to compute weights by navigate the relation graph:</p>
<pre>
<code class="ruby">
def compute_distances(weights = :default, max_depth_allowed = 6)

  # retrieve the list of the weights associated to each relation type
  # (its just an hash {:relation_type => weight})
  weights = CONFIG_FILE['distance']["#{weights}"]
  data = Words::Wordnet.new

  # get a list of sysnsets as a starting point (eg: red, crimson)
  synsets_to_analyze = self.synsets.map{|s| [s.synset_id,0,0]}
  synsets_to_store   = []

  # process the first element of the list
  # until the sysets_to_analyze stack is empty
  while(sys = synsets_to_analyze.shift) do
    sys_id,dis,dep = *sys; next if dep >= max_depth_allowed
    sys = Words::Synset.new(sys_id,data.wordnet_connection,nil) rescue next;

    # save the current sysnset words into an output array
    sys.words.each {|w|  synsets_to_store.unshift([sys_id,w,dis])}

    # put each of the sysnset related to this into the stack unless they
    # are already present
    sys.relations.each do |r|
      synsets_to_analyze.unshift(
        [r.destination.synset_id, dis + weights["#{r.relation_type}"],dep + 1]
      ) if r.is_semantic? and
           !synsets_to_store.find{|s| s.first == r.destination.synset_id}
    end
  end

  # now in sysnsets_to_store you have an array of the words each of them
  # with the weight that separe it from the starting synsets.
 # (now I store them on a db, but is just because the context is the same as the Abacus gem)
  synsets_to_store.each do |s|
    a_id = ArticleKey.find_by_the_key(s[1]).id rescue next
    self.distances.find_or_create_by_article_key_id( a_id, :distance => s[2])
  end

end
</code>
</pre>
<p>Here some of the results for &#8216;sword&#8217; with depth = 3:</p>
<pre><code>
sword:                           0
brand:                           0
steel:                           0
broadsword:                      2
rapier:                          2
tuck:                            2
backsword:                       2
fencing sword:                   2
falchion:                        2
Excalibur:                       2
cutlas:                          2
sabre:                           2
cavalry sword:                   2
saber:                           2
cutlass:                         2
foible:                          3
blade:                           3
hilt:                            3
forte:                           3
tip:                             3
peak:                            3
point:                           3
helve:                           3
haft:                            3
claymore:                        4
scimitar:                        4
saber:                           4
sabre:                           4
foil:                            4
epee:                            4
arm:                             5
basket hilt:                     5
head:                            5
weapon system:                   5
knife blade:                     5
weapon:                          5
widow's peak:                    5
cusp:                            5
razorblade:                      5
cutting edge:                    6
pommel:                          6
knob:                            6
knife edge:                      6
fire ship:                       7
shaft:                           7
slasher:                         7
missile:                         7
Greek fire:                      7
missile:                         7
weapon of mass destruction:      7
light arm:                       7
WMD:                             7
gun:                             7
flamethrower:                    7
pike:                            7
brass knucks:                    7
knucks:                          7
brass knuckles:                  7
knuckles:                        7
W:                               7
tomahawk:                        7
hatchet:                         7
lance:                           7
knuckle duster:                  7
bow and arrow:                   7
projectile:                      7
sling:                           7
bow:                             7
stun baton:                      7
spear:                           7
stun gun:                        7
convexity:                       8
cutting implement:               8
convex shape:                    8
portion:                         8
part:                            8
handle:                          8
grip:                            8
hold:                            8
handgrip:                        8
reap hook:                       9
knife:                           9
sticker:                         9
dagger:                          9
axe:                             9
file:                            9
awl:                             9
lawn mower:                      9
mower:                           9
scissors:                        9
ax:                              9
sickle:                          9
cone shape:                      9
conoid:                          9
cone:                            9
reaping hook:                    9
pencil:                          9
arrowhead:                       9
knife:                           9
pair of scissors:                9
spatula:                         9
spatula:                         9
alpenstock:                      9
instrument:                      10
weapons system:                  11
implements of war:               11
arms:                            11
munition:                        11
weaponry:                        11
</code></pre>
<p>Now, as you may notice, there still a lot of tuning to do; for example it is pretty strange that &#8216;weapon of mass destruction&#8217; is more semantically related to &#8216;sword&#8217; than &#8216;dagger&#8217; <img src='http://sandropaganotti.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . </p>
<p>Anyway I&#8217;m pretty pleased of the results of this small experiment thus I&#8217;m still far from my initial idea: calculate the weight of each word of the dictionary in relation to &#8216;good&#8217; and &#8216;bad&#8217; and use these weights to estimate the &#8216;mood&#8217; of some common trends in twitter.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2010/05/04/a-semantic-experiment-for-separate-good-from-bad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Game of Life, introducing gray</title>
		<link>http://sandropaganotti.com/2010/04/02/game-of-life-introducing-gray/</link>
		<comments>http://sandropaganotti.com/2010/04/02/game-of-life-introducing-gray/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 22:13:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[cellular automata]]></category>
		<category><![CDATA[game of life]]></category>
		<category><![CDATA[Processing]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=368</guid>
		<description><![CDATA[During the last hour I modified my previous version of Game Of life trying to reproduce the same behavior using an analogic discriminator. Instead of counting the number of neighbours I elaborate their medium color and use this value to decide the next rgb combination of the cell. In the following snippet the two versions [...]]]></description>
			<content:encoded><![CDATA[<p>During the last hour I modified my previous version of Game Of life trying to reproduce the same behavior using an analogic discriminator. Instead of counting the number of neighbours I elaborate their medium color and use this value to decide the next rgb combination of the cell. </p>
<p><span id="more-368"></span>In the following snippet the two versions (classic and analogic) are compared:</p>
<pre><code class="javascript">
//  Classic version:
  void compute(){
    int black_neighbours = 0;
    for(int z=0; z < neighbours.length; z++)
      if(neighbours[z].rgb == black)
        black_neighbours ++;  

    switch(black_neighbours){
      case 0:
      case 1:
      case 4:
      case 5:
      case 6:
      case 7:
      case 8:
        to_color(white);
        break;
      case 2:
        to_color(rgb);
        break;
      case 3:
        to_color(black);
        break;
    }
  } 

// Analogic version
  void compute(){
    int[] medium_color = new int[] {0,0,0};
    for(int z=0; z < neighbours.length; z++)
      for(int c=0; c < 3; c++)
        medium_color[c] = medium_color[c] + neighbours[z].rgb[c];

    int medium_tone = 0;
    for(int c=0; c < 3; c++){
      medium_color[c] = medium_color[c] / neighbours.length;
      medium_tone = medium_tone + medium_color[c];
    }  

    medium_tone = medium_tone / 3;

    if (medium_tone > 191 || medium_tone < 128 ){
      to_color(white);
    }else if(medium_tone > 159 ){
      to_color(rgb);
    }else{
      to_color(black);
    }
  }
</code></pre>
<p>Next I went a step further using &#8216;medium color&#8217; when the classic rules asked insted to keep the previous cell color. This lead to a general acceleration to white because the medium neighbours color is always more bright than pure black, to balance this behavior I expanded the range of medium_tones which results in black. Here&#8217;s the tuned code:</p>
<pre><code class="javascript">
  void compute(){
    int[] medium_color = new int[] {0,0,0};
    for(int z=0; z < neighbours.length; z++)
      for(int c=0; c < 3; c++)
        medium_color[c] = medium_color[c] + neighbours[z].rgb[c];

    int medium_tone = 0;
    for(int c=0; c < 3; c++){
      medium_color[c] = medium_color[c] / neighbours.length;
      medium_tone = medium_tone + medium_color[c];
    }  

    medium_tone = medium_tone / 3;

    if (medium_tone > 191 || medium_tone < 80 ){
      to_color(white);
    }else if(medium_tone > 159 ){
      to_color(medium_color);
    }else{
      to_color(black);
    }
  }
</code></pre>
<p>Now <a href="http://www.youtube.com/watch?v=QheZEcI5bv4">a short video</a> of this new behavior:</p>
<p><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/QheZEcI5bv4&#038;hl=it_IT&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/QheZEcI5bv4&#038;hl=it_IT&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2010/04/02/game-of-life-introducing-gray/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A processing.org Game of Life</title>
		<link>http://sandropaganotti.com/2010/03/20/a-processing-org-game-of-life/</link>
		<comments>http://sandropaganotti.com/2010/03/20/a-processing-org-game-of-life/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 17:13:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[game of life]]></category>
		<category><![CDATA[Jhon Conway]]></category>
		<category><![CDATA[Processing]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=325</guid>
		<description><![CDATA[Everybody knows the popular Game of Life created by Jhon Conway and becamed famous after been published by Martin Gardner on Scientific American in 1970. It is essentially a cellular automation algorithm with a very few simple rules that determinate how to grow a pool of one-pixel-shaped organisms layed upon a 2D matrix. Here&#8217;s the [...]]]></description>
			<content:encoded><![CDATA[<p>Everybody knows the popular <a href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life" target="_blank">Game of Life</a> created by <a href="http://en.wikipedia.org/wiki/John_Horton_Conway" target="_blank">Jhon Conway</a> and becamed famous after been published by <a href="http://en.wikipedia.org/wiki/Martin_Gardner" target="_blank">Martin Gardner</a> on <a href="http://ddi.cs.uni-potsdam.de/HyFISCH/Produzieren/lis_projekt/proj_gamelife/ConwayScientificAmerican.htm" target="_blank">Scientific American</a> in 1970. It is essentially a cellular automation algorithm with a very few simple rules that determinate how to grow a pool of one-pixel-shaped organisms layed upon a 2D matrix.</p>
<p><span id="more-325"></span>Here&#8217;s the rules:</p>
<ul>
<li>if the organism has more than 3 or fewer than 2 neighbours it dies;</li>
<li>if the organism has 2 or 3 neighbours it survives;</li>
<li>if a white cell in the matrix is sorrounded by exactly 3 neighbours it became a living organism.</li>
</ul>
<p>I&#8217;ve implemented this Game Of Life using Processing language and trying to push all of the game logic within the organism class in order to really simulate a cellular behavior, here&#8217;s the class:</p>
<pre><code class="javascript">class Spot{
  int[]   rgb, rgb_next;
  int     x,y;
  Spot[]  neighbours;

  Spot(int gx, int gy, int[] c){
    rgb      = c;
    rgb_next = new int[3];
    x       = gx;
    y       = gy;
  }

  void set_neighbors(Spot[][] grid){
    int xp = (x+1 == grid.length ? 0 : x+1);
    int xm = (x-1 == -1 ? grid.length - 1 : x-1);
    int yp = (y+1 == grid[0].length ? 0 : y+1);
    int ym = (y-1 == -1 ? grid[0].length - 1 : y-1);

    neighbours = new Spot[] {  grid[xm][ym], grid[xm][y ], grid[xm][yp],
                               grid[x ][ym],               grid[x ][yp],
                               grid[xp][ym], grid[xp][y ], grid[xp][yp]
                            };
  }

  void compute(){
    int black_neighbours = 0;
    for(int z=0; z &lt; neighbours.length; z++)
      if(neighbours[z].rgb == black)
        black_neighbours ++;  

    switch(black_neighbours){
      case 0:
      case 1:
      case 4:
      case 5:
      case 6:
      case 7:
      case 8:
        to_color(white);
        break;
      case 2:
        to_color(rgb);
        break;
      case 3:
        to_color(black);
        break;
    }
  } 

  void advance(){
    rgb = rgb_next;
    rgb_next = new int[3];
  }

  void draw(int bw,int bh){
     fill(rgb[0],rgb[1],rgb[2]);
     rect(x*bw,y*bh,bw,bh);
  }

  void to_color(int[] c){ rgb_next = c; }
}
</code></pre>
<p>There are three methods that worth a look:</p>
<ul>
<li><strong>set_neighbors</strong>:<br />
which determinates the sourronding neighbors (as the method name states) by creating an array of pointer to the closest organisms using the matrix passed as parameter as a reference. The first four lines are needed in order to eliminate the boundaries by linking each edge of the matrix to the opposite one.</li>
<li><strong>compute</strong>:<br />
which implements the real logic of the Game, it is divided into two steps, the first part calculates the number of alive neighbors sorrounding the organism and the second one applies the rules stated above.</li>
<li><strong>advance</strong>:<br />
due the fact that all of the organisms need to be processed before each of them can switch to the new state, the Spot class record the result of the &#8216;compute&#8217; method inside a different variable and then, when advance is invoked, it moves this result to the &#8216;live&#8217; variable.</li>
</ul>
<p>Here&#8217;s a short video of my script in action, the source code is, as usually, <a href="http://github.com/sandropaganotti/processing-game-of-life" target="_blank">available on my github account</a>:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="660" height="405" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/LcHvyVpdnEk&amp;hl=it_IT&amp;fs=1&amp;rel=0&amp;border=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="660" height="405" src="http://www.youtube.com/v/LcHvyVpdnEk&amp;hl=it_IT&amp;fs=1&amp;rel=0&amp;border=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2010/03/20/a-processing-org-game-of-life/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Isocrono e Google Map API</title>
		<link>http://sandropaganotti.com/2010/01/18/isocrono-e-google-map-api/</link>
		<comments>http://sandropaganotti.com/2010/01/18/isocrono-e-google-map-api/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 22:23:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[Google Map]]></category>
		<category><![CDATA[isocrono]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=287</guid>
		<description><![CDATA[Un isocrono non è nient&#8217;altro che una curva che unisce su di una mappai punti che distano uno stesso intervallo temporale (a piedi, o con un mezzo di trasporto) da un punto dato. In questo articolo, che funge da approfondimento della homepage del progetto, vorrei entrare un pò nel merito del piccolo script da utilizzare [...]]]></description>
			<content:encoded><![CDATA[<p>Un <a href="http://it.wikipedia.org/wiki/Isoclina#Scienze_Sociali" target="_blank">isocrono</a> non è nient&#8217;altro che una curva che unisce su di una mappai punti che distano uno stesso intervallo temporale (a piedi, o con un mezzo di trasporto) da un punto dato. In questo articolo, che funge da approfondimento <a href="http://sandropaganotti.com/generate-an-isochrone-map-using-google-maps-api/" target="_blank">della homepage del progetto</a>, vorrei entrare un pò nel merito del piccolo script da utilizzare per calcolare un&#8217;approssimazione di isocrono usando le API di Google Maps.</p>
<p><span id="more-287"></span>Lo script si compone di tre parti, una (classica) funzione di inizializzazione,  una funzione che effettua il <a href="http://code.google.com/intl/it/apis/maps/documentation/services.html#Geocoding" target="_blank">GeoCoding</a> della località della quale si vuole calcolare l&#8217;isocrono e la funzione chiave, che cicla su ognuno dei raggi (il numero di raggi è impostabile, di default 10) della circonferenza costruita intorno a tale località e per ogni raggio si muove verso l&#8217;esterno misurando la distanza in minuti dal centro, quando trova un punto che sorpassa il tempo limite dato lo script mette un marker.</p>
<p>Lo script passa al raggio successivo quando rileva una misurazione che supera del 50% il tempo limite dato.</p>
<pre><code class="javascript">
    function crawlpoint(px,py,mins){
        var point      = new GPoint(px,py);
        var destpoint  = new GPoint(px + x,py + y);   

        directions.loadFromWaypoints(new Array(point.y + "," + point.x ,destpoint.y + "," + destpoint.x),{preserveViewport:true});
        x = x + (inc_x * Math.sin(start_s));
        y = y + (inc_y * Math.cos(start_s));
        m = m + 1;

        if (directions.getNumRoutes() &gt; 0){
            document.getElementById('txt1').value = 'y' + document.getElementById('txt1').value
            var curr_meas = directions.getDuration().seconds/60;
            if (prev_meas &lt;= mins &amp;&amp; curr_meas &gt; mins ){
                map.addOverlay(new GMarker(prev_dest,{title:'Distance: ' + directions.getDuration().html}));
                found     = 1;
            }else{
                prev_dest = destpoint;
                prev_meas = curr_meas;
            }

            if(curr_meas &gt; (mins + (mins * 0.4)) || (m &gt; 20 &amp;&amp; found ==1) || m &gt; 50){
                points.push(new GLatLng(prev_dest.y, prev_dest.x));
                start_s = start_s + slice;
                x = inc_x;
                y = inc_y;
                m = 0;
                found = 0;
                prev_meas = 0;
                curr_meas = 0;
                prev_dest = point;
                directions.clear();

                if(start_s &gt;= (2*Math.PI)){
                    start_s = 0;
                    $('#loader').hide();
                    clearInterval(intval);
                }
            }

        }else{
            document.getElementById('txt1').value = 'n' + document.getElementById('txt1').value
        }
    }
</code></pre>
<p>Possiamo spezzare la funzione in tre punti distinti, la prima parte invoca le <a href="http://code.google.com/intl/it/apis/maps/documentation/services.html#Directions" target="_blank">Directions API</a>, per calcolare la distanza tra il centro e un punto (destpoint) posizionato sul raggio attivo (il cui angolo è memorizzato in start_s, inizialmente a 0) ad una distanza espressa da due variabili x e y. Una volta calcolato il percorso x e y vengono incrementate in modo che al prossimo giro puntino ad un punto sullo stesso raggio un poco più avanti.</p>
<p>La seconda parte aggiunge un marker se tra la durata del percorso attuale supera per la prima volta il limite di tempo inserito.</p>
<p>La terza parte resetta tutti i contatori e avanza al raggio successivo se la misurazione temporale corrente eccede del 50% il tempo limite inserito o se sono state effettuate più di venti misurazioni con l&#8217;identificazione di un marker o più di 50 misurazioni.</p>
<p>Trovate il codice nella sua interezza sul mio account di <a href="http://github.com/sandropaganotti/isochrone-with-google-map" target="_blank">github</a>, potete inoltre testare il tutto su di una <a href="http://sandropaganotti.com/wp-content/goodies/demos/isochrone/index.html" target="_blank">pagina di demo</a>.</p>
<p>PS: credo che l&#8217;algoritmo sia altamente perfezionabile, ad esempio introducendo alcuni concetti di reinforcement learning per la ricerca degli zeri della funzione T(R(p1,p2)) &#8211; t dove T(R(p1,p2)) è il tempo di percorrenza del percorso tra p1 e p2 e t è il tempo limite dell&#8217;isocrono.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2010/01/18/isocrono-e-google-map-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>QBox: uno slideshow in WebGL</title>
		<link>http://sandropaganotti.com/2010/01/05/qbox-uno-slideshow-in-webgl/</link>
		<comments>http://sandropaganotti.com/2010/01/05/qbox-uno-slideshow-in-webgl/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 15:52:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[QBox]]></category>
		<category><![CDATA[Slideshow]]></category>
		<category><![CDATA[WebGL]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=274</guid>
		<description><![CDATA[Di ritorno da un bellissimo capodanno a Nantes ho deciso di spendere ancora qualche ora sul nuovo binding tra Javascript e OpenGL ES 2.0, formalmente noto col nome di WebGL; il risultato ha preso il nome di QBox, uno slideshow che recupera un certo numero di immagini mappandole su di un cubo rotante (le immagini [...]]]></description>
			<content:encoded><![CDATA[<p>Di ritorno da un bellissimo capodanno a <a href="http://maps.google.it/maps?q=nantes&amp;oe=utf-8&amp;client=firefox-a&amp;ie=UTF8&amp;hq=&amp;hnear=Nantes,+Loira+Atlantica,+Paesi+della+Loira,+Francia&amp;gl=it&amp;ei=Cl1DS5f9O42anwPfv9X6CQ&amp;ved=0CBMQ8gEwAA&amp;t=h&amp;z=11" target="_blank">Nantes</a> ho deciso di spendere ancora qualche ora sul nuovo binding tra Javascript e OpenGL ES 2.0, formalmente noto col nome di WebGL; il risultato ha preso il nome di QBox, uno slideshow che recupera un certo numero di immagini mappandole su di un cubo rotante (le immagini possono essere anche più di quattro, c&#8217;è un meccanismo di sostituzione automatico).</p>
<p><span id="more-274"></span>Non mi dilungo oltre ne nella descrizione ne nelle procedure di installazione in quanto è tutto specificato <a href="http://sandropaganotti.com/qbox-a-webgl-photo-slideshow-for-your-website/" target="_blank">sulla homepage del progetto</a> (c&#8217;è anche un <a href="http://www.youtube.com/watch?v=5ui-XBVChmE" target="_blank">video</a> e una <a href="http://sandropaganotti.com/wp-content/goodies/demos/qbox/" target="_blank">demo live</a> se il vostro browser supporta WebGL, testato con Webkit); vorrei invece spendere questo post nello spiegare un paio di funzioni che ho scritto e che potrebbero IMHO rivelarsi utili a qualche lettore, ecco la prima:</p>
<pre><code class="javascript">function createTextureFromCanvas(ctx, canvas_imagedata) {

    var pixels = new WebGLUnsignedByteArray(canvas_imagedata.data);
    var texture = ctx.createTexture();
    ctx.bindTexture(ctx.TEXTURE_2D, texture);
    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE);
    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE);
    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.NEAREST);
    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.NEAREST);
    ctx.pixelStorei(ctx.UNPACK_ALIGNMENT, 1);
    ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, canvas_imagedata.width, canvas_imagedata.height, 0, ctx.RGBA, ctx.UNSIGNED_BYTE, pixels);
    ctx.generateMipmap(ctx.TEXTURE_2D)
    ctx.bindTexture(ctx.TEXTURE_2D, null);

    return texture;
}
</code></pre>
<p>In questa funzione si concentra il cuore dello slideshow, non tanto dal punto di vista operativo, quanto di mio personale sforzo concettuale; il principale problema che ho incontrato nello sviluppo di questo script infatti riguardava la necessità di mappare immagini di dimensioni potenzialmente diverse su di un cubo (le cui facce devono essere tutte uguali). Ecco quindi il passaggio forzato attraverso dei canvas bidimensionali di appoggio, sui quali effettuare le operazioni di resize delle immagini prima di passarle come textures sul cubo. Questi canvas sono anche serviti per gestire i margini neri che venivano a crearsi naturalmente in quanto la proporzione tra le dimensioni delle fotografie non è sempre 1:1.</p>
<p>Ma una volta ottenuto questi canvas contenenti le immagini normalizzate come procedere per metterle su di una texture ? Dopo aver seguito senza successo <a href="http://gist.github.com/215896">un gist sul tema</a> mi sono imbattuto nel salvifico esempio &#8216;<a href="https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/demos/google/procedural-texture-test/index.html" target="_blank">Texture test</a>&#8216; che contiene una funzione che disegna 4 pixel su di una texture:</p>
<pre><code class="javascript">
function createCheckerboardTexture() {
    var pixels = new WebGLUnsignedByteArray([255, 255, 255,
                                             0,   0,   0,
                                             0,   0,   0,
                                             255, 255, 255]);
    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    //  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    //  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 2, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, pixels);
    return texture;
}
</code></pre>
<p>Da qui è stato facile; al posto che specificare i singoli bit dell&#8217;immagine ho passato nella variabile pixels il contenuto dei miei canvas di appoggio e, con un paio di altre modifiche sono riuscito ad ottenere l&#8217;effetto desiderato.</p>
<p>La seconda funzione di cui vorrei far menzione è invece quella che recupera un immagine e la mappa, centrata, su di un canvas 2d, per scrivere queste righe ho utilizzato il metodo drawImage del context 2D in un modo che non conoscevo (<a href="https://developer.mozilla.org/En/Canvas_tutorial/Using_images#Scaling" target="_blank">suggeritomi da qui</a>), cioè con 5 parametri:</p>
<ul>
<li>Canvas di destinazione;</li>
<li>Posizione x e y da cui disgnare l&#8217;immagine sul canvas di destinazione;</li>
<li>Dimensioni dell&#8217;immagine sul canvas di destinazione (width e height).</li>
</ul>
<p>Ecco la funzione, in ingresso riceve l&#8217;&lt;img&gt; da adattare al canvas:</p>
<pre><code class="javascript">function initTexture(e)
{
  var textureWidth  = 500;

  if($(e).width() &gt; $(e).height()){
     var magnitude = textureWidth/$(e).width();
  } else {
     var magnitude = textureWidth/$(e).height();
  }

  var new_width  = Math.floor($(e).width()*magnitude);
  var new_height = Math.floor($(e).height()*magnitude);
  var textureCanvas     = document.createElement("canvas");
  textureCanvas.width   = textureCanvas.height = textureWidth;
  var textureContext    = textureCanvas.getContext("2d");
  textureContext.drawImage(e,Math.floor((textureWidth-new_width)/2.0),Math.floor((textureWidth-new_height)/2.0),new_width,new_height); 

  return textureCanvas;
}</code></pre>
<p>Se la cosa vi interessa sappiate che tutto il progetto è, come al solito, <a href="http://github.com/sandropaganotti/QBox--a-WebGL-photo-slideshow" target="_blank">disponibile sul mio account di github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2010/01/05/qbox-uno-slideshow-in-webgl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby e Gosu: un multiplayer a schermo condiviso</title>
		<link>http://sandropaganotti.com/2009/12/08/ruby-e-gosu-un-multiplayer-a-schermo-condiviso/</link>
		<comments>http://sandropaganotti.com/2009/12/08/ruby-e-gosu-un-multiplayer-a-schermo-condiviso/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 20:21:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Librerie]]></category>
		<category><![CDATA[Gosu]]></category>
		<category><![CDATA[multiplayer]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=246</guid>
		<description><![CDATA[Tutto è nato da una bellissima presentazione che ho seguito ormai quasi un anno fa: si parla dell&#8217;Euruko 2009 in quel di Barcellona; lo speech in oggetto si intitolava &#8216;Fun with ruby (and without r***s). Program your own games with gosu&#8216; e trattava di una libreria per lo sviluppo di giochi scritta in Ruby chiamata [...]]]></description>
			<content:encoded><![CDATA[<p>Tutto è nato da una bellissima presentazione che ho seguito ormai quasi un anno fa: si parla dell&#8217;Euruko 2009 in quel di Barcellona; lo speech in oggetto si intitolava <a href="http://app.euruko2009.org/talks/9-fun-with-ruby-and-without-r-s-program-your-own-games-with-gosu" target="_blank">&#8216;Fun with ruby (and without r***s). Program your own games with gosu</a>&#8216; e trattava di una libreria per lo sviluppo di giochi scritta in Ruby chiamata <a href="http://code.google.com/p/gosu/" target="_blank">Gosu</a>.</p>
<p><span id="more-246"></span></p>
<p>Per tutta una serie di impegni/dimenticanze/ritardi/&#8230; non sono più riuscito ad avvicinarmi a Gosu anche se le sue potenzialità sembravano quantomeno interessanti; oggi approfittando del piovoso ponte lavorativo  mi sono cimentato nella stesura di  una piccolissima applicazione (non la si può nemmeno chiamare gioco) che gestisca, su un unico schermo, una moltitudine di client associando ad ognuno di essi uno sprite e consentendogli di pilotarlo con dei semplici comandi.</p>
<p>In questa proof-of-concept ogni client può connettersi alla porta 8888 del server e dialogando in TCP può pilotare il proprio areo da caccia sullo schermo dell&#8217;applicazione; la sintassi del messaggio è semplicissima:</p>
<pre><code>codice_client|comando</code></pre>
<p>I comandi supportati sono, al momento, solo &#8216;left&#8217;, &#8216;right&#8217;, &#8216;close&#8217; e &#8216;welcome&#8217; ma ben presto introdurrò almeno &#8216;shot&#8217; per consentire all&#8217;areo di difendersi dai (futuri) nemici. L&#8217;intera implementazione è come al solito presente sul mio <a href="http://github.com/sandropaganotti/Gosu-Multiplayer-Shared-Screen" target="_blank">account di github</a>; a seguire invece uno screenshot dell&#8217;applicazione con due client connessi:</p>
<div id="attachment_248" class="wp-caption aligncenter" style="width: 650px"><img class="size-full wp-image-248" title="Multiplayer, shared screen" src="http://sandropaganotti.com/wp-content/uploads/2009/12/ishot-55.png" alt="Ogni aereo è controllato da un client diverso" width="640" height="502" /><p class="wp-caption-text">Ogni aereo è controllato da un client diverso</p></div>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2009/12/08/ruby-e-gosu-un-multiplayer-a-schermo-condiviso/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Matematica e carte da Briscola</title>
		<link>http://sandropaganotti.com/2009/10/10/matematica-e-carte-da-briscola/</link>
		<comments>http://sandropaganotti.com/2009/10/10/matematica-e-carte-da-briscola/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 08:20:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Approfondimenti]]></category>
		<category><![CDATA[Carte da Briscola]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=214</guid>
		<description><![CDATA[Ho trascorso la scorsa settimana in Kenya, durante il soggiorno ho avuto modo di assistere ad un interessante gioco eseguito da Salvo, uno degli animatori del villaggio. Le istruzioni per ripeterlo sono queste: Mescolate un mazzo di carte da Briscola; Tenete il mazzo in mano in modo che le carte siano a faccia in su; [...]]]></description>
			<content:encoded><![CDATA[<p>Ho trascorso <a title="Alcune immagini della mia vacanza in Kenya" href="http://picasaweb.google.com/sandro.paganotti/Kenia2009#" target="_blank">la scorsa settimana in Kenya</a>, durante il soggiorno ho avuto modo di assistere ad un interessante gioco eseguito da Salvo, uno degli animatori del villaggio.</p>
<p><span id="more-214"></span>Le istruzioni per ripeterlo sono queste:</p>
<ol>
<li>Mescolate un mazzo di <a title="Alcune informazioni sulla briscola" href="http://en.wikipedia.org/wiki/Briscola" target="_blank">carte da Briscola;</a></li>
<li>Tenete il mazzo in mano in modo che le carte siano a faccia in su;</li>
<li>Estraete la prima carta dal mazzo, memorizzatene il valore ( da 1 a 10 ) e appoggiatela a faccia coperta sul tavolo;</li>
<li>Estraete le successive 10-k carte ed impilatele, sempre a faccia coperta, sulla precedente ( dove k è il valore memorizzato al punto 3 );</li>
<li>Ripetete i punti 3 e 4 con le restanti carte del mazzo. Se non doveste trovare sufficienti carte per completare l&#8217;ultima pila disponete le carte di questa pila a faccia in giù sul tavolo separandole una dall&#8217;altra ( possiamo chiamarle &#8216;carte del resto&#8217;).</li>
</ol>
<p>Ok, se avete operato nel modo corretto la somma delle carte capofila di ogni mazzetto (quelle del punto 3) dovrebbe corrispondere alla seguente formula:</p>
<pre><code>(numero di mazzetti * 11) + carte del resto - 40
</code></pre>
<p>Cerchiamo di capire come si possa arrivare ad un simile risultato:</p>
<p>Cominciamo affermando che ogni mazzetto di carte è composto da 11 &#8211; k carte dove k è il valore della carta a capofila quindi, ad esempio, se la carta capofila è un due il mazzetto conterrà 9 carte: il due e le otto successive, con questa osservazione è possibile stendere una prima versione della formula:</p>
<p><img class="aligncenter size-full wp-image-218" title="chart" src="http://sandropaganotti.com/wp-content/uploads/2009/10/chart3.png" alt="chart" width="162" height="49" /></p>
<p>Dove con n indichiamo il numero di mazzetti, con <img class="size-full wp-image-219 alignnone" title="chart" src="http://sandropaganotti.com/wp-content/uploads/2009/10/chart4.png" alt="chart" width="19" height="18" /> il valore della carta capofila dell&#8217;x-esimo mazzetto e con r il numero della &#8216;carte del resto&#8217;. Ora non ci resta che isolare il più possibile k, per fare questo non dobbiamo fare altro che applicare alcune trasformazioni alla formula:</p>
<p><img class="aligncenter size-full wp-image-220" title="chart0" src="http://sandropaganotti.com/wp-content/uploads/2009/10/chart0.png" alt="chart0" width="185" height="49" /></p>
<p><img class="aligncenter size-full wp-image-221" title="chart1" src="http://sandropaganotti.com/wp-content/uploads/2009/10/chart11.png" alt="chart1" width="186" height="49" /></p>
<p><img class="aligncenter size-full wp-image-222" title="chart2" src="http://sandropaganotti.com/wp-content/uploads/2009/10/chart21.png" alt="chart2" width="162" height="49" /></p>
<p>Done, con questi semplici passaggi siamo riusciti a ricostruire il funzionamento di un piccolo gioco che è riuscito ad impressionarmi ed incuriosirmi.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2009/10/10/matematica-e-carte-da-briscola/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

