<?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; Engine</title>
	<atom:link href="http://sandropaganotti.com/tag/engine/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>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>Uno stormo con processing.org</title>
		<link>http://sandropaganotti.com/2009/01/01/uno-stormo-con-processing/</link>
		<comments>http://sandropaganotti.com/2009/01/01/uno-stormo-con-processing/#comments</comments>
		<pubDate>Thu, 01 Jan 2009 16:56:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Algoritmo]]></category>
		<category><![CDATA[Engine]]></category>
		<category><![CDATA[Flock]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[Simulazione]]></category>
		<category><![CDATA[Stormo]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=83</guid>
		<description><![CDATA[Esiste molta letteratura sul problema di simulazione di uno stormo (detto anche Flocking), queste sono le tre regole principali a cui ogni partecipante allo stormo deve obbedire: muoversi verso il centro del gruppo; mantenere una distanza minima dagli altri; muoversi con una velocità simile alla velocità del gruppo; Sulla base di queste tre regole ho [...]]]></description>
			<content:encoded><![CDATA[<p>Esiste molta letteratura sul problema di simulazione di uno stormo (detto anche <a href="http://en.wikipedia.org/wiki/Flocking_(behavior)">Flocking</a>), queste sono le tre regole principali a cui ogni partecipante allo stormo deve obbedire:</p>
<p><span id="more-83"></span></p>
<ul>
<li>muoversi verso il centro del gruppo;</li>
<li>mantenere una distanza minima dagli altri;</li>
<li>muoversi con una velocità simile alla velocità del gruppo;</li>
</ul>
<p>Sulla base di queste tre regole ho sviluppato un piccolo programma in <a href="http://processing.org">Processing.org</a> che simula il modello comportamentale di un gruppo (mantenendo le tre leggi sopra descritte) in questi passi:</p>
<ul>
<li>per ogni elemento dello stormo viene generata una posizione iniziale random all&#8217;interno del canvas;</li>
<li>per ogni ciclo di ridisegno, per ogni elemento dello stormo:
<ul>
<li>recupero la velocità dell&#8217;elemento più vicino e la assegno (leggermente variata) all&#8217;elemento corrente;</li>
<li>trovo il centro dello stormo (e lo modifico con un pò di noise);</li>
<li>avvicino l&#8217;elemento corrente verso il centro dello stormo alla velocità precedentemente impostata &#8211; eseguo quest&#8217;ultima operazione solo se l&#8217;elemento nella nuova posizione non è troppo vicino a qualche altro elemento dello stormo;</li>
</ul>
</li>
</ul>
<p>A questo ho aggiunto la possibilità, usando i tasti W,S,A,D di spostare il centro dello stormo calcolato automaticamente e, in questo modo, pilotare l&#8217;intero stormo.</p>
<p>Come al solito il codice nella sua interezza è presente <a href="http://github.com/sandropaganotti/processing.org-flock">sul mio account di GitHub</a>, posso però in questa sede mostrarvi una demo di quanto creato grazie alla potentissima libreria <a href="http://ejohn.org/blog/processingjs/">Processing.js</a> regalataci da Jhon Resing che consente di eseguire script scritti per Processing.org all&#8217;interno di un elemento &#8216;CANVAS&#8217; del browser.</p>
<p>Questa libreria non è però al momento 100% cross-browser: io ho personalmente testato il tutto con la versione più aggiornata di Firefox (3.0.5) senza riscontrare nessuna perdità di funzionalità (funzionano anche i comandi da tastiera!); lo stesso però non posso garantire per altri browser.</p>
<p>Per provare il programma non vi resta che cliccare sul link sottostante; ricordate che potete direzionare lo stormo usando la vostra tastiera (tasti: WSAD).</p>
<p><a onclick="$('processing_canvas').show();Processing( $('processing_canvas'), $('processing').textContent ); return false;">Lancia la simulazione di stormo in Processing</a></p>
<p><canvas id="processing_canvas" style="display:none;"></canvas></p>
<pre style="display:none;"><code id="processing">

class Creature {
 int sng_x;
 int sng_y;
 float sng_x_speed;
 float sng_y_speed;

 Creature(){
   sng_x = 0;
   sng_y = 0;
   sng_x_speed = 0;
   sng_y_speed = 0;
 }

 float calc_dist(Creature k){
   return sqrt(pow(this.sng_x - k.sng_x,2) + pow(this.sng_y - k.sng_y,2));
 }
 void to_text(){
   println("X: " + sng_x + " Y: " + sng_y);
 }
}

int canvas_width  = 400;
int canvas_height = 400;
int min_separation = 15;
int circle_size = 5;
int num_sheep = 20;
int max_noise = 250;
int mint_follow_x = 0;
int mint_follow_y = 0;
int follow_amount = 100;
float max_speed_variance = 0.001;
float min_speed = 0.005;
float max_speed = 0.01;

Creature[] flock = new Creature[num_sheep]; 

void setup(){
  int i;
  int j;
  boolean bln_separation;
  size(canvas_width,canvas_height);

  for(int x=0; x < flock.length; x++){
    bln_separation = false;
    flock[x] = new Creature();
    while(!bln_separation){
      flock[x].sng_x = int(random(1,canvas_width));
      flock[x].sng_y = int(random(1,canvas_height));
      bln_separation = true;
      for(int y=0; y < x; y++){
        if(flock[x].calc_dist(flock[y]) <= min_separation){
          bln_separation = false;
          break;
        }
      }
    }
  }
}

void draw(){
  background(100);
  float sng_dist;
  float sng_x_speed = 0.0;
  float sng_y_speed = 0.0;
  int sng_x_sum;
  int sng_y_sum;
  float sng_x_avg;
  float sng_y_avg;
  float sng_x_dist;
  float sng_y_dist;
  int sng_tmp_x;
  int sng_tmp_y;

  for(int x=0; x < flock.length; x++){
    sng_dist = 0;
    for(int y=0; y < flock.length; y++){
      if(x!=y){
        if(sng_dist == 0.0 || flock[x].calc_dist(flock[y]) < sng_dist){
          sng_dist = flock[x].calc_dist(flock[y]);
          sng_x_speed = flock[y].sng_x_speed;
          sng_y_speed = flock[y].sng_y_speed;
        }
      }
    }

    flock[x].sng_x_speed = sng_x_speed + max_speed_variance;
    flock[x].sng_y_speed = sng_y_speed + max_speed_variance;
    if(flock[x].sng_x_speed < min_speed) flock[x].sng_x_speed = min_speed;
    if(flock[x].sng_y_speed < min_speed) flock[x].sng_y_speed = min_speed;
    if(flock[x].sng_x_speed > max_speed) flock[x].sng_x_speed = max_speed;
    if(flock[x].sng_y_speed > max_speed) flock[x].sng_y_speed = max_speed;

    sng_x_sum = 0;
    sng_y_sum = 0;
    for(int y=0; y < flock.length; y++){
      sng_x_sum = sng_x_sum + flock[y].sng_x;
      sng_y_sum = sng_y_sum + flock[y].sng_y;
    }

    sng_x_avg = float(sng_x_sum / num_sheep) + (random(1) * max_noise) - (max_noise / 2.0) + mint_follow_x;
    sng_y_avg = float(sng_y_sum / num_sheep) + (random(1) * max_noise) - (max_noise / 2.0) + mint_follow_y;  

    sng_tmp_x = flock[x].sng_x;
    sng_tmp_y = flock[x].sng_y;
    sng_x_dist = sng_x_avg - flock[x].sng_x;
    sng_y_dist = sng_y_avg - flock[x].sng_y;
    flock[x].sng_x = int(flock[x].sng_x + sng_x_dist * flock[x].sng_x_speed);
    flock[x].sng_y = int(flock[x].sng_y + sng_y_dist * flock[x].sng_y_speed);

    for(int y=0; y < flock.length; y++){
      if( x!=y &#038;&#038; flock[x].calc_dist(flock[y]) <= min_separation ){
        flock[x].sng_x = sng_tmp_x;
        flock[x].sng_y = sng_tmp_y;
        break;
      }
    }

    if(flock[x].sng_x > canvas_width) flock[x].sng_x = flock[x].sng_x - canvas_width;
    if(flock[x].sng_x < 0) flock[x].sng_x = flock[x].sng_x + canvas_width;
    if(flock[x].sng_y > canvas_height) flock[x].sng_y = flock[x].sng_y - canvas_height;
    if(flock[x].sng_y < 0) flock[x].sng_y = flock[x].sng_y + canvas_height;

     ellipse(flock[x].sng_x,flock[x].sng_y,circle_size,circle_size);
  }
}

void keyPressed() {
  if (key == 'w') mint_follow_y = mint_follow_y - follow_amount;
  if (key == 's') mint_follow_y = mint_follow_y + follow_amount;
  if (key == 'a') mint_follow_x = mint_follow_x - follow_amount;
  if (key == 'd') mint_follow_x = mint_follow_x + follow_amount;
}

</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2009/01/01/uno-stormo-con-processing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
