<?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, 25 Jul 2010 12:45:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<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>
		<item>
		<title>L-System con Processing</title>
		<link>http://sandropaganotti.com/2009/09/28/l-system-con-processing/</link>
		<comments>http://sandropaganotti.com/2009/09/28/l-system-con-processing/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 00:01:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Engine]]></category>
		<category><![CDATA[L-System]]></category>
		<category><![CDATA[L0D-System]]></category>
		<category><![CDATA[Processing.org]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=193</guid>
		<description><![CDATA[Utilizzando un L-System è possibile descrivere un pattern evolutivo semplicemente specificando alcune regole di sostituzione; un esempio di queste grammatiche potrebbe essere riassunto nei seguenti predicati: Se incontro un carattere &#8216;A&#8217; lo devo trasformare in &#8216;AB&#8217;; Se incontro un carattere &#8216;B&#8217; lo devo trasformare in &#8216;A&#8217;. Ipotizziamo ora di partire da una stringa &#8216;A&#8217;, alla [...]]]></description>
			<content:encoded><![CDATA[<p>Utilizzando un <a href="http://en.wikipedia.org/wiki/L-system" target="_blank">L-System</a> è possibile descrivere un pattern evolutivo semplicemente specificando alcune regole di sostituzione; un esempio di queste grammatiche potrebbe essere riassunto nei seguenti predicati:</p>
<p><span id="more-193"></span></p>
<ul>
<li>Se incontro un carattere &#8216;A&#8217; lo devo trasformare in &#8216;AB&#8217;;</li>
<li>Se incontro un carattere &#8216;B&#8217; lo devo trasformare in &#8216;A&#8217;.</li>
</ul>
<p>Ipotizziamo ora di partire da una stringa &#8216;A&#8217;, alla prima iterazione otterremmo &#8216;AB&#8217;, poi &#8216;ABA&#8217;, quindi &#8216;ABAAB&#8217; , &#8216;ABAABABA&#8217; e via dicendo. Gli L-System sono molto interessanti in quanto ci consentono, con grammatiche un pò più complesse di quella appena osservata, di simulare la crescita di molti organismi appartenenti al mondo vegetale.</p>
<p>Per fare questo si associa ad ogni simbolo della grammatica un preciso significato (ad esempio potremmo dire che &#8216;A&#8217; sta a significare &#8216;disegna una linea retta&#8217; mentre &#8216;B&#8217; potrebbe voler dire &#8216;ruota il cursore di 90 gradi&#8217;) e, dopo un certo numero di iterazioni, si scorre la stringa generata applicando ad ogni simbolo il significato pattuito.</p>
<p>Facciamo un esempio, supponiamo di voler sperimentare il famoso &#8216;<a href="http://en.wikipedia.org/wiki/Cantor_set" target="_blank">Cantor Set</a>&#8216;, un prototipo di frattale che evidenzia un insieme di punti su di un segmento; ecco la definizione formale dell&#8217;L-System:</p>
<pre><code>
    simboli : A B
    assioma : A
    regole : A → ABA, B → BBB 

</code></pre>
<p>Associamo ora ai simboli il seguente significato:</p>
<ul>
<li>se trovo &#8216;A&#8217; stampo una linea nera ( i punti fanno parte del set );</li>
<li>se trovo &#8216;B&#8217; ne stampo una rossa ( i punti non fanno parte del set );</li>
</ul>
<p>Applicando iterativamente le regole partendo dalla stringa iniziale (formalmente detta assioma) &#8216;A&#8217; e successivamente trasformando i simboli ottenuti nelle loro interpretazioni otteniamo il seguente risultato (una riga per ogni iterazione):</p>
<div id="attachment_202" class="wp-caption aligncenter" style="width: 410px"><img class="size-full wp-image-202" title="Un Insieme di Cantor generato con un L-System" src="http://sandropaganotti.com/wp-content/uploads/2009/09/ishot-23.png" alt="Un Insieme di Cantor generato con un L-System" width="400" height="322" /><p class="wp-caption-text">Un Insieme di Cantor generato con un L-System</p></div>
<p>Per provare un pò di L-System ho sviluppato una piccolissima applicazione con <a href="http://www.processing.org" target="_blank">Processing</a> che non fa altro che applicare iterativamente delle regole del tipo appena visto dando poi la possibilità di specificare, di volta in volta, le interpretazioni necessarie ad ottenere risultati come quello illustrato qui sopra.</p>
<p>Il codice sorgente è, come al solito, <a href="http://github.com/sandropaganotti/processing-l-system" target="_blank">disponibile sul mio account di github</a>. Al prossimo appuntamento entreremo un pò più nel dettaglio delle varie famiglie di L-System ( indipendenti dal contesto/dipendenti dal contesto, deterministici o stocastici) e cercheremo di definire e sviluppare una grammatica che ci consenta di simulare la crescita di un&#8217;arbusto.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2009/09/28/l-system-con-processing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alcune osservazioni sull&#8217;algoritmo di copertura di un segmento</title>
		<link>http://sandropaganotti.com/2009/07/31/alcune-osservazioni-sullalgoritmo-di-copertura-di-un-segmento/</link>
		<comments>http://sandropaganotti.com/2009/07/31/alcune-osservazioni-sullalgoritmo-di-copertura-di-un-segmento/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 22:09:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Copertura di un segmento]]></category>
		<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=182</guid>
		<description><![CDATA[Sembra che oramai si sia instaurata una sorta di simbiosi tra questo blog e quello di Eineki; questo articolo infatti trae spunto dal suo ultimo golf programming contest e dai due algoritmi che ho analizzato come candidati alla soluzione. Il problema da risolvere è abbastanza intuitivo; dato un set di segmenti identificati da coppie di [...]]]></description>
			<content:encoded><![CDATA[<p>Sembra che oramai si sia instaurata una sorta di simbiosi tra questo blog e quello di <a href="http://eineki.wordpress.com/">Eineki</a>; questo articolo infatti trae spunto dal suo ultimo golf programming contest e dai due algoritmi che ho analizzato come candidati alla soluzione.</p>
<p>Il problema da risolvere è abbastanza intuitivo; dato un set di segmenti identificati da coppie di interi [inizio, fine] bisogna fondere tra loro i segmenti che si sovrappongono.<br />
<span id="more-182"></span></p>
<p><strong>Primo Algoritmo: </strong></p>
<p>La mia prima idea (anche se <span style="text-decoration: line-through;">alcuni</span> molti credits vanno a <a href="http://nijiart.it/">Niji</a>) è stata quella di spostare ad uno ad uno i segmenti dal set di input a quello di output;  durante questa procedura ogni segmento che si sovrappone ai rimanenti del set di input viene fuso ed il risultato spostato in output. Alla fine di un intero ciclo di spostamento nel set di output trovano posto un numero di segmenti minore o uguale a quelli presenti nel set di input a seconda del numero di fusioni.</p>
<p>Con un numero di segmenti minore rispetto a quello del set di input l&#8217;algortimo procede ad un nuovo ciclo di spostamento, se invece il numero dei segmenti è lo stesso allora significa che non vi sono più fusioni da effettuare e che quindi quanto contenuto in output rappresenta il risultato definitivo.</p>
<p>Questo algoritmo, che in un primo momento mi era sembrato di una complessità non riducibile, si è invece rivelato computazionalmente molto più impegnativo del secondo, del quale ho tentato anche un implementazione in Erlang.</p>
<p><strong>Secondo Algoritmo:</strong></p>
<p>La differenza principale di questa procedura (per la quale devo ringraziare <a href="http://www.linkedin.com/pub/fabio-oneri/7/a32/a66">Fabio</a>) rispetto alla precedente è l&#8217;introduzione di un elemento di ordinamento che riassetta il set di input organizzando i segmenti come se fossero poggiati su di una immaginaria linea retta. A questo punto avendo tutti i segmenti ordinati (supponiamo che [A,B,C,D] siano 4 segmenti) è possibile confrontarli a coppie di due ( A e B, B e C, ecc..) fondendo la coppia quando necessario (se A e B si sovrappongono in B dovrà essere riportato il risultato della fusione tra i due).</p>
<p>L&#8217;implementazione che ho sviluppato è lungi dall&#8217;essere perfetta in quanto denota tutte le mie carenze nei confronti di Erlang, del quale stò cercando di apprendere i segreti, ma dovrebbe essere sufficiente a rendere l&#8217;idea:</p>
<pre><code>
-module(coverage).
-export([sort_cover/1]).
-import(lists,[sort/2,foldl/3]).

sort_cover(A) ->  lists:foldl(
	fun([E1,E2],[[H1,H2]|T]) ->
		if
		 	((E1 >= H1) and (E1 =< H2)) or ((E2 >= H1) and (E2 =< H2)) -> [[
				if
					E1 >= H1 -> H1;
					true	 -> E1
				end,
				if
					E2 >= H2 -> E2;
					true	 -> H2
				end
			]|T];

			true	->	[[E1,E2]|[[H1,H2]] ++ T]
		end
	end, [[-1,-1]],
	lists:sort( fun([K,I],[L,M]) -> (K < L) or ((K >= L) and (I =< M)) end, A)).
</code></pre>
<p>La caratteristica migliore di questo algoritmo è sicuramente la sua bassa complessità: O(nlogn); l'operazione computazionalmente più costosa è infatti il sort.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2009/07/31/alcune-osservazioni-sullalgoritmo-di-copertura-di-un-segmento/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
