<?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>nemediano &#187; Computación</title>
	<atom:link href="http://www.nemediano.com.mx/category/mis-demonios/computacion/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nemediano.com.mx</link>
	<description>Reflexiones de un espiritu curioso</description>
	<lastBuildDate>Fri, 28 Oct 2011 19:07:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Livecoding en el Cenart</title>
		<link>http://www.nemediano.com.mx/2011/livecoding-en-el-cenart/</link>
		<comments>http://www.nemediano.com.mx/2011/livecoding-en-el-cenart/#comments</comments>
		<pubDate>Fri, 26 Aug 2011 21:28:20 +0000</pubDate>
		<dc:creator>nemediano</dc:creator>
				<category><![CDATA[Acerca de mi]]></category>
		<category><![CDATA[Computación]]></category>
		<category><![CDATA[cenart]]></category>
		<category><![CDATA[livecoding]]></category>
		<category><![CDATA[processing]]></category>

		<guid isPermaLink="false">http://www.nemediano.com.mx/?p=397</guid>
		<description><![CDATA[Como siempre sucede Tzolkin me presenta con amigos (ya saben de los poquísimos que tiene) que hacen cosas interesantes. No entraré en detalles en esta parte. Pero lo importante es que me contactaron con unos monitos que hacen livecoding en el Cenart. Antes que nada quiero decir que mi hermano ya me había comentado del [...]]]></description>
			<content:encoded><![CDATA[<p>Como siempre sucede Tzolkin me presenta con amigos (ya saben de los poquísimos que tiene) que hacen cosas interesantes. No entraré en detalles en esta parte. Pero lo importante es que me contactaron con unos monitos que hacen <a href="http://en.wikipedia.org/wiki/Live_coding" target="_blank">livecoding</a> en el <a href="http://www.cenart.gob.mx/" target="_blank">Cenart</a>. Antes que nada quiero decir que mi hermano ya me había comentado del livecoding, pero según teníamos entendido es una practica muy Europea que en México nadie hacia.</p>
<p>Total que como en mis ratos libres (Si, me sorprende que tenga <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  ) me gusta programar al <a href="http://processing.org/" target="_blank">Procesing</a>, me interesó y me lancé a ver de que iba la cosa el mes pasado. Como me gusto la cosa y ahora que por fin me gradué y tengo tiempo libre (si, ajá) me decidí a participar en el evento de este mes aquí la crónica de mi 9 minutos de fama como artista.</p>
<p><span id="more-397"></span></p>
<p>El mes pasado solo me lance a ver y me entere de que iba la cosa: la idea es escribir programas en vivo desde cero y contra reloj. Bueno, cual es el chiste. Para empezar lo llaman concierto <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' />  . Pues en la modalidad en la que lo hacen en el Cenart, es que pasan por parejas, una persona escribe un programa para hacer audio y otra uno para hacer video. Tienen 9 minutos para escribir desde cero el código y mostrarlo. No se vale traer nada escrito ni copiar ni pegar de otro código existente, además como proyectan todo lo que haces en tu compu, el chiste es que los asistentes vean como lo escribes. Así que si haces trampa quedas en evidencia. En general, en su <a href="http://cmm.cenart.gob.mx/tallerdeaudio/actividades/sesioneslivecoding/sesioneslivecoding.html" target="_blank">pagina</a> se explican mejor.</p>
<p>Pues en la primera sesión me llevé varias impresiones:</p>
<ul>
<li>Eso de la formalidad a los artistas, no se les da. (Esto es un cumplido)</li>
<li>Son endiabladamente rápidos y buenos para codificar, la neta me sorprendí bastante.</li>
<li>¿Como es posible que <a href="http://en.wikipedia.org/wiki/Scheme_%28programming_language%29" target="_blank">Scheme</a> sirva para algo practico? <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </li>
<li>Yo <strong>no puedo</strong> hacer eso, así de rápido.</li>
</ul>
<p>Al terminar en evento hable con Tito y me dijo que no es tan live, como me pareció en un principio. Vamos la codificación es en live, pero no están improvisando (bueno no tanto) es decir ensayan el programa que van a escribir. Fijense que esto tiene todo el sentido del mundo, despues de todo antes de dar un concierto&#8230; ensayas, ¿no? <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  . Luego, usan frameworks muy amigables, para hacerlo rápido. Por ejemplo el mismo Procesing, <a href="http://www.pawfal.org/fluxus/" target="_blank">Fluxus</a> y <a href="http://www.audiosynth.com/" target="_blank">SuperColider</a>. Por lo que sus primitivas son muy evolucionadas (chiste local).</p>
<p>Total que después de ver la sesión y como la verdad son un batos muy agradables (y en el Cenart hay chicas muy guapas) me decidí a participar. Bueno esto no fue tan inmediato, en realidad me tomo casi tres semanas decidirme a hacerlo, <a href="http://la-ciudad-de-eleutheria.blogspot.com/" target="_blank">Eleutheria</a> fue vital en convencerme y con la bendición de la bandita me apunte (mande correo confirmando mi participación).</p>
<p>Como algunos de ustedes ya saben, he estado un poco ocupado (malditos escuincles del demonio, que no quieren aprender Teoría de Grafos <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  ). Por lo que fiel a mi costumbre un día antes en la mañana empecé a pensar que iba a hacer (e invité a la bandita a que me fuera a ver <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> , total ya si voy a hacer el ridículo, si quiera que quede entre cuates (nótese la correcta anidación de los paréntesis)). Me tomo media hora programar por primera vez la idea (ya no me acordaba ni que era el Procesing, ni que era java, ni que era la POO, ni que era programar <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  ).</p>
<p>Ok, ahí me empecé a asustar. Una vez que tenia la idea, borre mi código (no se imaginan lo difícil y antinatural que fué para mi hacerlo <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_confused.gif' alt=':-?' class='wp-smiley' />  ) y lo codifique de nuevo desde ceros. Resultado esta vez tomo 10 minuto. Deje que pasaron unas horas y repetí proceso. Además investigue que partes de mi código eran prescindible (no se imaginan la cantidad de lineas que uno gasta haciendo safefall en los estados de default). Por ultimo el miércoles antes de dormir, lo volví a hacer una vez mas 6 minutos 35 seg (OK, now we are talking <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ).</p>
<p>Total que el jueves, me pasó todo. Fui a Acatlan, me entretuve platicando de mis aspiraciones políticas con alguien muy importante de la FESA, fui a la Universidad Anahuac del norte a pedir consejo espiritual a mi mentor y por azares del destino (y después de tomar un taxi). A las 4 y media estaba en el Cenart, con el estomago vacío y listo para la sesión.</p>
<p>Me fije que no había un orden estricto, tu te apuntas en el lugar que quieras, total que fiel a mi costumbre me apunte de segundo. Pero luego nadie se apunto al principio y se corrieron todos un lugar así que para aumentar mis nervios me tocó empezar. Con todo y el nervio termine mi programa como en 8min.</p>
<p>Fiel a la filosofía del blog y de mi persona y aprovechando que el Procesing es muy amigable para exportar cosas (es lo bueno de usar Java para programar, ¡Como las niñas! XD ) aquí esta mi código.</p>
<div class="processing_embed" id="LivecodingAtCenart_container"><p><a href="#" onclick="deployJava.addAppletTo('LivecodingAtCenart', 'http://www.nemediano.com.mx/wp-content/uploads/2011/08/LivecodingAtCenart.jar', 512, 384, 'http://www.nemediano.com.mx/wp-content/plugins/wordpress-processing-embed', 'LivecodingAtCenart_container'); return false;">Ejecutar el programa como un applet de Java</a></p></div>
<p>Source Code: <a href="http://www.nemediano.com.mx/wp-content/uploads/2011/08/LivecodingAtCenart.pde">LivecodingAtCenart.pde</a> <a href="http://www.nemediano.com.mx/wp-content/uploads/2011/08/Neuron.pde">Neuron.pde</a></p>
<p>Built with <a title="Processing.org" href="http://processing.org/">Processing</a></p>
<p>Después del evento y relajarme, estas reflexiones cruzan mi mente:</p>
<ul>
<li>Aunque me fue bien para ser la primera vez, sin duda fui el peor participante en el rubro de video.</li>
<li>Principalmente fue por que erré el paradigma, mi programa es muy estructurado y en general los demas son mucho, mucho menos convencionales y mas&#8230; artísticos. El error estuvo desde que planee que hacer.</li>
<li>Esto no será la última vez que participe <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
<li>Me sorprende que haya mas participantes en el audio que en el video. El simple hecho de que haya mas gente que programa sonido, que gente que haga graficación por computadora me deja anonadado. Si en MAC y en el posgrado y en general entre toda la bandita, hay chingomil gente que quiere hacer gráficos y ninguna que conozco quisiera hacer audio. Me sorprende que en el gremio de los artistas sea justo al revés, para mi no tiene ningún sentido.</li>
<li>Urge aprender Fluxus y reencontrarme con la programación funcional de graficos.</li>
<li>No tengo ni la mas remota idea del sentido musical <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </li>
<li>Eso ultimo explica también por que no puedo tocar ni el <a href="http://en.wikipedia.org/wiki/Birimbau" target="_blank">berimbau</a> (instrumento musical con solo tres tonos) <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </li>
<li>La aleatoriedad es lo de hoy <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </li>
<li>Es mas fácil enseñarle a un artista a programar, que aun científico a &#8230; ¿cocinar? Este último es solo una conjetura.</li>
</ul>
<p>Y como resultado de las conclusiones este es el trabajo futuro <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<ul>
<li>Invitar a la banda del Cenart al congreso de TI en FES Acatlan.</li>
<li>Aprender Fluxus</li>
<li>Como dijo MacArthur al abandonar las Filipinas. I shall return</li>
</ul>
<p>La anécdota: Al final uno de ellos me pregunto &#8220;<em>¿Como se te ocurrió escribir una clase en vivo?</em>&#8221; Mi respuesta natural es: ¿Por que en la POO la base de todo desarrollo es el diseño de clases? ¿Por que la simple idea de un programa en un lenguaje de POO (como java) sin clases me es reprobable? Pero saben, ahora que lo reflexiono mas&#8230; el tenía toda la razón.</p>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.nemediano.com.mx%2F2011%2Flivecoding-en-el-cenart%2F&amp;t=Livecoding%20en%20el%20Cenart" id="facebook_share_icon_397" style="font-size:11px; line-height:13px; font-family:'lucida grande',tahoma,verdana,arial,sans-serif; text-decoration:none;"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif" alt="Share on Facebook" /></a>
	<script type="text/javascript">
	<!--
	var button = document.getElementById('facebook_share_link_397') || document.getElementById('facebook_share_icon_397') || document.getElementById('facebook_share_both_397') || document.getElementById('facebook_share_button_397');
	if (button) {
		button.onclick = function(e) {
			var url = this.href.replace(/share\.php/, 'sharer.php');
			window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
			return false;
		}
	
		if (button.id === 'facebook_share_button_397') {
			button.onmouseover = function(){
				this.style.color='#fff';
				this.style.borderColor = '#295582';
				this.style.backgroundColor = '#3b5998';
			}
			button.onmouseout = function(){
				this.style.color = '#3b5998';
				this.style.borderColor = '#d8dfea';
				this.style.backgroundColor = '#fff';
			}
		}
	}
	-->
	</script>
	]]></content:encoded>
			<wfw:commentRss>http://www.nemediano.com.mx/2011/livecoding-en-el-cenart/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Un swap sin memoria extra</title>
		<link>http://www.nemediano.com.mx/2011/un-swap-sin-memoria-extra/</link>
		<comments>http://www.nemediano.com.mx/2011/un-swap-sin-memoria-extra/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 04:56:13 +0000</pubDate>
		<dc:creator>nemediano</dc:creator>
				<category><![CDATA[Computación]]></category>
		<category><![CDATA[Matematicas]]></category>
		<category><![CDATA[Mis demonios]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.nemediano.com.mx/?p=384</guid>
		<description><![CDATA[Este es otro de los trucos que me enseño Eduardo Lemus cuando me estaba preparando para mis entrevistas en Microsoft. Se trata de hacer un cambio swap entre dos variables con la restricción de que no podemos usar ninguna variable temporal como buffer. Antes que nada quiero aclarar que este truco es una mala practica, [...]]]></description>
			<content:encoded><![CDATA[<p>Este es otro de los trucos que me enseño Eduardo Lemus cuando me estaba preparando para mis entrevistas en Microsoft. Se trata de hacer un cambio swap entre dos variables con la restricción de que no podemos usar ninguna variable temporal como buffer.</p>
<p>Antes que nada quiero aclarar que este truco es una mala practica, en la mayoría de los lugares donde lo he visto (mientras me documentaba para escribir este post) aconsejan no hacerlo. La razón, aunque el truco funciona (y como veremos adelante tiene un fundamento solido) es confuso. Es decir según los <a href="http://en.wikipedia.org/wiki/Software_engineering">IS</a> la ganancia en performance es muy poca comparada con la complicación en entender el código escrito. Además de que en computadoras modernas este truco puede ser mas lento que la solución estándar (estúpidos optimizadores de memoria).</p>
<p>Así que solo ocuparlo en código que quieran usar con fin de hacer faramalla, show e impresionar chicas. <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  O en caso de que algún entrevistador para alguna chamba se pase de listo y les pregunte como hacerlo.<br />
<span id="more-384"></span></p>
<h2>Entendiendo el problema</h2>
<p>En muchos algoritmos (por ejemplo en ordenación) es necesario intercambiar los valores de dos variables. Para simplificar el resto de la explicación asumiré <em>sin perdida de generalidad</em> (como me gusta usar esa frase <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  ) que se tienen valores numéricos y enteros.</p>
<p>Es decir al principio tenemos algo como.</p>
<p>A = 2<br />
B = 4</p>
<p>Queremos llevar a cabo la operación de intercambio y obtener una situación como:</p>
<p>A = 4<br />
B = 2</p>
<h2>Como lo haría una persona normal</h2>
<p>Pues como nos enseñaron en la escuela XD. En todos los lenguajes de programación al asignación es una operación destructiva. Es decir al momento de asignar un valor a una variable se pierde el contenido anterior. (¡Estúpidas limitantes físicas del computo!).</p>
<p>Por lo que la gente que no sabe el truco haría algo así:</p>
<p>TEMP = A<br />
A = B<br />
B = TEMP</p>
<p>De esta manera tenemos un espacio de memoria extra donde guardar el valor de A, por lo tanto podemos destruir el contenido de A sin tentarnos nuestro corazoncillo. Y recuperarlo después del buffer temporal.</p>
<p>Ahora lo interesante: ¿Cómo se hace sin usar ninguna variable TEMP?</p>
<h2>La solución del matemático.</h2>
<p>Ahora si ustedes son de esas personas que saben un montón de matemáticas, pero jamas han programado de a de veras (¡Como los hombres!) podrían sugerir esta solución. (No se hagan se que por ahí hay muchísimos).</p>
<p>A = A + B<br />
B = A &#8211; B<br />
A = A &#8211; B</p>
<p>Ahora sabemos que ésta es un caso particular de una solución mas general.</p>
<ol>
<li>Combina los dos valores en la variable A por medio de una operación binaria bien portada (Es decir que sea invertible). En este momento en A están guardados de alguna manera los dos valores.</li>
<li>Usa la operación inversa de la operación binaria para extraer en la variable B el valor original de A a partir del valor actual de A. Recuerda que no hemos modificado B.</li>
<li>Usa la operación inversa para extraer ahora el viejo valor de B en A. Recordando que tenemos guardado en B el valor original de A.</li>
</ol>
<p>El fallo de la solución anterior es que trabajamos con maquinas de memoria finita, es decir podría pasar que la operación bien portada que es la suma produzca un número tan grande que no quepa en la localidad de memoria que le guardamos. ¿No se acuerdan del molesto carry cuando nos enseñaron la suma en binario y  hacer circuitos sumadores? Pues es aquí donde nos vino a fastidiar la vida.</p>
<h2>La solución del computólogo</h2>
<p>Tan simple, tan elegante, tan parecida a la solución del matemático XD (Por ahí dicen que es la misma por que los computologos y los matemáticos son casi lo mismo ). Pues resulta que hay mas de una operación bien portada y una que tiene todo lo que necesitamos es el XOR.</p>
<table>
<tr>
<th>x</th>
<th>y</th>
<th>x<img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=%5Coplus+&bg=FFFFFF&fg=000000'  alt="\oplus " />y</th>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>0</td>
</tr>
</table>
<p>¡Muérete de envidia suma! ¡El XOR es una suma sin carry vean la tabla!. ¿Suficiente? El XOR (conocido también en los bajos mundos de la lógica como <strong>disyunción exclusiva</strong>) es una de las operaciones que pueden construir toda la lógica de primer orden, además es conmutativo, asociativo y es su propio inverso. Pueden ver aquí la lista de <a href="http://en.wikipedia.org/wiki/Xor">todo lo bello que es el XOR</a>. Es mas: ¡XOR soy tu fan!</p>
<p>Es decir podemos usar el XOR que como no tiene carry y nunca se desborda para hacer</p>
<p>A = A <img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=%5Coplus&bg=FFFFFF&fg=000000'  alt="\oplus" /> B<br />
B = B <img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=%5Coplus&bg=FFFFFF&fg=000000'  alt="\oplus" /> A<br />
A = A <img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=%5Coplus&bg=FFFFFF&fg=000000'  alt="\oplus" /> B</p>
<p>¿Mencione que es conmutativo y que es su propio inverso? Además que en todo lenguaje decente como en C y C++ y en algunos no decentes (Java <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) Tenemos un operador de XOR y tenemos una forma abreviada de hacer la asignación. ¿No me creen? Miren con sus propios ojos:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
&nbsp;
	<span style="color: #0000ff;">int</span> a <span style="color: #000080;">=</span> <span style="color: #0000dd;">4</span>, b <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span>
&nbsp;
	<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Los valores son: a = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> a <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; b = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> b <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
	swap<span style="color: #008000;">&#40;</span>a, b<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
	<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Después del swap:&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
	<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Los valores son: a = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> a <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; b = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> b <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span> swap <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> <span style="color: #000040;">&amp;</span>a, <span style="color: #0000ff;">int</span> <span style="color: #000040;">&amp;</span>b<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
	a <span style="color: #000040;">^</span><span style="color: #000080;">=</span> b<span style="color: #008080;">;</span>
	b <span style="color: #000040;">^</span><span style="color: #000080;">=</span> a<span style="color: #008080;">;</span>
	a <span style="color: #000040;">^</span><span style="color: #000080;">=</span> b<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Y para que no digan que no pelo a la banda Javera, tomen no se vallan a enojar.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> TestSwaping <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">int</span> a <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4</span>, b <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Los valores son: a = &quot;</span> <span style="color: #339933;">+</span> a <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot; b = &quot;</span> <span style="color: #339933;">+</span> b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		a <span style="color: #339933;">^=</span> b<span style="color: #339933;">;</span>
		b <span style="color: #339933;">^=</span> a<span style="color: #339933;">;</span>
		a <span style="color: #339933;">^=</span> b<span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Después del swap&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Los valores son: a = &quot;</span> <span style="color: #339933;">+</span> a <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot; b = &quot;</span> <span style="color: #339933;">+</span> b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Mas información sobre la correctez y demás cosas de este truco esta en su <a href="http://en.wikipedia.org/wiki/XOR_swap_algorithm">pagina wikipedia</a>.<br />
﻿</p>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.nemediano.com.mx%2F2011%2Fun-swap-sin-memoria-extra%2F&amp;t=Un%20swap%20sin%20memoria%20extra" id="facebook_share_icon_384" style="font-size:11px; line-height:13px; font-family:'lucida grande',tahoma,verdana,arial,sans-serif; text-decoration:none;"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif" alt="Share on Facebook" /></a>
	<script type="text/javascript">
	<!--
	var button = document.getElementById('facebook_share_link_384') || document.getElementById('facebook_share_icon_384') || document.getElementById('facebook_share_both_384') || document.getElementById('facebook_share_button_384');
	if (button) {
		button.onclick = function(e) {
			var url = this.href.replace(/share\.php/, 'sharer.php');
			window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
			return false;
		}
	
		if (button.id === 'facebook_share_button_384') {
			button.onmouseover = function(){
				this.style.color='#fff';
				this.style.borderColor = '#295582';
				this.style.backgroundColor = '#3b5998';
			}
			button.onmouseout = function(){
				this.style.color = '#3b5998';
				this.style.borderColor = '#d8dfea';
				this.style.backgroundColor = '#fff';
			}
		}
	}
	-->
	</script>
	]]></content:encoded>
			<wfw:commentRss>http://www.nemediano.com.mx/2011/un-swap-sin-memoria-extra/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Esteganografía y otros bichos de las CC</title>
		<link>http://www.nemediano.com.mx/2011/esteganografia-y-otros-bichos-de-las-cc/</link>
		<comments>http://www.nemediano.com.mx/2011/esteganografia-y-otros-bichos-de-las-cc/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 21:07:47 +0000</pubDate>
		<dc:creator>nemediano</dc:creator>
				<category><![CDATA[Computación]]></category>
		<category><![CDATA[Mis demonios]]></category>
		<category><![CDATA[ciencia]]></category>
		<category><![CDATA[codigos]]></category>
		<category><![CDATA[computacion]]></category>
		<category><![CDATA[criptografía]]></category>
		<category><![CDATA[esteganografía]]></category>

		<guid isPermaLink="false">http://www.nemediano.com.mx/?p=372</guid>
		<description><![CDATA[Hace ya unos meses me reuní con mi viejo amigo Leo, de por allá cuando estábamos trabajando juntos en la FC. Tenia mucho tiempo de no verlo y después de ponernos al tanto de nuestras vidas y de empezar a platicar de diversas cuestiones (OVNIS, terremotos, teoría de la conspiración, la nueva versión de Ubuntu, [...]]]></description>
			<content:encoded><![CDATA[<p>Hace ya unos meses me reuní con mi viejo amigo Leo, de por allá cuando estábamos trabajando juntos en la FC. Tenia mucho tiempo de no verlo y después de ponernos al tanto de nuestras vidas y de empezar a platicar de diversas cuestiones (OVNIS, terremotos, teoría de la conspiración, la nueva versión de Ubuntu, de CC y de matemáticas), al final me comento de un truco muy simple que conocía para ocultar mensajes en las imágenes.</p>
<p>Pasaron unos días y comente con otro amigo (Lalo Lemus) el truco de mi amigo Leo y me comento que era una forma muy primitiva de una área de las Ciencias de la computación conocida como <a href="http://en.wikipedia.org/wiki/Steganography">Esteganografía</a> (siempre me ha sorprendido la cantidad de cultura general de computólogo que posee Lalo).</p>
<p><span id="more-372"></span>La esteganografía es la rama de las ciencias de la computación que estudia la manera de transmitir mensajes ocultos embebidos en mensajes. Aquí hago un paréntesis, ya se que están pensando que eso es la <a href="http://en.wikipedia.org/wiki/Cryptography">criptografia</a>, pero no, aunque son cosas muy parecidas la criptografía y la estagnografía son cosas diferentes.</p>
<p>Mientras que la criptografía estudia como cifrar mensajes para que cuando alguien los intercepte no sea capaz de entenderlos, la esteganografia estudia como oculta el mismo hecho <em>de que un mensaje existe</em>.</p>
<p>Vamos para la cirpto se asume que el enemigo conoce que se va a atransmitir un mensaje, y que ademas el enemigo va a interceptar el mensaje. Solo que el mensaje viene en clave y no va a poder entender su contenido (esta cifrado).</p>
<p>En el caso de la esteganografia, el enemigo se da cuenta que hay un intercambio de información. Pero no sabe que en la información; aparentemente inocente, hay un mensaje oculto.</p>
<p>Desde los tiempo de <a href="http://en.wikipedia.org/wiki/Herodotus">Herodoto</a> (padre de la historia) hay indicios de esteganografía. Pues se describe una situación donde un general escribió un aviso donde prevenía de un ataque de los griegos en una tableta de madera, y después la encero y escribió otro mensaje sobre la cera (en esos tiempo era común mandar correspondencia en tabletas enceradas).</p>
<p>Herodoto también describe otro caso mas <em>hardcore</em> en donde le rapan la cabeza a un esclavo y le tatuan un mensaje, luego esperan a que el cabello del esclavo vuelva a crecer y lo mandan (sin conocimiento del mensaje) con el receptor.</p>
<p>En la esteganografia moderna se trata de esconder archivos dentro de otros archivos (de apariencia inocente) por ejemplo imágenes, musica o vídeos. Una de la técnicas mas comunes es la de modificar el LSB (Bit menos significativo) en los datos de algún archivo (por ejemplo los píxeles de una imagen). De esta manera la imagen no cambia mucho (no es perceptible al ojo humano y tiene un mensaje oculto entre sus píxeles.</p>
<p>Una buena esteganografia, debe cumplir con:</p>
<ul>
<li>El archivo no sea sospechoso.</li>
<li>Un usuario normal no debe notar el cambio entre un archivo común y un archivo con un mensaje oculto</li>
<li>El tamaño del archivo no debe variar.</li>
</ul>
<p>Como la mayoría de las buenas técnicas de esteganografia requieren un cierto conocimiento de teoría de la información y de programación, por lo que la mayoría de los usuarios mortales no podemos usarlas tan fácil.</p>
<p>Aquí es donde se vuelve valioso el truco de mi amigo Leo</p>
<h2>Esteganografía para principiantes</h2>
<p>Este truco no es una buena esteganografia, pues no cumple con los requisitos arriba expuestos. pero digamos que tiene la enorme ventaja que no requiere nada mas que el ambiente estándar de usuario (sin conocimientos de programación) y en un sistema operativo decente sin ser nada del otro mundo (vamos con cualquier GNU/Linux &#8211; Unix basta).</p>
<p>El truco en cuestión es el siguiente (me dio permiso de escribirlo :p )</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cat</span> imagen.jpg mensaje.zip <span style="color: #000000; font-weight: bold;">&gt;</span> imagenConMensaje.jpg
<span style="color: #c20cb9; font-weight: bold;">du</span> <span style="color: #660033;">-b</span> imagen.jpg
<span style="color: #c20cb9; font-weight: bold;">tail</span> <span style="color: #660033;">-c</span> +<span style="color: #000000;">4012558</span> imagenConMensaje.jpg <span style="color: #000000; font-weight: bold;">&gt;</span> mensajeRecuperado.zip</pre></div></div>

<p>Expliquemos paso a paso. Se tiene una imagen: <strong>imagen.jpg</strong> y se quiere ocultar el mensaje contenido en el zip: <strong>mensaje.zip</strong>. Se le añaden a la imagen los bytes del mensaje al final. Esto forma una nueva imagen (que mide el tamaño de la imagen mas el tamaño del mensaje). Ahora si queremos recuperar el mensaje debemos de saber cual era el tamaño original del mensaje (por eso lo calculamos con <strong>du</strong>) y extraemos los ultimo bytes de la imagen y les damos forma en un nuevo archivo .zip.</p>
<p>En el caso de mi imagen el tamaño resulto ser 4012558, pero obviamente <em><strong>esa cantidad debe sustituirse con el tamaño de la imagen que ustedes usen</strong></em> (el resultado del comando previo).</p>
<h3>¿Por que funciona?</h3>
<p>Recordemos que en las imagenes .jpg hay un <em>cabecero</em> y luego vienen los datos y en el cabecero <em>esta guardado el tamaño de la imagen</em>. Al añadir el mensaje al final del archivo con el comando <strong>cat</strong>, le estamos poniendo bytes al final de los datos sin modificar el cabecero. Por esta razón la nueva imagen con los datos puede ser vista y leída en cualquier SW como si fuera una imagen normal. Aun cuando tiene los datos ocultos.</p>
<p>Si nosotros supiéramos el tamaño de la imagen original, podemos restarle a la imagen modificada ese tamaño (<strong>tail</strong>) y el resultado deben ser los bytes que contienen el mensaje, como ese era originalmente un zip lo direccionamos en nuevo zip y tendremos el mensaje de vuelta.</p>
<p>Como ejemplo aquí hay una imagen de Emma Watson.</p>

<a href="http://www.nemediano.com.mx/wp-content/gallery/imagenesvarias/emma.jpg" title="Imagen original de Emma Watson" class="thickbox" rel="singlepic403" >
	<img class="ngg-singlepic" src="http://www.nemediano.com.mx/wp-content/gallery/cache/403__320x240_emma.jpg" alt="emma" title="emma" />
</a>

<p>Ahora aquí esta la misma imagen, junto con <strong>todos los libros de Narnia</strong> escondidos en un zip.</p>

<a href="http://www.nemediano.com.mx/wp-content/gallery/imagenesvarias/emmaconlibros.jpg" title="Imagen de Emma Watson con un zip con TODOS los libros de narnia" class="thickbox" rel="singlepic404" >
	<img class="ngg-singlepic" src="http://www.nemediano.com.mx/wp-content/gallery/cache/404__320x240_emmaconlibros.jpg" alt="emmaconlibros" title="emmaconlibros" />
</a>

<p>Nótese el cambio de tamaño de la imagen a mas del doble (como ya dijimos esta <strong>no es</strong> una buena técnica de esteganografía).</p>
<p>Nota Las miniaturas son links a las verdaderas imágenes que usé.</p>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.nemediano.com.mx%2F2011%2Festeganografia-y-otros-bichos-de-las-cc%2F&amp;t=Esteganograf%C3%ADa%20y%20otros%20bichos%20de%20las%20CC" id="facebook_share_icon_372" style="font-size:11px; line-height:13px; font-family:'lucida grande',tahoma,verdana,arial,sans-serif; text-decoration:none;"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif" alt="Share on Facebook" /></a>
	<script type="text/javascript">
	<!--
	var button = document.getElementById('facebook_share_link_372') || document.getElementById('facebook_share_icon_372') || document.getElementById('facebook_share_both_372') || document.getElementById('facebook_share_button_372');
	if (button) {
		button.onclick = function(e) {
			var url = this.href.replace(/share\.php/, 'sharer.php');
			window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
			return false;
		}
	
		if (button.id === 'facebook_share_button_372') {
			button.onmouseover = function(){
				this.style.color='#fff';
				this.style.borderColor = '#295582';
				this.style.backgroundColor = '#3b5998';
			}
			button.onmouseout = function(){
				this.style.color = '#3b5998';
				this.style.borderColor = '#d8dfea';
				this.style.backgroundColor = '#fff';
			}
		}
	}
	-->
	</script>
	]]></content:encoded>
			<wfw:commentRss>http://www.nemediano.com.mx/2011/esteganografia-y-otros-bichos-de-las-cc/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Organizando fotos con ImageMagick</title>
		<link>http://www.nemediano.com.mx/2010/organizando-fotos-con-imagemagick/</link>
		<comments>http://www.nemediano.com.mx/2010/organizando-fotos-con-imagemagick/#comments</comments>
		<pubDate>Fri, 16 Jul 2010 22:07:36 +0000</pubDate>
		<dc:creator>nemediano</dc:creator>
				<category><![CDATA[Computación]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.nemediano.com.mx/?p=317</guid>
		<description><![CDATA[El semestre antepasado lleve la clase de tratamiento de imágenes multiespectrales con el Dr jorge Lira. Fue un curso muy pesado tareas y practicas a diestra y siniestra, además incluían manejar imágenes en un formato RAW para evitar la pedida de información, (esto se traducía en que cada practica o tarea que queríamos hacer, involucraba [...]]]></description>
			<content:encoded><![CDATA[<p>El semestre antepasado lleve la clase de tratamiento de imágenes multiespectrales con el <a href="http://turing.iimas.unam.mx/~siav/Gente/jorgelira.htm">Dr jorge Lira</a>. Fue un curso muy pesado tareas y practicas a diestra y siniestra, además incluían manejar imágenes en un formato RAW para evitar la pedida de información, (esto se traducía en que cada practica o tarea que queríamos hacer, involucraba de 500MB a 1GB en 10 o 15 imágenes).  Lo mas feo del asunto es que las imágenes en RAW no son interpretables en casi ningún programa, para poder transformarlas en lindos png o jpg (o tiff) que pudiéramos usar en los reportes y tareas (Documentos de <a href="http://www.latex-project.org/">LaTeX</a> o de <a href="www.openoffice.org">Open Office</a>).</p>
<p>Prácticamente dependíamos de un programa comercial (privativo) que el Dr tenia en su laboratorio para guardar una copia de la imagen en algún formato mas universal. No contentos con llevar nuestro GB de imágenes en raw con los datos de la practica, teníamos que viajar con una copia de la imagen en jpg para poder escribir nuestro reporte.</p>
<p>Fue entonces cuando mi amiga Etna, me presento con <a href="http://www.imagemagick.org/script/index.php">ImageMagick</a>.<br />
<span id="more-317"></span></p>
<h2>Y que es ImageMagick&#8230;</h2>
<p>Es un conjunto de programas libres que sirven para convertir, transformar, y procesar imágenes en casi cualquier formato (y lo digo en serio). Lo que lo hace tan poderoso y flexible es que su interfaz es en linea de comandos, por lo que es ideal para desarrollar programas que ocupen ImageMagick y procesen imágenes (de hecho hay bindings para varios lenguajes de programación).</p>
<p>Una de las chucherias de ImageMagick es convertir de formato raw a cualquier formato.</p>
<h2>Por que lo querría usar uno normalmente.</h2>
<p>La segunda vez que me encontré con la necesidad de procesar un montón de imágenes y que me motivo a escribir este post fue regresando de las vacaciones en Oaxaca. Yo no llevaba mi cámara, pero Erika y Mag me pasaron sus fotos.</p>
<p>Ya saben tenia cientos de imágenes con títulos bien descriptivos como IMG_2379.JPG que pesaban algo así como 600Kb y median como 3072&#215;2304 píxeles. Lo cual si hubiera querido subir en mi blog, conllevan un montón de trafico de red, y además seria un desperdicio, por que quien tiene un monitor con esa resolución (Vamos los que las vieran las tendrían que rescalar antes de verlas).</p>
<p>La solución de nuevo es ImageMagick</p>
<h2>Como se usa ImageMagik</h2>
<p>Pues el comando convert (que no es el único que conforma ImageMagick), nos da toda la versatilidad que queremos.</p>
<h3>Escalando una imagen</h3>
<p>Al escalar una imagen debemos de tener cuidado de hacerlo de una manera de que conserve su proporción (su aspect ratio), la mayoría del SW nos deja hacerlo si le decimos que no queremos deformaciones, también se puede hacer en ImageMagick</p>
<pre>convert -resize 50% input.jpg output.jpg</pre>
<p>Al darle en porcentaje el tamaño, Imagemagick sabe que no debe modificar el aspect ratio.</p>
<h3>Reduciendo la calidad de la imagen</h3>
<p>Hay dos tipos de compresión una donde no se pierde información llamada lossless, y otra llamada lossy compresión que es cuando un imagen pierde parte de su información al comprimirse. Cuando guardamos una imagen en formato jpg se esta haciendo una compresión con pérdida (lossy). El algoritmo del jpg es lo suficientemente flexible para dejarnos controlar la perdida con un parámetro de calidad. Mientras menos sea la calidad menor sera la perdida y mayor el tamaño de la imagen.</p>
<p>Sin embargo el algoritmo es tan bueno que bajar un poco la calidad de la imagen, suele bajar en mucho el tamaño (en bytes) de la misma, aproximadamente una imagen al 90% de calidad mide una cuarta parte que la imagen original. El estándar para publicar en una web es del 85%.</p>
<p>Para hacerlo en ImageMagick se ocupa el siguiente comando</p>
<pre>convert -quality 85% input.jpg output.jpg</pre>
<h3>Corrigiendo la orientación</h3>
<p>Otra cosa interesante es que ImageMagick puede corregir la orientación de una imagen de una cámara si los metadatos de la foto tienen esa orientación con el comando</p>
<pre>convert -auto-orient input.jpg output.jpg</pre>
<p>Ojo esto no siempre funciona (a veces los metadatos de la cámara no están bien), por lo que siempre es bueno darle una checada a la imagen de salida. También recuerda que en muchos navegadores de archivos se aplica esta corrección, pero eso no quiere decir que la imagen este volteada, si no que el visor de imágenes la esta transformando para que la veas.</p>
<p>Eso puede provocar que en tu máquina tu veas la imagen al derecho y cuando la subas a un sitio web, la veas al revés. La única forma de saberlo es viendo el tamaño de la imagen y ver si es mas alta que ancha o viceversa.</p>
<p>Y desde luego todos estos pasos se pueden llevar a cabo al mismo tiempo. Por ejemplo:</p>
<pre>convert -auto-orient -quality 85% -resize 50% input.jpg output.jpg</pre>
<h2>Y poniendo todo en un script</h2>
<p>Aprovechando que tuve que aprender un poco de bash, para un programa de la tesis, escribí el siguiente scrip en bash, para hacer las operaciones antes descritas sobre una carpeta con muchas imágenes.</p>
<p>El script tiene las siguientes características:</p>
<ul>
<li>Siempre trata de hacer la corrección de orientación</li>
<li>Acepta opcionalmente los siguientes parámetros</li>
<li><strong>-q quality</strong> Para reducir de calidad las imágenes, el parámetro debe ser entero y estar en el intervalo (0, 100)</li>
<li><strong>-s size</strong> Para reducir el tamaño en un porcentaje, (en ImageMagick esto no necesariamente tiene que especificarse así, pero en el scrip valido que solo se pueda cambiar el tamaño en un porcentaje) que acepta enteros en el intervalo (0, 100)</li>
<li><strong>-n name</strong> Para especificar un patrón de nombre de la imagen de salida, en caso de que este parámetro no se le proporcione, las imágenes de salida tendrán el mismo nombre que las de salida (puede que las sobrescriban), con la única excepción que valido que en la imagen de salida la extensión siempre sea en minúsculas (odio que en la mayoría de las cámaras, las extensiones de las imágenes estén en mayúsculas DSC_001.JPG)</li>
</ul>
<p>En resumen el scrip corrido en su forma completa por ejemplo:</p>
<pre>photo2wp.sh -q 85 -s 50  –name Vacaciones</pre>
<p>Tomara todas las imágenes con extensión jpg ó JPG que haya en el directorio actual. A cada una de ellas las escalará al 50% respetando su aspect ratio, las comprimirá en jpg, con el 85% de calidad y las imágenes de salida tendrán el nombre VacacionesXXX.jpg. Donde XXX es un numero progresivo que depende de la cantidad de imágenes que haya en la carpeta.</p>
<p>Es posible pasar mas de una palabra en el nombre pero entonces hay que encerrarlo en comillas:</p>
<pre>photo2wp.sh -q 85 -s 50  –name “Mis Vacaciones”</pre>
<p>Todos los argumentos son opcionales:</p>
<pre>photo2wp.sh -q 85  –name Vacaciones</pre>
<p>Por ejemplo comprime todas las imágenes al 85% y las renombra como VacacionesXXX.jpg, sin escalar su tamaño.</p>
<p>En un abuso de las opciones, puede usarse sin argumentos</p>
<pre>photo2wp.sh</pre>
<p>Que toma todas las imágenes, trata de corregir su orientación, y las guarda con el mismo nombre pero asegurándose que la extensión sea en minúsculas (si las imágenes originales tienen su extensión en minúsculas, las va a sobrescribir)</p>
<p>Por ultimo algunas recomendaciones:</p>
<ul>
<li><strong>No he testeado el script al 100%</strong>, así que siempre ten una copia de tus imágenes originales. (Aún cuando no uses mi script esto es buena practica)</li>
<li>Recuerda que el script solo funciona cuando <strong>ya tienes instalado</strong> el ImageMagick en tu maquina.</li>
<li>Si quieres usar el script, recuerda que antes que nada debes darle permisos de ejecución.</li>
<li>Recuerda que el script solo actúa sobre el directorio en el que esta siendo ejecutado. <strong>No se mete recursivamente</strong> en carpetas.</li>
</ul>
<p>Finalmente el script esta aqui (copia y pega en un archivo de texto yo lo llame photo2wp.sh, pero pon el nombre que quieras):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Este scrip toma todas las fotos de la carpeta donde se ejecute y las</span>
<span style="color: #666666; font-style: italic;">#procesa. Primero la pone al derecho dependiendo de los metadatos, </span>
<span style="color: #666666; font-style: italic;">#les cambia de nombre y las guarda con un tamaño y una calidad </span>
<span style="color: #666666; font-style: italic;">#determinadas por las opciones</span>
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> dameNumero <span style="color: #7a0874; font-weight: bold;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$total</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">100</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$cont</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">10</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #007800;">number</span>=<span style="color: #ff0000;">&quot;0<span style="color: #007800;">$cont</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">else</span>
			<span style="color: #007800;">number</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$cont</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$total</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">1000</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$cont</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">10</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #007800;">number</span>=<span style="color: #ff0000;">&quot;00<span style="color: #007800;">$cont</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$cont</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">100</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #007800;">number</span>=<span style="color: #ff0000;">&quot;0<span style="color: #007800;">$cont</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">else</span>
			<span style="color: #007800;">number</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$cont</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">else</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$cont</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">10</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #007800;">number</span>=<span style="color: #ff0000;">&quot;000<span style="color: #007800;">$cont</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$cont</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">100</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #007800;">number</span>=<span style="color: #ff0000;">&quot;00<span style="color: #007800;">$cont</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$cont</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">1000</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #007800;">number</span>=<span style="color: #ff0000;">&quot;0<span style="color: #007800;">$cont</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">else</span>
			<span style="color: #007800;">number</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$cont</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">fi</span> 
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Aqui parseamos las opciones</span>
<span style="color: #007800;">qflag</span>=<span style="color: #000000;">0</span>
<span style="color: #007800;">sflag</span>=<span style="color: #000000;">0</span>
<span style="color: #007800;">nflag</span>=<span style="color: #000000;">0</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">getopts</span> <span style="color: #ff0000;">'q:s:n:'</span> OPTION
<span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #007800;">$OPTION</span> <span style="color: #000000; font-weight: bold;">in</span>
  q<span style="color: #7a0874; font-weight: bold;">&#41;</span>	<span style="color: #007800;">qflag</span>=<span style="color: #000000;">1</span>
		<span style="color: #007800;">quality</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$OPTARG</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">;;</span>
  s<span style="color: #7a0874; font-weight: bold;">&#41;</span>	<span style="color: #007800;">sflag</span>=<span style="color: #000000;">1</span>
		<span style="color: #007800;">size</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$OPTARG</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">;;</span>
  n<span style="color: #7a0874; font-weight: bold;">&#41;</span>	<span style="color: #007800;">nflag</span>=<span style="color: #000000;">1</span>
		<span style="color: #007800;">nameBase</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$OPTARG</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">;;</span>
  <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Usage: photo2wp.sh [-q &lt;quality&gt;] [-s &lt;size&gt;] [-n &lt;name&gt;]&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
		<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">2</span>
		<span style="color: #000000; font-weight: bold;">;;</span>
  <span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Si no nos dieron quality asume el 100</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$qflag</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">quality</span>=<span style="color: #000000;">100</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Si no nos dieron size asume el 100</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$sflag</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">size</span>=<span style="color: #000000;">100</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#Checamos que quality sea valido</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$quality</span> =~ ^<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">0</span>-<span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>+$ <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$quality</span> <span style="color: #660033;">-gt</span> <span style="color: #000000;">100</span> <span style="color: #660033;">-o</span> <span style="color: #007800;">$quality</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
    <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;El parámetro quality debe se un número entero en el intervalo [0, 100]&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
		<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">3</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">else</span> 
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;El parámetro quality debe se numérico y entero&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
    <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">3</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Ahora validamos el valor de size</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$size</span> =~ ^<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">0</span>-<span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>+$ <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$size</span> <span style="color: #660033;">-gt</span> <span style="color: #000000;">100</span> <span style="color: #660033;">-o</span> <span style="color: #007800;">$size</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
    <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;El parámetro size debe se un número entero en el intervalo [0, 100]&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
		<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">3</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">else</span> 
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;El parámetro size debe se numérico y entero&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
    <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">3</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Contamos cuantas imagenes hay</span>
<span style="color: #007800;">total</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">*</span>.<span style="color: #7a0874; font-weight: bold;">&#91;</span>jJ<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>pP<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>gG<span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">wc</span> -l<span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$total</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;No hay imagenes que procesar en esta carpeta&quot;</span>
	<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Calculemos las opciones y avisemos al usuario que vamos a hacer</span>
<span style="color: #007800;">opciones</span>=<span style="color: #ff0000;">&quot;-auto-orient&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Hay <span style="color: #007800;">$total</span> fotos&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$sflag</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Se van a escalar a un tamaño de: <span style="color: #007800;">$size</span>%&quot;</span>
	<span style="color: #007800;">opciones</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opciones</span> -resize <span style="color: #007800;">$size</span>%&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$qflag</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Se van a comprimir con una calidad de: <span style="color: #007800;">$quality</span>%&quot;</span>
	<span style="color: #007800;">opciones</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opciones</span> -quality <span style="color: #007800;">$quality</span>%&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$nflag</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Se guardaran con el nombre: <span style="color: #007800;">$nameBase</span>[XXX].jpg&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Todo correcto empezamos a procesar</span>
<span style="color: #007800;">cont</span>=<span style="color: #000000;">0</span>
<span style="color: #007800;">number</span>=<span style="color: #ff0000;">&quot;&quot;</span>
<span style="color: #007800;">output_file</span>=<span style="color: #ff0000;">&quot;&quot;</span>
<span style="color: #007800;">images</span>=<span style="color: #000000; font-weight: bold;">*</span>.<span style="color: #7a0874; font-weight: bold;">&#91;</span>jJ<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>pP<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>gG<span style="color: #7a0874; font-weight: bold;">&#93;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Ciclo principal sobre todas las imagenes de entrada</span>
<span style="color: #000000; font-weight: bold;">for</span> input_file <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$images</span>
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #666666; font-style: italic;">#Calculamos el nombre de la imagen de salida</span>
	<span style="color: #007800;">cont</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">expr</span> <span style="color: #007800;">$cont</span> + <span style="color: #000000;">1</span><span style="color: #000000; font-weight: bold;">`</span>
	dameNumero
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$nflag</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #007800;">output_file</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$nameBase</span><span style="color: #007800;">$number</span>&quot;</span>
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #007800;">output_file</span>=<span style="color: #800000;">${input_file%%.*}</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">#Realizamos la conversion</span>
	<span style="color: #000000; font-weight: bold;">if</span> convert <span style="color: #007800;">$opciones</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$input_file</span>&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$output_file</span>.jpg&quot;</span> <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null ; <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Imagen <span style="color: #007800;">$cont</span> de <span style="color: #007800;">$total</span>&quot;</span>
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$input_file</span> no pudo ser procesada...&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span></pre></td></tr></table></div>

<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.nemediano.com.mx%2F2010%2Forganizando-fotos-con-imagemagick%2F&amp;t=Organizando%20fotos%20con%20ImageMagick" id="facebook_share_icon_317" style="font-size:11px; line-height:13px; font-family:'lucida grande',tahoma,verdana,arial,sans-serif; text-decoration:none;"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif" alt="Share on Facebook" /></a>
	<script type="text/javascript">
	<!--
	var button = document.getElementById('facebook_share_link_317') || document.getElementById('facebook_share_icon_317') || document.getElementById('facebook_share_both_317') || document.getElementById('facebook_share_button_317');
	if (button) {
		button.onclick = function(e) {
			var url = this.href.replace(/share\.php/, 'sharer.php');
			window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
			return false;
		}
	
		if (button.id === 'facebook_share_button_317') {
			button.onmouseover = function(){
				this.style.color='#fff';
				this.style.borderColor = '#295582';
				this.style.backgroundColor = '#3b5998';
			}
			button.onmouseout = function(){
				this.style.color = '#3b5998';
				this.style.borderColor = '#d8dfea';
				this.style.backgroundColor = '#fff';
			}
		}
	}
	-->
	</script>
	]]></content:encoded>
			<wfw:commentRss>http://www.nemediano.com.mx/2010/organizando-fotos-con-imagemagick/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Un lenguaje extraño, y un error mas extraño.</title>
		<link>http://www.nemediano.com.mx/2010/un-lenguaje-extrano-y-un-error-mas-extrano/</link>
		<comments>http://www.nemediano.com.mx/2010/un-lenguaje-extrano-y-un-error-mas-extrano/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 00:01:45 +0000</pubDate>
		<dc:creator>nemediano</dc:creator>
				<category><![CDATA[Acerca de mi]]></category>
		<category><![CDATA[Computación]]></category>
		<category><![CDATA[Mis demonios]]></category>

		<guid isPermaLink="false">http://www.nemediano.com.mx/?p=282</guid>
		<description><![CDATA[Hoy ha estado el día muy extraño, un error de aritmética entera del procesador intel de mi laptop, no me dejaba en paz, hasta que por fin se me ocurrió compilar el mismo programa en otra maquina y ahí si me funciona. Me castra, me castra, ¡¿Como es posible que ni en la aritmética entera [...]]]></description>
			<content:encoded><![CDATA[<p>Hoy ha estado el día muy extraño, un error de aritmética entera del procesador intel de mi laptop, no me dejaba en paz, hasta que por fin se me ocurrió compilar el mismo programa en otra maquina y ahí si me funciona. Me castra, me castra, ¡¿Como es posible que ni en la aritmética entera de un procesador podamos confiar?!</p>
<p>Eso no fue todo, <strong>Fatima</strong> me hizo la corrección y me sorprende tanto, es un código que a todas luces es equivalente al mio (o debería de ser para cualquier programador) y pues resulta que lo es en una maquina que no tenga procesador intel (o bueno al menos es mi conjetura).</p>
<p>El caso es que Pixie, solo lo acepta de una forma y que en Ometochtli (la maquina servidor en la que trabajamos), con un procesador AMD chorrocientas veces mas poderoso funciona a la perfección de ambas maneras).<br />
<span id="more-282"></span><br />
Para no enojarme mas reduzco mi programa mas grande a un caso de prueba, para que vean de lo que hablo:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> factor <span style="color: #000080;">=</span> <span style="color: #0000dd;">1000</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;factor * 1.345 = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>factor <span style="color: #000040;">*</span> <span style="color:#800080;">1.345</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;factor * 2.344 = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>factor <span style="color: #000040;">*</span> <span style="color:#800080;">2.344</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;1000 * 1.345 = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1000</span> <span style="color: #000040;">*</span> <span style="color:#800080;">1.345</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;1000 * 2.344 = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1000</span> <span style="color: #000040;">*</span> <span style="color:#800080;">2.344</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span></pre></div></div>

<p>La cosa es que las primeras lineas escriben:<br />
<code><br />
factor * 1.345 = 1344<br />
factor * 2.344 = 2343<br />
</code><br />
Mientras que las segundas escriben:<br />
<code><br />
1000 * 1.345 = 1345<br />
1000 * 2.344 = 2344<br />
</code><br />
Este error parece que solo esta presenta cuando los números en cuestión tienen en su parte decimal y 3 seguido de un cuatro. Es increíble pero si cambian el numero por 1.253, todo funciona perfectamente. Desde luego con cualquier caso en un procesador AMD parece que funciona bien.</p>
<p>!!!Es cierto!!! se que no me lo van a creer así que pongo el pantallazo, se que con todo y eso algunos no me van a creer. Pero ya no hay mas que pueda hacer.<br />
<a href="http://www.nemediano.com.mx/wp-content/uploads/2010/03/HorrorDeIntel.png"><img src="http://www.nemediano.com.mx/wp-content/uploads/2010/03/HorrorDeIntel-300x175.png" alt="Si es cierto!!" title="HorrorDeIntel" width="300" height="175" class="aligncenter size-medium wp-image-283" /></a><br />
Y eso no es lo mas triste del asunto, lo mas triste es la manera como lo corrigió <strong>Fatima</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">double</span> aux<span style="color: #008080;">;</span>
aux <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">double</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>factor <span style="color: #000040;">*</span> <span style="color:#800080;">1.345</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;factor * 1.345 = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>aux<span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span></pre></div></div>

<p>¡¡¡Y así si funciona!!!, Aun cuando el código es equivalente al mio. Desde luego el programa que queremos hacer es mucho mas extenso que esto, pero no me deja de molestar, que cosas así pasen, me pone muy nervioso.</p>
<p>Ya para seguir en el tono pongo un poema que vi en mi clase de ingles, que escribió Lord Cromer, que seguro en su momento se sintió como yo ahora. </p>
<h2>Our Queer Language</h2>
<blockquote><p>
When the English tongue we speak,<br />
Why is &#8220;break&#8221; not rhymed with &#8220;freak&#8221;?<br />
Will you tell me why it’s true<br />
We say &#8220;sew&#8221; but likewise &#8220;few&#8221;;</p>
<p>And the maker of a verse<br />
Cannot cap his &#8220;horse&#8221; with &#8220;worse&#8221;?<br />
&#8220;Beard&#8221; sounds not the same as &#8220;heard&#8221;;<br />
&#8220;Cord&#8221; is different from &#8220;word&#8221;;<br />
Cow is &#8220;cow,&#8221; but low is &#8220;low&#8221;;<br />
&#8220;Shoe&#8221; is never rhymed with &#8220;foe.&#8221;</p>
<p>Think of &#8220;hose&#8221; and &#8220;dose&#8221; and &#8220;lose&#8221;;<br />
&#8220;Doll&#8221; and &#8220;roll&#8221; and &#8220;home&#8221; and &#8220;some.&#8221;<br />
And since &#8220;pay&#8221; is rhymed with &#8220;say,&#8221;<br />
Why not &#8220;paid&#8221; with &#8220;said,&#8221; I pray?</p>
<p>We have &#8220;blood&#8221; and &#8220;food&#8221; and &#8220;goo d&#8221;;<br />
&#8220;Mould&#8221; is not pronounced as &#8220;could.&#8221;<br />
Wherefore &#8220;done&#8221; but &#8220;gone&#8221; and &#8220;lone&#8221;?<br />
Is there any reason known?<br />
And, in short, it seems to me,<br />
Sounds and letters disagree.
</p></blockquote>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.nemediano.com.mx%2F2010%2Fun-lenguaje-extrano-y-un-error-mas-extrano%2F&amp;t=Un%20lenguaje%20extra%C3%B1o%2C%20y%20un%20error%20mas%20extra%C3%B1o." id="facebook_share_icon_282" style="font-size:11px; line-height:13px; font-family:'lucida grande',tahoma,verdana,arial,sans-serif; text-decoration:none;"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif" alt="Share on Facebook" /></a>
	<script type="text/javascript">
	<!--
	var button = document.getElementById('facebook_share_link_282') || document.getElementById('facebook_share_icon_282') || document.getElementById('facebook_share_both_282') || document.getElementById('facebook_share_button_282');
	if (button) {
		button.onclick = function(e) {
			var url = this.href.replace(/share\.php/, 'sharer.php');
			window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
			return false;
		}
	
		if (button.id === 'facebook_share_button_282') {
			button.onmouseover = function(){
				this.style.color='#fff';
				this.style.borderColor = '#295582';
				this.style.backgroundColor = '#3b5998';
			}
			button.onmouseout = function(){
				this.style.color = '#3b5998';
				this.style.borderColor = '#d8dfea';
				this.style.backgroundColor = '#fff';
			}
		}
	}
	-->
	</script>
	]]></content:encoded>
			<wfw:commentRss>http://www.nemediano.com.mx/2010/un-lenguaje-extrano-y-un-error-mas-extrano/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Programa del copo de Koch en OpenGL</title>
		<link>http://www.nemediano.com.mx/2009/programa-del-copo-de-koch-en-opengl/</link>
		<comments>http://www.nemediano.com.mx/2009/programa-del-copo-de-koch-en-opengl/#comments</comments>
		<pubDate>Tue, 20 Jan 2009 20:54:49 +0000</pubDate>
		<dc:creator>nemediano</dc:creator>
				<category><![CDATA[Computación]]></category>
		<category><![CDATA[Mis demonios]]></category>
		<category><![CDATA[copo]]></category>
		<category><![CDATA[fractal]]></category>
		<category><![CDATA[glut]]></category>
		<category><![CDATA[koch]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[programa]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.nemediano.com.mx/?p=153</guid>
		<description><![CDATA[El semestre pasado, que me toco dar clase de Graficación por computadora, en la FESA, un amigo mio (que no tomaba clase conmigo) me pidió que le ayudara en una tarea para su clase de Sistemas Dinámicos, como la verdad no tenia mucho tiempo, hice todo lo posible por zafarme, cuando ya no pude, le [...]]]></description>
			<content:encoded><![CDATA[<p>El semestre pasado, que me toco dar clase de Graficación por computadora, en la FESA, un amigo mio (que no tomaba clase conmigo) me pidió que le ayudara en una tarea para su clase de Sistemas Dinámicos, como la verdad no tenia mucho tiempo, hice todo lo posible por zafarme, cuando ya no pude, le pregunte de que se trataba y me dijo que quería hacer un programa gráfico de un fractal, para ilustrar una exposición, que en concreto quería hacer el <a href="http://es.wikipedia.org/wiki/Copo_de_nieve_de_Koch">copo de Koch</a>.</p>
<p><span id="more-153"></span></p>
<p>Al principio me gustó la idea, después de todo, traía fresco lo de la graficada y el programa parecía ser muy sencillo, le dije que solo preparara la recurrencia matemática y que después pasaría a ayudarle, después de una semana pase a verlo y como suele suceder no había hecho nada ni yo ni el, sin embargo el programa resulto ser lo bastante simple para que solo me llevara un par de horas terminarlo.</p>
<p>Pueden descargar el código <a title="Copo koch en OpenGL" href="http://www.nemediano.com.mx/wp-content/uploads/2009/01/copokoch.c">aquí</a>. Y para probar mis últimos dos plugines agregados al blog me decidí a escribir este post. los dos plugines de los que hablo son el <a href="http://wordpress.org/extend/plugins/wp-syntax/">WP-sintax</a> que permite poner código de algún lenguaje de programación en tus post y el <a href="http://gaussianos.com/wp-latex-plugin-para-mostrar-formulas-matematicas-escritas-con-latex-en-wordpress/">WP-LaTeX</a> que agregar una fórmula escrita en LaTeX, (en forma de imagen) a tus post.</p>
<h2>Copo de Koch</h2>
<p>La primeras lineas solo incluyen las dos bibliotecas que vamos a usar, la primera es la <a href="http://es.wikipedia.org/wiki/GLUT">glut estandar</a> para levantar OpenGL y la otra es math.h, para hacer cálculos.</p>
<p>Veamos después de eso que hay:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>6
7
8
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">float</span> x<span style="color: #339933;">,</span> y<span style="color: #339933;">,</span> z<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>Punto<span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Con estas lineas definimos un nuevo tipo de dato, lo bautizamos como <strong>Punto</strong> y tiene adentro tres flotantes, para representar coordenadas, aunque el programa es en esencia bidimensional, como el OpenGL trabaja en 3D, me gusta declarar todo como si estuviera dibujando en 3D.</p>
<p>Después se declaran algunas variables globales, y el prototipo de las funciones, las variables globales son:</p>
<ul>
<li><strong>xMax, yMax:</strong> Guardan el tope de las coordenadas del mundo, es decir de donde a donde corre la parte visible de la ventana en X y en Y, con respecto al origen (situada al centro de la ventana)</li>
<li><strong>vertices:</strong> Es un arreglo de tres puntos, que guardara la única información que necesitamos para empezar a generar el copo de nieve, la posición de tres vértices.</li>
<li><strong>numPtos:</strong> Este guarda el número de vértices proporcionados por el usuario, es un contador para poner la siguiente lógica: &#8220;Si ya tienes tres puntos, empieza a hacer el fractal, si tienes menos de tres puntos, continua esperando&#8230;&#8221;</li>
<li><strong>fondo:</strong> Otro entero que guardará la profundidad máxima para hacer el fractal, donde un cero, pinta un triangulo, un uno la estrella de David y así en adelante. Es si lo quieren ver así el numero de veces que se manda a llamar recursivamente el fractal.</li>
</ul>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span><span style="color: #339933;">**</span> argv<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
   glutInit<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>argc<span style="color: #339933;">,</span> argv<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glutInitDisplayMode <span style="color: #009900;">&#40;</span>GLUT_SINGLE <span style="color: #339933;">|</span> GLUT_RGBA<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glutInitWindowSize <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">640</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">480</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glutInitWindowPosition <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">105</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glutCreateWindow <span style="color: #009900;">&#40;</span>argv<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   inicializar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   glutDisplayFunc<span style="color: #009900;">&#40;</span>dibuja<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glutReshapeFunc<span style="color: #009900;">&#40;</span>redimensiona<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glutKeyboardFunc<span style="color: #009900;">&#40;</span>teclado<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glutSpecialFunc<span style="color: #009900;">&#40;</span>tecladoEspecial<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glutMouseFunc<span style="color: #009900;">&#40;</span>raton<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   glutMainLoop<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>La función main, no mucho que decir, es muy estándar en el estilo glut, pone la maquina de estados en el estado adecuado, manda llamar a inicializar, registra cinco funciones de callback y por ultimo manda al loop principal de glut. Utilizo un solo buffer por que no voy a hacer animación, y ocupo el nombre del programa para el titulo de la ventana.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>47
48
49
50
51
52
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> inicializar <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   glClearColor<span style="color: #009900;">&#40;</span><span style="color:#800080;">0.0f</span><span style="color: #339933;">,</span> <span style="color:#800080;">0.0f</span><span style="color: #339933;">,</span> <span style="color:#800080;">0.0f</span><span style="color: #339933;">,</span> <span style="color:#800080;">0.0f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glPointSize<span style="color: #009900;">&#40;</span><span style="color:#800080;">5.0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   numPtos <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
   fondo <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>La primer función en ser ejecutada, pone el color del fondo en negro, a los puntos les da tamaño 5, inicializa el contador de puntos y a profundidad.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> redimensiona <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> ancho<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> alto<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #993333;">float</span> aspect<span style="color: #339933;">;</span>
&nbsp;
   glViewport <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> ancho<span style="color: #339933;">,</span> alto<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glMatrixMode <span style="color: #009900;">&#40;</span>GL_PROJECTION<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glLoadIdentity <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>alto <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
   	  alto <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   aspect <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">float</span><span style="color: #009900;">&#41;</span> ancho <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">float</span><span style="color: #009900;">&#41;</span> alto<span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ancho <span style="color: #339933;">&lt;=</span> alto<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   	  glOrtho<span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>MUNDO<span style="color: #339933;">,</span> MUNDO<span style="color: #339933;">,</span> <span style="color: #339933;">-</span>MUNDO<span style="color: #339933;">/</span>aspect<span style="color: #339933;">,</span> MUNDO<span style="color: #339933;">/</span>aspect<span style="color: #339933;">,</span> <span style="color: #339933;">-</span>MUNDO<span style="color: #339933;">,</span> MUNDO<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   	  xMax <span style="color: #339933;">=</span> MUNDO<span style="color: #339933;">;</span>
   	  yMax <span style="color: #339933;">=</span> MUNDO <span style="color: #339933;">/</span> aspect<span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
   	  glOrtho<span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>MUNDO <span style="color: #339933;">*</span> aspect<span style="color: #339933;">,</span> MUNDO <span style="color: #339933;">*</span> aspect<span style="color: #339933;">,</span> <span style="color: #339933;">-</span>MUNDO<span style="color: #339933;">,</span> MUNDO<span style="color: #339933;">,</span> <span style="color: #339933;">-</span>MUNDO<span style="color: #339933;">,</span> MUNDO<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   	  xMax <span style="color: #339933;">=</span> MUNDO <span style="color: #339933;">*</span> aspect<span style="color: #339933;">;</span>
   	  yMax <span style="color: #339933;">=</span> MUNDO<span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   glMatrixMode<span style="color: #009900;">&#40;</span>GL_MODELVIEW<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   glLoadIdentity<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>La función redimensiona, es llamada al inicio del programa, (el estándar de glut así lo indica) y cada vez que hay un evento de resize a la ventana. es una función muy común en estilo glut, lo único raro, quizás es que guarda en variables globales el valor de la máxima coordenada Y y la máxima coordenada X. Por lo demás es muy normal, da una proyección ortogonal, i.e: pone el sistema de referencia.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>82
83
84
85
86
87
88
89
90
91
92
93
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> teclado <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> key<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> cx<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> cy<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">27</span><span style="color: #339933;">:</span>
		   exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">default</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	glutPostRedisplay<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>La función teclado es muy simple, si detecta un evento de la tecla &#8220;Esc&#8221;, termina el programa con codigo 0.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> tecladoEspecial <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> key<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> cy<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> cx<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">case</span> GLUT_KEY_PAGE_UP<span style="color: #339933;">:</span>
		   fondo<span style="color: #339933;">++;</span>
		<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">case</span> GLUT_KEY_PAGE_DOWN<span style="color: #339933;">:</span>
		   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>fondo <span style="color: #339933;">&gt;</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> fondo<span style="color: #339933;">--;</span>
		<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">default</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	glutPostRedisplay<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Está función sirve para cachar eventos de las teclas PgUp y PgDn, y en respuesta aumenta el valor de la variable global fondo, es decir hace que el fractal itere mas o menos veces, después de poner el nuevo valor en fondo, avisa a la ventana que necesita volver a dibujarse.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> raton <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> boton<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> estado<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> cx<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> cy<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">float</span> x<span style="color: #339933;">,</span> y<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;">/* Calculamos las coordenadas de mundo (relativas) apartir de 
	 * las de ventana (absolutas) */</span>
&nbsp;
	x <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>GLfloat<span style="color: #009900;">&#41;</span>cx <span style="color: #339933;">*</span> <span style="color:#800080;">2.0</span> <span style="color: #339933;">*</span> xMax<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> glutGet<span style="color: #009900;">&#40;</span>GLUT_WINDOW_WIDTH<span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> xMax<span style="color: #339933;">;</span>
	y <span style="color: #339933;">=</span> yMax <span style="color: #339933;">-</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>GLfloat<span style="color: #009900;">&#41;</span>cy <span style="color: #339933;">*</span> <span style="color:#800080;">2.0</span> <span style="color: #339933;">*</span> yMax<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> glutGet<span style="color: #009900;">&#40;</span>GLUT_WINDOW_HEIGHT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>boton <span style="color: #339933;">==</span> GLUT_LEFT_BUTTON <span style="color: #339933;">&amp;&amp;</span> estado <span style="color: #339933;">==</span> GLUT_DOWN<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>numPtos <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		   vertices<span style="color: #009900;">&#91;</span>numPtos<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">x</span> <span style="color: #339933;">=</span> x<span style="color: #339933;">;</span>
		   vertices<span style="color: #009900;">&#91;</span>numPtos<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">y</span> <span style="color: #339933;">=</span> y<span style="color: #339933;">;</span>
		   vertices<span style="color: #009900;">&#91;</span>numPtos<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">z</span> <span style="color: #339933;">=</span> <span style="color:#800080;">0.0</span><span style="color: #339933;">;</span>
		   <span style="color: #339933;">++</span>numPtos<span style="color: #339933;">;</span>
	    <span style="color: #009900;">&#125;</span>
	    <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
	       numPtos <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	       vertices<span style="color: #009900;">&#91;</span>numPtos<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">x</span> <span style="color: #339933;">=</span> x<span style="color: #339933;">;</span>
		   vertices<span style="color: #009900;">&#91;</span>numPtos<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">y</span> <span style="color: #339933;">=</span> y<span style="color: #339933;">;</span>
		   vertices<span style="color: #009900;">&#91;</span>numPtos<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">z</span> <span style="color: #339933;">=</span> <span style="color:#800080;">0.0</span><span style="color: #339933;">;</span>
		   numPtos<span style="color: #339933;">++;</span>
	    <span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	glutPostRedisplay<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Este código cacha las acciones del ratón, las lineas 118 y 119, calculan la posicion en x y en y en donde el usuario realizo el click, recordemos que el glut, nos pasa como parámetros dos enteros que representan el pixel en el que se hizo el click, pero para la lógica de nuestro programa lo queremos en coordenadas de mundo.</p>
<p>En las lineas siguientes, se pregunta si el mouse dio click izquierdo de ser así, preguntamos cuantos puntos llevamos, si son menos de tres, seguimos esperando si no que este sea el primero, de esta manera cada cuarto punto se <em>resetea</em>, el estado del programa, así que si después de pintar un fractal queremos pintar otro simplemente damos un nuevo click y ese es el primer punto de un nuevo fractal.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> dibuja <span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>
&nbsp;
	glClear<span style="color: #009900;">&#40;</span>GL_COLOR_BUFFER_BIT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	glMatrixMode<span style="color: #009900;">&#40;</span>GL_MODELVIEW<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	glLoadIdentity<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>numPtos <span style="color: #339933;">!=</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	   glColor3f<span style="color: #009900;">&#40;</span><span style="color:#800080;">1.0</span><span style="color: #339933;">,</span> <span style="color:#800080;">1.0</span><span style="color: #339933;">,</span> <span style="color:#800080;">1.0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	   glBegin<span style="color: #009900;">&#40;</span>GL_POINTS<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	      <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span>numPtos<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	   	     glVertex3f<span style="color: #009900;">&#40;</span>vertices<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">x</span><span style="color: #339933;">,</span> vertices<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">y</span><span style="color: #339933;">,</span> vertices<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">z</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	      <span style="color: #009900;">&#125;</span>
	   glEnd<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>numPtos <span style="color: #339933;">==</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	   glColor3f<span style="color: #009900;">&#40;</span><span style="color:#800080;">1.0</span><span style="color: #339933;">,</span> <span style="color:#800080;">1.0</span><span style="color: #339933;">,</span> <span style="color:#800080;">0.0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	   glBegin<span style="color: #009900;">&#40;</span>GL_LINE_STRIP<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	      koch<span style="color: #009900;">&#40;</span>vertices<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> vertices<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	      koch<span style="color: #009900;">&#40;</span>vertices<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> vertices<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	      koch<span style="color: #009900;">&#40;</span>vertices<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> vertices<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	   glEnd<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
&nbsp;
	glFlush<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Esta función se encarga de dibujar el fractal, primero limpia la pantalla, luego pone el estado de dibujar y pregunta si tenemos algún numero de puntos que no sea tres (por la lógica de la función anterior esto solo puede pasar cuando son menos que tres) de ser así solo pone los puntos que llevamos. En caso contrario se prepara a dibujar el fractal, para esto hace uso de la función auxiliar koch, que da los vértices de una curva de koch, así que para hacer el copo de koch, pinta tres curvas de koch: Una del vértice 0, al vértice 1, otra del vértice 1 al vértice 2 y por ultimo una que cierra el copo del vértice 2 al vértice 0.</p>
<h2>Dibujando la curva de Koch</h2>
<p>Ahora viene la parte mas interesante:  ¿Como se dibuja la curva de Koch?<br />
La función encargada de hacerlo es la función <strong>koch</strong>, pide como argumento dos puntos y un entero, que es el nivel de profundidad en la recursividad del algoritmo, es decir: la primera vez que se llame tendrá valor 0, la segunda vez que se llame tendrá valor 1 y así sucesivamente. Aquí esta el código de la función:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> koch <span style="color: #009900;">&#40;</span>Punto p0<span style="color: #339933;">,</span> Punto p1<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> profundidad<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	Punto a<span style="color: #339933;">,</span> b<span style="color: #339933;">,</span> p2<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>profundidad <span style="color: #339933;">&lt;</span> fondo<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		a.<span style="color: #202020;">x</span> <span style="color: #339933;">=</span> <span style="color:#800080;">2.0</span> <span style="color: #339933;">/</span> <span style="color:#800080;">3.0</span> <span style="color: #339933;">*</span> p0.<span style="color: #202020;">x</span> <span style="color: #339933;">+</span> <span style="color:#800080;">1.0</span> <span style="color: #339933;">/</span> <span style="color:#800080;">3.0</span> <span style="color: #339933;">*</span> p1.<span style="color: #202020;">x</span><span style="color: #339933;">;</span>
		a.<span style="color: #202020;">y</span> <span style="color: #339933;">=</span> <span style="color:#800080;">2.0</span> <span style="color: #339933;">/</span> <span style="color:#800080;">3.0</span> <span style="color: #339933;">*</span> p0.<span style="color: #202020;">y</span> <span style="color: #339933;">+</span> <span style="color:#800080;">1.0</span> <span style="color: #339933;">/</span> <span style="color:#800080;">3.0</span> <span style="color: #339933;">*</span> p1.<span style="color: #202020;">y</span><span style="color: #339933;">;</span>
		a.<span style="color: #202020;">z</span> <span style="color: #339933;">=</span> <span style="color:#800080;">0.0</span><span style="color: #339933;">;</span>
&nbsp;
		b.<span style="color: #202020;">x</span> <span style="color: #339933;">=</span> <span style="color:#800080;">1.0</span> <span style="color: #339933;">/</span> <span style="color:#800080;">3.0</span> <span style="color: #339933;">*</span> p0.<span style="color: #202020;">x</span> <span style="color: #339933;">+</span> <span style="color:#800080;">2.0</span> <span style="color: #339933;">/</span> <span style="color:#800080;">3.0</span> <span style="color: #339933;">*</span> p1.<span style="color: #202020;">x</span><span style="color: #339933;">;</span>
		b.<span style="color: #202020;">y</span> <span style="color: #339933;">=</span> <span style="color:#800080;">1.0</span> <span style="color: #339933;">/</span> <span style="color:#800080;">3.0</span> <span style="color: #339933;">*</span> p0.<span style="color: #202020;">y</span> <span style="color: #339933;">+</span> <span style="color:#800080;">2.0</span> <span style="color: #339933;">/</span> <span style="color:#800080;">3.0</span> <span style="color: #339933;">*</span> p1.<span style="color: #202020;">y</span><span style="color: #339933;">;</span>
		b.<span style="color: #202020;">z</span> <span style="color: #339933;">=</span> <span style="color:#800080;">0.0</span><span style="color: #339933;">;</span>
&nbsp;
		p2.<span style="color: #202020;">x</span> <span style="color: #339933;">=</span> <span style="color:#800080;">0.5</span> <span style="color: #339933;">*</span> p0.<span style="color: #202020;">x</span> <span style="color: #339933;">+</span> <span style="color:#800080;">0.5</span> <span style="color: #339933;">*</span> p1.<span style="color: #202020;">x</span> <span style="color: #339933;">+</span> a.<span style="color: #202020;">y</span> <span style="color: #339933;">-</span> b.<span style="color: #202020;">y</span><span style="color: #339933;">;</span>
		p2.<span style="color: #202020;">y</span> <span style="color: #339933;">=</span> <span style="color:#800080;">0.5</span> <span style="color: #339933;">*</span> p0.<span style="color: #202020;">y</span> <span style="color: #339933;">+</span> <span style="color:#800080;">0.5</span> <span style="color: #339933;">*</span> p1.<span style="color: #202020;">y</span> <span style="color: #339933;">+</span> b.<span style="color: #202020;">x</span> <span style="color: #339933;">-</span> a.<span style="color: #202020;">x</span><span style="color: #339933;">;</span>
		p2.<span style="color: #202020;">z</span> <span style="color: #339933;">=</span> <span style="color:#800080;">0.0</span><span style="color: #339933;">;</span>
&nbsp;
		glVertex3f<span style="color: #009900;">&#40;</span>p0.<span style="color: #202020;">x</span><span style="color: #339933;">,</span> p0.<span style="color: #202020;">y</span><span style="color: #339933;">,</span> p0.<span style="color: #202020;">z</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		koch<span style="color: #009900;">&#40;</span>p0<span style="color: #339933;">,</span> a<span style="color: #339933;">,</span> profundidad <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		glVertex3f<span style="color: #009900;">&#40;</span>a.<span style="color: #202020;">x</span><span style="color: #339933;">,</span> a.<span style="color: #202020;">y</span><span style="color: #339933;">,</span> a.<span style="color: #202020;">z</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		koch<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> p2<span style="color: #339933;">,</span> profundidad <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		glVertex3f<span style="color: #009900;">&#40;</span>p2.<span style="color: #202020;">x</span><span style="color: #339933;">,</span> p2.<span style="color: #202020;">y</span><span style="color: #339933;">,</span> p2.<span style="color: #202020;">z</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		koch<span style="color: #009900;">&#40;</span>p2<span style="color: #339933;">,</span> b<span style="color: #339933;">,</span> profundidad <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		glVertex3f<span style="color: #009900;">&#40;</span>b.<span style="color: #202020;">x</span><span style="color: #339933;">,</span> b.<span style="color: #202020;">y</span><span style="color: #339933;">,</span> b.<span style="color: #202020;">z</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		koch<span style="color: #009900;">&#40;</span>b<span style="color: #339933;">,</span> p1<span style="color: #339933;">,</span> profundidad <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		glVertex3f<span style="color: #009900;">&#40;</span>p1.<span style="color: #202020;">x</span><span style="color: #339933;">,</span> p1.<span style="color: #202020;">y</span><span style="color: #339933;">,</span> p1.<span style="color: #202020;">z</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span> 
&nbsp;
	<span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>En la linea 176, se pregunta cuantas veces se ha ejecutado esta función en la recursión, si es mas que lo que vale la variable <strong>fondo</strong>, regresa sin hacer ninguna operación, poniendo fin a la recursión. Sin embargo si aun es menor, se ejecutan los cálculos necesarios (se hace otra iteración) y dentro del procedimiento se llama recursivamente la función koch aumentando el nivel de profundidad.</p>
<p>La lógica de la función koch se explica a continuación:</p>
<p>La idea principal es que como entrada tenemos dos puntos (<strong>p0</strong> y <strong>p1</strong>), los cuales representan un segmento y queremos a partir de ellos calcular tres puntos mas (<strong>a</strong>, <strong>b</strong> y <strong>p2</strong>). Como se ve en la figura:</p>
<div id="attachment_180" class="wp-caption alignnone" style="width: 310px"><a href="http://www.nemediano.com.mx/wp-content/uploads/2009/01/koch1.png"><img src="http://www.nemediano.com.mx/wp-content/uploads/2009/01/koch1-300x62.png" alt="Segmento de recta" title="koch1" width="300" height="62" class="size-medium wp-image-180" /></a><p class="wp-caption-text">Segmento de recta</p></div>
<p>Para calcular cada uno de estos puntos, se hace uso de la ecuación paramétrica de un segmento de recta. Si tenemos dos puntos <strong>p</strong> y <strong>q</strong> entonces la ecuación paramétrica en <strong>t</strong>, del semento de recta entre <strong>p</strong> y <strong>q</strong> es: <img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=s%28t%29+%3D+%281-t%29%5Cvec%7Bp%7D+%2B+t%5Cvec%7Bq%7D&bg=FFFFFF&fg=000000'  alt="s(t) = (1-t)\vec{p} + t\vec{q}" /> con <img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=0+%5Cleq+t+%5Cleq+1&bg=FFFFFF&fg=000000'  alt="0 \leq t \leq 1" /> con esta ecuación podemos calcular fácilmente tanto <strong>a</strong>, como <strong>b</strong>. Sin embargo para calcular <strong>p2</strong> tendremos que hacer algunas cosas mas.</p>
<div id="attachment_181" class="wp-caption alignnone" style="width: 310px"><a href="http://www.nemediano.com.mx/wp-content/uploads/2009/01/koch2.png"><img src="http://www.nemediano.com.mx/wp-content/uploads/2009/01/koch2-300x126.png" alt="Puntos a calcular en el nuevo segmento de koch" title="koch2" width="300" height="126" class="size-medium wp-image-181" /></a><p class="wp-caption-text">Puntos a calcular en el nuevo segmento de koch</p></div>
<p>Primero calculamos el punto medio del segmento, a ese vector hay que sumarle la <em>elevación</em> del nuevo punto, para calcularla necesitamos sumarle un nuevo vector que sea perpendicular al segmento, para esto utilizamos el hecho de que el producto punto de dos vectores perpendiculares entre si, siempre es cero. Así que construimos el vector que va de a a b y de ahí lo volteamos es decir:</p>
<p>Dado un vector:</p>
<p><img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=%5Cleft%28+%5Cbegin%7Barray%7D%7Bc%7D+x++%5C%5C+y+%5Cend%7Barray%7D+%5Cright%29&bg=FFFFFF&fg=000000'  alt="\left( \begin{array}{c} x  \\ y \end{array} \right)" /></p>
<p>Es perpendicular a el vector <strong>v</strong> dado por:</p>
<p><img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=%5Cvec%7Bv%7D+%3D+%5Cleft%28+%5Cbegin%7Barray%7D%7Bc%7D+-y+%5C%5C+x+%5Cend%7Barray%7D+%5Cright%29&bg=FFFFFF&fg=000000'  alt="\vec{v} = \left( \begin{array}{c} -y \\ x \end{array} \right)" /></p>
<p>Por lo que podemos encontrar el punto <strong>p2</strong> de la siguiente manera:</p>
<p><img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=%5Cvec%7Bp_2%7D+%3D+%5Cdfrac%7B1%7D%7B2%7D%5Cvec%7Bp_0%7D+%2B+%5Cdfrac%7B1%7D%7B2%7D%5Cvec%7Bp_1%7D+%2B+%5Cleft%28+%5Cbegin%7Barray%7D%7Bc%7D+a_%7By%7D-b_%7By%7D+%5C%5C+b_%7Bx%7D-a_%7Bx%7D+%5Cend%7Barray%7D+%5Cright%29&bg=FFFFFF&fg=000000'  alt="\vec{p_2} = \dfrac{1}{2}\vec{p_0} + \dfrac{1}{2}\vec{p_1} + \left( \begin{array}{c} a_{y}-b_{y} \\ b_{x}-a_{x} \end{array} \right)" /></p>
<p>Recordemos que el vector que va de <strong>a</strong> a <strong>b</strong> se puede ver como <strong>b-a</strong>.</p>
<h2>Descargas</h2>
<ul>
<li><a title="Copo koch en OpenGL" href="http://www.nemediano.com.mx/wp-content/uploads/2009/01/copokoch.c">Código fuente el programa</a></li>
<li><a href="http://www.nemediano.com.mx/wp-content/uploads/2009/01/copo-de-koch.exe">Ejecutable de win32</a></li>
</ul>
<p>¿Por que solo pongo el ejecutable para Windows, si yo siempre uso GNU/Linux?, por que los usuarios del lado luminoso de la fuerza les conviene mas compilar el fuente, que al cabo es solo uno, recuerden que deberán tener instalado OpenGL y glut.</p>
<h2>Pantallazos</h2>
<div class="ngg-galleryoverview" id="ngg-gallery-12-153">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://www.nemediano.com.mx/2009/programa-del-copo-de-koch-en-opengl/?show=slide">
			[Show as slideshow]		</a>
	</div>

	
	<!-- Thumbnails -->
		
	<div id="ngg-image-87" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.nemediano.com.mx/wp-content/gallery/kochopengl/Pantallazo-.-copoKoch-1.png" title="Un copo de Koch, chueco por la forma en que se crearon sus vértices iniciales" class="thickbox" rel="set_12" >
								<img title="Pantallazo-.-copoKoch-1.png" alt="Pantallazo-.-copoKoch-1.png" src="http://www.nemediano.com.mx/wp-content/gallery/kochopengl/thumbs/thumbs_Pantallazo-.-copoKoch-1.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-88" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.nemediano.com.mx/wp-content/gallery/kochopengl/Pantallazo-.-copoKoch-2.png" title="Un anticopo de koch simétrico, en el programa se produce dando los click en sentido contrario a las manecillas del reloj" class="thickbox" rel="set_12" >
								<img title="Pantallazo-.-copoKoch-2.png" alt="Pantallazo-.-copoKoch-2.png" src="http://www.nemediano.com.mx/wp-content/gallery/kochopengl/thumbs/thumbs_Pantallazo-.-copoKoch-2.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-89" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.nemediano.com.mx/wp-content/gallery/kochopengl/Pantallazo-.-copoKoch-3.png" title="Una instancias un poco rara del copo de Koch, es en realidad un anticopo de Koch" class="thickbox" rel="set_12" >
								<img title="Pantallazo-.-copoKoch-3.png" alt="Pantallazo-.-copoKoch-3.png" src="http://www.nemediano.com.mx/wp-content/gallery/kochopengl/thumbs/thumbs_Pantallazo-.-copoKoch-3.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-90" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.nemediano.com.mx/wp-content/gallery/kochopengl/Pantallazo-.-copoKoch-4.png" title="Una instancia con solo tres iteraciones del copo de Koch" class="thickbox" rel="set_12" >
								<img title="Pantallazo-.-copoKoch-4.png" alt="Pantallazo-.-copoKoch-4.png" src="http://www.nemediano.com.mx/wp-content/gallery/kochopengl/thumbs/thumbs_Pantallazo-.-copoKoch-4.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-91" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.nemediano.com.mx/wp-content/gallery/kochopengl/Pantallazo-.-copoKoch.png" title="Una instancia con cinco iteraciones del copo de Koch" class="thickbox" rel="set_12" >
								<img title="Pantallazo-.-copoKoch.png" alt="Pantallazo-.-copoKoch.png" src="http://www.nemediano.com.mx/wp-content/gallery/kochopengl/thumbs/thumbs_Pantallazo-.-copoKoch.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>

<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.nemediano.com.mx%2F2009%2Fprograma-del-copo-de-koch-en-opengl%2F&amp;t=Programa%20del%20copo%20de%20Koch%20en%20OpenGL" id="facebook_share_icon_153" style="font-size:11px; line-height:13px; font-family:'lucida grande',tahoma,verdana,arial,sans-serif; text-decoration:none;"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif" alt="Share on Facebook" /></a>
	<script type="text/javascript">
	<!--
	var button = document.getElementById('facebook_share_link_153') || document.getElementById('facebook_share_icon_153') || document.getElementById('facebook_share_both_153') || document.getElementById('facebook_share_button_153');
	if (button) {
		button.onclick = function(e) {
			var url = this.href.replace(/share\.php/, 'sharer.php');
			window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
			return false;
		}
	
		if (button.id === 'facebook_share_button_153') {
			button.onmouseover = function(){
				this.style.color='#fff';
				this.style.borderColor = '#295582';
				this.style.backgroundColor = '#3b5998';
			}
			button.onmouseout = function(){
				this.style.color = '#3b5998';
				this.style.borderColor = '#d8dfea';
				this.style.backgroundColor = '#fff';
			}
		}
	}
	-->
	</script>
	]]></content:encoded>
			<wfw:commentRss>http://www.nemediano.com.mx/2009/programa-del-copo-de-koch-en-opengl/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Hay LaTeX en wordpress!!!</title>
		<link>http://www.nemediano.com.mx/2009/hay-latex-en-wordpress/</link>
		<comments>http://www.nemediano.com.mx/2009/hay-latex-en-wordpress/#comments</comments>
		<pubDate>Sat, 03 Jan 2009 06:38:29 +0000</pubDate>
		<dc:creator>nemediano</dc:creator>
				<category><![CDATA[Computación]]></category>
		<category><![CDATA[Mis demonios]]></category>
		<category><![CDATA[LaTeX]]></category>
		<category><![CDATA[matematicas]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://www.nemediano.com.mx/?p=133</guid>
		<description><![CDATA[Haciendo una prueba. Otra prueba: Una prueba mas: Puta Madre estoy que no me la acabo, es cierto hay un plugin que no requiere de todos los hacks del anterior plugin, me funciono de inmediato, esto es la wea!!!! Se puede escribir en wordpress con LaTeX Me cacho que no me la acabo, es la [...]]]></description>
			<content:encoded><![CDATA[<p>Haciendo una prueba.<br />
<img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=%5CLaTeX&bg=FFFFFF&fg=000000'  alt="\LaTeX" /></p>
<p>Otra prueba:</p>
<p><img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=%5Cdfrac%7Ba%7D%7Bb%7D+%2B+%5Cfrac%7Bc%7D%7Bd%7D+%3D+%5Cdfrac%7Bad+%2B+cb%7D%7Bdb%7D&bg=FFFFFF&fg=000000'  alt="\dfrac{a}{b} + \frac{c}{d} = \dfrac{ad + cb}{db}" /></p>
<p>Una prueba mas:</p>
<p><img style="border:0px;vertical-align:middle;" src='http://l.wordpress.com/latex.php?latex=%5Cint_%7B0%7D%5E%7B%5Cinfty%7D+x+dx+%3D+F%28x%29+%2B+C&bg=FFFFFF&fg=000000'  alt="\int_{0}^{\infty} x dx = F(x) + C" /></p>
<p>Puta Madre estoy que no me la acabo, es cierto hay un plugin que no requiere de todos los hacks del anterior plugin, me funciono de inmediato, esto es la wea!!!!</p>
<p>Se puede escribir en wordpress con LaTeX</p>
<p>Me cacho que no me la acabo, es la neta del planeta <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  <img src='http://www.nemediano.com.mx/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Aqui el <a title="LaTeX en WP" href="http://gaussianos.com/wp-latex-plugin-para-mostrar-formulas-matematicas-escritas-con-latex-en-wordpress/" target="_blank">enlace</a> que me funciono, ahhhh sigo en shock.</p>
<p>Estoy usando WP 2.6, en un servidor estandar.</p>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.nemediano.com.mx%2F2009%2Fhay-latex-en-wordpress%2F&amp;t=Hay%20LaTeX%20en%20wordpress%21%21%21" id="facebook_share_icon_133" style="font-size:11px; line-height:13px; font-family:'lucida grande',tahoma,verdana,arial,sans-serif; text-decoration:none;"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif" alt="Share on Facebook" /></a>
	<script type="text/javascript">
	<!--
	var button = document.getElementById('facebook_share_link_133') || document.getElementById('facebook_share_icon_133') || document.getElementById('facebook_share_both_133') || document.getElementById('facebook_share_button_133');
	if (button) {
		button.onclick = function(e) {
			var url = this.href.replace(/share\.php/, 'sharer.php');
			window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
			return false;
		}
	
		if (button.id === 'facebook_share_button_133') {
			button.onmouseover = function(){
				this.style.color='#fff';
				this.style.borderColor = '#295582';
				this.style.backgroundColor = '#3b5998';
			}
			button.onmouseout = function(){
				this.style.color = '#3b5998';
				this.style.borderColor = '#d8dfea';
				this.style.backgroundColor = '#fff';
			}
		}
	}
	-->
	</script>
	]]></content:encoded>
			<wfw:commentRss>http://www.nemediano.com.mx/2009/hay-latex-en-wordpress/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Poniendo un entorno de desarrollo Java en Ubuntu</title>
		<link>http://www.nemediano.com.mx/2008/poniendo-un-entorno-de-desarrollo-java-en-ubuntu/</link>
		<comments>http://www.nemediano.com.mx/2008/poniendo-un-entorno-de-desarrollo-java-en-ubuntu/#comments</comments>
		<pubDate>Mon, 08 Sep 2008 01:12:28 +0000</pubDate>
		<dc:creator>nemediano</dc:creator>
				<category><![CDATA[Acerca de mi]]></category>
		<category><![CDATA[Computación]]></category>
		<category><![CDATA[Recetario de Ubuntu]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jsp]]></category>
		<category><![CDATA[manual]]></category>
		<category><![CDATA[programar]]></category>
		<category><![CDATA[servlet]]></category>
		<category><![CDATA[sun]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://www.nemediano.com.mx/2008/poniendo-un-entorno-de-desarrollo-java-en-ubuntu/</guid>
		<description><![CDATA[En el posgrado, en la clase de Programación Avanzada muy para mi desagrado nos han obligado a programar en Java. Aunque la clase pinta ser bastante interesante, por que ha tomado un poco el tinte de cátedra, no pude evitar mi decepción cuando nos dijeron que el curso giraría en torno al desarrollo en Java. [...]]]></description>
			<content:encoded><![CDATA[<p>En el <a href="http://www.mcc.unam.mx/" target="_blank">posgrado</a>, en la clase de <a href="http://hp.fciencias.unam.mx/~alg/pAvz/" target="_blank">Programación Avanzada</a> muy para mi desagrado nos han obligado a programar en Java.</p>
<p>Aunque la clase pinta ser bastante interesante, por que ha tomado un poco el tinte de cátedra, no pude evitar mi decepción cuando nos dijeron que el curso giraría en torno al desarrollo en Java.</p>
<p>El primer profesor es la <a href="http://hp.fciencias.unam.mx/~alg/" target="_blank">Dra. Amparo Lopez</a>, su clase ha sido un poco aburrida para mi, por que ella misma admitió que seria un curso introductorio y que los que ya supiéramos programar en Java podríamos saltarnos su parte de la cátedra, (vía un proyecto en Java).</p>
<p>Como he decidido quedarme, y se que para las demás partes de la cátedra sera importante tener un entorno de desarrollo completo en Java he decidido escribir este post.</p>
<p>Este post debería de servirle a cualquier estudiante que quiera (o tenga) que aprender java</p>
<p><span id="more-67"></span></p>
<h2>¿Que es lo que entiendo por entorno de desarrollo Java?</h2>
<p>Queremos tener un compilado Java, para esto usar el JDK de <strong>sun</strong>, es decir <strong>no queremos</strong> la alternativa libre.</p>
<p>Queremos tener un IDE muy eficiente. Para esto usaremos <a href="http://www.eclipse.org/" target="_blank">eclipse</a>, por ser software libre y por ser a mi juicio y el de muchas personas que conozco, el mejor IDE para desarrollar en Java (propietarios incluidos).</p>
<p>Queremos un servidor/contenedor de <a href="http://en.wikipedia.org/wiki/Java_Servlet" target="_blank">servlets</a> y <a href="http://en.wikipedia.org/wiki/JavaServer_Pages" target="_blank">JSP&#8217;s</a>, para esto utilizaremos uno de los mejores: <a href="http://tomcat.apache.org/" target="_blank">apache tomcat</a> por aquello de que también es software libre.</p>
<p>En resumen:</p>
<ul>
<li>JDK de sun (vía repositorios).</li>
<li>Eclipse EE para desarrollo en Java (descargado del web).</li>
<li>Servidor Web Tomcat (descargado del web).</li>
</ul>
<h2>De donde partimos</h2>
<p>Hago las siguientes suposiciones:</p>
<p>Que tienes ya instalado Ubuntu (Yo estoy probando en 8.04, pero pienso que puedes adaptar estos pasos a tus necesidades fácilmente).</p>
<p>Que vamos a levantar Tomcat no como servicio, si no <strong>dentro de Eclipse</strong>, y por el puerto <strong>8080</strong>, esto con el fin de que si ya tenemos otro servidor web (por ejemplo un <a href="http://en.wikipedia.org/wiki/LAMP_(software_bundle)" target="_blank">LAMP</a>) no tengan conflictos. Y además si es un entorno de desarrollo, probablemente tengas un servidor dedicado en algún otro lado.</p>
<p>Asumimos que <strong>no tenemos</strong> instalado el Eclipse de los repositorios. Por que al instalarlo también instala el java libre y lo usara en vez de usar el de sun.</p>
<p><strong>Advertencia:</strong> Considero que eclipse es el mejor IDE de Java, pero eso no quiere decir que sea ligero, no recomiendo instalarlo en maquinas de menos de 512MB de RAM y al menos otro tanto de swap</p>
<h2>Instalando Java JDK de Sun</h2>
<p>Este es el único paquete que nos traeremos de los repositorios, por su sencillez y que no esta tan atrasado respecto a las versiones disponibles del web. Además así nos evitamos setear un montón de variables de entorno manualmente. Así que instalamos ya sea vía apt o synaptic los siguientes paquetes:</p>
<ul>
<li>sun-java6-bin</li>
<li>sun-java6-demo</li>
<li>sun-java6-jdk</li>
<li>sun-java6-jre</li>
<li>sun-java6-doc</li>
</ul>
<p>El paquete sun-java6-doc es opcional si queremos tener la documentación. Desgraciadamente este es un metapaquete que no contiene la documentación. Así que si deseamos instalarlo, tendremos que ir a la <a href="http://java.sun.com/javase/downloads/index.jsp#docs" target="_blank">pagina de sun</a>, descargar la documentación de java, una archivo llamado <em>jdk-6-doc.zip</em>, luego cambiarle de dueño a root, y moverlo a /tmp. Después decirle a synaptic o apt que instalen el paquete.</p>
<p>Asumiendo que estamos parados en donde esta el archivo descargado:</p>
<p><code>sudo chown root:root jdk-6-doc.zip<br />
mv jdk-6-doc.zip /tmp<br />
sudo apt-get install sun-java6-doc</code></p>
<h2>Instalamos Eclipse</h2>
<p>Lo descargamos del <a href="http://www.eclipse.org/downloads/" target="_blank">sitio oficial</a>, queremos la versión que dice: <em>Eclipse IDE for Java EE Developers</em> por que es el mas completo para nuestros propósitos.</p>
<p>Podríamos usar cualquier otro y después instalarle los paquetes adicionales que nos hagan falta, pero ¿Para que molestarnos? Si podemos descargar uno que ya viene listo para usarse con Java.</p>
<p>Una vez que lo descarguemos, solo hace falta descomprimirlo en algún lado, lo mas recomendable es ponerlo en alguna carpeta usada comúnmente para guardar programas, yo ocupe /opt pero también podría funcionar /usr/local por aquello de la buena educación.</p>
<p>Supongamos que estamos parados donde se hizo la descarga:</p>
<p><code>tar -xzvf eclipse-jee-ganymede-linux-gtk.tar.gz<br />
sudo mv eclipse/ /opt</code></p>
<p>Ahora sólo nos hace falta crear un lanzador para usar Eclipse, asumiedo que usamos Gnome, vamos a <em>Sistema -&gt; Preferencias -&gt; Menú Principal</em>. Se abrira <strong>alacarte</strong> seleccionamos un el menú donde queremos crear el lanzador, un buen lugar es <strong>Programación</strong>, y de ahi le damos <strong>Elemento nuevo</strong>.</p>
<p>Llenamos los datos que nos piden: el tipo es Aplicación, el nombre Eclipse, en comando le damos examinar y buscamos el ejecutable se llama <strong>eclipse</strong>, y esta dentro de <em>la carpeta eclipse.</em>. El eclipse EE para java al parecer viene sin icono, puedes buscar alguno en la web, <a title="Icono de Eclipse" href="http://www.nemediano.com.mx/wp-content/uploads/2008/09/icon.png" target="_blank">aqui</a> pongo uno por si te sirve.</p>
<p>Un pantallazo de la de como le hize yo:</p>
<p><a href="http://www.nemediano.com.mx/wp-content/uploads/2008/09/propiedades-del-lanzador.png"><img class="alignnone size-thumbnail wp-image-70" title="propiedades-del-lanzador" src="http://www.nemediano.com.mx/wp-content/uploads/2008/09/propiedades-del-lanzador-150x150.png" alt="" width="150" height="150" /></a></p>
<h2>Instalando Apache Tomcat</h2>
<p>Primero vamos al <a href="http://tomcat.apache.org/" target="_blank">sitio de Apache tomcat</a>, y de ahí descargamos la ultima versión, cuando escribí esto era la rama 6.x la versión 6.0.18 y de ahí descargamos la distribución .tar.gz. (en realidad cualquiera hubiera servido, pues son multiplataforma, pero por costumbre en Linux el usamos la que viene compresa .gz).</p>
<p>Ahora descomprimimos tomcat y lo movemos a algún directorio apropiado, de nuevo yo uso /opt.</p>
<p><code>tar -xzvf apache-tomcat-6.0.18.tar.gz<br />
sudo mv apache-tomcat-6.0.18 /opt/apache-tomcat</code></p>
<p>Liiisto esa es la instalación de tomcat, si queremos probarlo, podemos ejecutar el archivo <strong>start.sh</strong> para arrancar Tomcat y <strong>shutdown.sh</strong> para detenerlo. Ambos viven en el directorio <strong>bin</strong>, dentro del directorio de Tomcat.</p>
<p><code>/opt/apache-tomcat/bin/startup.sh<br />
/opt/apache-tomcat/bin/shutdown.sh</code></p>
<p>Para probar podemos arrancar Tomcat y abrir nuestro navegador en el sitio http://localhost:8080, donde nos debe contestar Tomcat dándonos la bienvenida. Si quieres ver que hace, puedes navegar a Miscellaneous y de ahí ejecutar alguno de los JSP o de los Servlets que trae de ejemplo. También recomendaría editar el archivo $CATALINA_HOME/conf/tomcat-users.xml y añadir a un usuario con privilegios de administración para usar el manager.</p>
<p>Aquí hay un ejemplo de como hacer una edición básica del archivo: tomcat-users.xml</p>
<pre>&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;tomcat-users&gt;
  &lt;role rolename="manager"/&gt;
  &lt;role rolename="admin"/&gt;
  &lt;user username="jorge" password="secreto" roles="admin,manager"/&gt;
&lt;/tomcat-users&gt;</pre>
<h2>Poniendo todo junto</h2>
<p>Ahora viene lo divertido, hay que decirle a Eclipse, donde esta Tomcat, esto tiene la enorme ventaja que así él podrá arrancarlo cuando lo use y pararlo cuando no. Es decir prácticamente administra él.</p>
<p>Primero ejecutamos eclipse, al lanzarlo por primera vez se ve una pantalla de bienvenida: En esta pantalla podemos leer la documentación y ver algunos tutoriales de eclipse, es muy recomendable leerlos en algún momento. Por ahora vamos directamente al <em>workbench</em>.</p>
<p><a href="http://www.nemediano.com.mx/wp-content/uploads/2008/09/pantallazo-java-eclipse-platform.png"><img class="alignnone size-thumbnail wp-image-73" title="pantallazo-java-eclipse-platform" src="http://www.nemediano.com.mx/wp-content/uploads/2008/09/pantallazo-java-eclipse-platform-150x150.png" alt="" width="150" height="150" /></a></p>
<p>En la parte superior del <em>workbench</em> el primer icono que encontramos de izquierda a derecha es el de <strong>New</strong>, lo presionamos y abre un submenu, ahí le damos la ultima opción la que dice <strong>Other</strong>.</p>
<p>Se abre una ventana pidiéndote que selecciones el asistente, buscamos en la carpeta de <strong>Servers</strong>, aquel que dice <strong>Server</strong> y le damos <strong>Next</strong></p>
<p><a href="http://www.nemediano.com.mx/wp-content/uploads/2008/09/pantallazo-new.png"><img class="alignnone size-thumbnail wp-image-74" title="pantallazo-new" src="http://www.nemediano.com.mx/wp-content/uploads/2008/09/pantallazo-new-150x150.png" alt="" width="150" height="150" /></a></p>
<p><strong>Una aclaración:</strong> eclipse solo puede tener un servidor de cada tipo y versión corriendo a la vez, así que si ya definiste algún servidor Tomcat 6.0 antes, no te dejará hacerlo de nuevo hasta que lo borres y lo vuelvas a crear (o cambies de workspace)</p>
<p>En la siguiente pantalla te pide que digas que tipo de Servidor seleccionas la carpeta de <strong>Apache</strong> y el servidor tipo <strong>Tomcat v6.0 Server</strong>, es importante también que le digas que el nombre del host es <strong>localhost</strong>. Y en el nombre del servidor le puedes poner lo que quieras el default esta bien.</p>
<p><a href="http://www.nemediano.com.mx/wp-content/uploads/2008/09/pantallazo-new-server.png"><img class="alignnone size-thumbnail wp-image-75" title="pantallazo-new-server" src="http://www.nemediano.com.mx/wp-content/uploads/2008/09/pantallazo-new-server-150x150.png" alt="" width="150" height="150" /></a></p>
<p>En donde dice <strong>Server Runtime enviroment</strong> le damos Add y se abre otro cuadro de dialogo, aquí lo importante es que le digamos donde esta instalado el Tomcat como se ve en la pantalla.</p>
<p><a href="http://www.nemediano.com.mx/wp-content/uploads/2008/09/pantallazo-new-server-runtime-environment.png"><img class="alignnone size-thumbnail wp-image-76" title="pantallazo-new-server-runtime-environment" src="http://www.nemediano.com.mx/wp-content/uploads/2008/09/pantallazo-new-server-runtime-environment-150x150.png" alt="" width="150" height="150" /></a></p>
<p>Si todo esta bien le puedes dar <strong>Finish</strong> y se &#8220;crea&#8221; el Server dentro de eclipse.</p>
<h2>Probando la instalación</h2>
<p>Cada que quieras hacer un nuevo proyecto con JSP&#8217;s o Servlets, creas un nuevo proyecto de tipo <strong>Web</strong> y luego <strong>Dinamic Web Project</strong> y te fijas que el <strong>Target Runtime Enviroment</strong> sea el servidor que recién creamos.</p>
<p>Para efectos de prueba, puedes descargarte <a href="http://www.nemediano.com.mx/wp-content/uploads/2008/09/intro-app-eclipse.zip">este proyecto</a> de prueba, e intentar ejecutarlo. Desde el menú <strong>File</strong>, <strong>Import</strong>, <strong>General</strong>, <strong>Existing Proyect into Workspace</strong>, <strong>Select Archive File</strong> y seleccionar el zip recién descargado.</p>
<p>Una vez importado desde la pestaña de servers <strong>arrancas el Servidor Tomcat</strong>, luego navegas dentro del proyecto recién importando y le pides que te muestre el JSP de prueba debes ver algo parecido a esto:</p>
<p><a href="http://www.nemediano.com.mx/wp-content/uploads/2008/09/pantallazo-java-http-localhost8080-intro-hellojsp-eclipse-platform.png"><img class="alignnone size-thumbnail wp-image-77" title="pantallazo-java-http-localhost8080-intro-hellojsp-eclipse-platform" src="http://www.nemediano.com.mx/wp-content/uploads/2008/09/pantallazo-java-http-localhost8080-intro-hellojsp-eclipse-platform-150x150.png" alt="" width="150" height="150" /></a></p>
<h2>Mas información</h2>
<p>Este post fue escrito basándome un poco en el <a href="http://oreilly.com/catalog/9780596006419/" target="_blank">libro de Orelly</a>, un poco en la documentación del mismo eclipse y bastante en <a href="http://www.coreservlets.com/Apache-Tomcat-Tutorial/" target="_blank">este</a> sitio.</p>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.nemediano.com.mx%2F2008%2Fponiendo-un-entorno-de-desarrollo-java-en-ubuntu%2F&amp;t=Poniendo%20un%20entorno%20de%20desarrollo%20Java%20en%20Ubuntu" id="facebook_share_icon_67" style="font-size:11px; line-height:13px; font-family:'lucida grande',tahoma,verdana,arial,sans-serif; text-decoration:none;"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif" alt="Share on Facebook" /></a>
	<script type="text/javascript">
	<!--
	var button = document.getElementById('facebook_share_link_67') || document.getElementById('facebook_share_icon_67') || document.getElementById('facebook_share_both_67') || document.getElementById('facebook_share_button_67');
	if (button) {
		button.onclick = function(e) {
			var url = this.href.replace(/share\.php/, 'sharer.php');
			window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
			return false;
		}
	
		if (button.id === 'facebook_share_button_67') {
			button.onmouseover = function(){
				this.style.color='#fff';
				this.style.borderColor = '#295582';
				this.style.backgroundColor = '#3b5998';
			}
			button.onmouseout = function(){
				this.style.color = '#3b5998';
				this.style.borderColor = '#d8dfea';
				this.style.backgroundColor = '#fff';
			}
		}
	}
	-->
	</script>
	]]></content:encoded>
			<wfw:commentRss>http://www.nemediano.com.mx/2008/poniendo-un-entorno-de-desarrollo-java-en-ubuntu/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Instalar SVN como modulo de Apache, con SSL y autentificación básica, en Ubuntu</title>
		<link>http://www.nemediano.com.mx/2007/instalar-svn-como-modulo-de-apache-con-ssl-y-autentificacion-basica-en-ubuntu/</link>
		<comments>http://www.nemediano.com.mx/2007/instalar-svn-como-modulo-de-apache-con-ssl-y-autentificacion-basica-en-ubuntu/#comments</comments>
		<pubDate>Wed, 19 Dec 2007 22:04:04 +0000</pubDate>
		<dc:creator>nemediano</dc:creator>
				<category><![CDATA[Computación]]></category>
		<category><![CDATA[Mis demonios]]></category>
		<category><![CDATA[Recetario de Ubuntu]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[instalar]]></category>
		<category><![CDATA[modulo]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://nemediano.wordpress.com/2007/12/19/instalar-svn-como-modulo-de-apache-con-ssl-y-autentificacion-basica-en-ubuntu/</guid>
		<description><![CDATA[Pues hace un rato que aprendimos a hacer este tipo de instalación en la Unidad y como se me hace algo útil, muy practico, y que a veces no es trivial de hacer, me decidí a escribir este tutorial. Estoy muy basado en el tutorial que escribió Viktor Zigo Suponemos que la instalación se va [...]]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom:0;">Pues hace un rato que aprendimos a hacer este tipo de instalación en la Unidad y como se me hace algo útil, muy practico, y que a veces no es trivial de hacer, me decidí a escribir este tutorial. Estoy muy basado en el <a title="alephzarro" href="http://alephzarro.com/blog/2007/01/07/installation-of-subversion-on-ubuntu-with-apache-ssl-and-basicauth/" target="_blank">tutorial</a> que escribió <em><span style="font-style:normal;">Viktor Zigo</span></em></p>
<ul>
<li> Suponemos que la instalación se va a realizar en Ubuntu, esto significa que el servidor va a  vivir en Ubuntu.</li>
<li> Que queremos que los repositorios  sean visibles vía web, que el servidor web sea Apache de la 	rama 2.x (Subversión tiene su propio servidor, nosotros mejor 	ocuparemos Apache).</li>
<li> Que el protocolo para comunicarse  sea SSL, la información viaje encriptada (es decir que el URL  sea https://algo).</li>
<li> Que se podría hospedar mas de un repositorio.</li>
<li> Que para conectarse un usuario 	tenga que proporcionar un password.</li>
<li> Que tengamos políticas de acceso, es decir que no todos los usuarios puedan ver todas las carpetas, habrá algunos que puedan ver, otros que puedan escribir, y a cada carpeta le podemos poner diferentes atributos (permisos).</li>
</ul>
<p><span id="more-30"></span></p>
<p style="margin-bottom:0;">Cuando aprendimos a hacer esta instalación leímos el tutorial de Viktor Zigo, que esta libre bajo una licencia Creative Commons, sin embargo me decido a aumentar algunas cosas como la política de acceso, además dado que no hay mucha documentación en español sobre este tema, me imagino que este documento le ayudara a alguien.</p>
<h2 class="western">Paquetes necesarios</h2>
<p style="margin-bottom:0;">Hay que instalar, o verificar que estén instalados los siguientes paquetes:</p>
<ul>
<li> subversion</li>
<li> libapache2-svn</li>
<li> libapache-mod-dav</li>
<li> apache2</li>
</ul>
<p>En ubuntu 7.10 el paquete  libapache-mod-dav, no existe simplemente continuamos sin el pues mod-dav ya esta incluido en apache2</p>
<h2 class="western">Habilitar el modulo de SSL en apache</h2>
<p style="margin-bottom:0;">Para hacer este paso primero hay que habilitar el modulo de apache que deja comunicarse via SSL, luego hay que editar un archivo de configuración de apache para decirle que escuche por el puerto 443, que es el default de SSL</p>
<h3 class="western">Habilitar el modulo de apache2 de SVN</h3>
<p><code>sudo a2enmod ssl</code></p>
<h3 class="western">Editar el archivo de configuración /etc/apache2/ports.conf del apache.</h3>
<p style="margin-bottom:0;">Agregando al final la linea: “Listen 443”. Es decir deben haber dos lineas, la del 80 y la del 443</p>
<p style="margin-bottom:0;"><strong>Nota</strong> me acabo de dar cuenta de que en Ubuntu 7.10, no es necesaria la edición del archivo, pues el comando anterior a2enmod, <strong>ya edita</strong> el archivo por nosotros, lo que se debe de hacer es fijarnos en este archivo y que escuche el 443.</p>
<h2 class="western">Generar un certificado</h2>
<p style="margin-bottom:0;">Para hacer un certificado hay que ocupar una herramienta, desde Ubuntu Festy en adelante esta herramienta es: <strong>make-ssl-cert</strong>, antes de eso la herramienta era: apache2-ssl-certificate.</p>
<p style="margin-bottom:0;">Sea cual sea el caso, hay que hacer un certificado, el certificado es un archivo .pes y una llave, que es un archivo con números raros de nombre.</p>
<p style="margin-bottom:0;">Para hacer el certificado la herramienta nos hace algunas preguntas, como quienes somos, donde se ubica el servidor físicamente, a que organización pertenecemos, etc.</p>
<p style="margin-bottom:0;">Es importante usar el nombre real de nuestro servidor, cuando lo pida, por que de lo contrario cada vez que un usuario quiera acceder al repositorio, su cliente le marcara un warning diciendo que el servidor y el emisor del certificado no corresponden.</p>
<p style="margin-bottom:0;">Si el servidor va a ser accesible por un dominio, el dominio es el nombre del servidor, si va a ser accedido por una IP fija, la IP es el nombre del servidor, si va a ser accedido dentro de una red interna el nombre en la red de la maquina es el nombre del servidor.</p>
<p style="margin-bottom:0;">La herramienta debe generar ambos archivos el <em>apache.pem</em> y el de la llave, lo mas recomendable es que estos se encuentren en la carpeta ssl, dentro de la carpeta de apache. Puede que sea necesario que nosotros tengamos que mover los archivos manualmente.</p>
<p style="margin-bottom:0;">La herramienta antes de Festy 7.04 se usaba asi:</p>
<p><code>sudo apache2-ssl-certificate</code></p>
<p style="margin-bottom:0;">Desde Festy en adelante se usa así:</p>
<p><code>sudo /usr/sbin/make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/apache.pem</code></p>
<p style="margin-bottom:0;">En donde el primer argumento es el comando a invocar en este caso <em>make-ssl-cert</em>, el segundo es una plantilla de certificado en este caso se ubica en  /<em>usr/share/ssl-cert/ssleay.cnf</em>, y el tercero el lugar donde se pone el certificado /<em>etc/apache2/ssl/apache.pem</em>. Es decir que lo único que podría cambiar es el tercer argumento aunque no se recomienda. Es importante que <strong>antes</strong> se cree la carpeta donde va a vivir el certificado</p>
<h2 class="western">Crear un host virtual</h2>
<p style="margin-bottom:0;">En apache2 hay posibilidad de que un solo servidor maneje muchos sitios, lo mas recomendable es hacer un sitio aparte para nuestros repositorios de SVN.</p>
<p style="margin-bottom:0;">Copiamos el sitio de default, para ocuparlo de plantilla</p>
<p><code>sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/$NOMBRESITIO</code></p>
<p style="margin-bottom:0;">En donde $NOMBRESITIO, es el nombre que queremos que tenga nuestro sitio que maneja los repositorios. por ejemplo podemos ponerle repos.</p>
<h3>Editamos configuración del sitio</h3>
<p style="margin-bottom:0;">Abrimos con nuestro editor de textos plano favorito el recién creado archivo de configuración del sitio y lo editamos:</p>
<p style="margin-bottom:0;">Cambiamos la parte que dice:</p>
<p><code>NameVirtualHost *<br />
&lt;VirtualHost *&gt;</code></p>
<p style="margin-bottom:0;">Por:</p>
<p><code>NameVirtualHost *:443<br />
&lt;VirtualHost *:443&gt;</code></p>
<p style="margin-bottom:0;">Y añadimos las siguientes lineas:</p>
<p><code><br />
SSLEngine on<br />
SSLCertificateFile /etc/apache2/ssl/apache.pem<br />
SSLProtocol all<br />
SSLCipherSuite HIGH:MEDIUM</code></p>
<p style="margin-bottom:0;">Dentro de las etiquetas <em>VirtualHost</em>, pero fuera de cualquier etiqueta <em>Directory</em></p>
<p style="margin-bottom:0;">Habilitamos el nuevo host virtual</p>
<p style="margin-bottom:0;">Primero le decimos a apache que ya hay un nuevo sitio</p>
<p><code>sudo a2ensite $NOMBRESITIO</code></p>
<p style="margin-bottom:0;">Y reiniciamos apache</p>
<p><code>sudo /etc/init.d/apache2 restart</code></p>
<p style="margin-bottom:0;">Si hubo errores al editar el archivo, ahora se quejara, corregimos hasta que apache arranque, si hay un warning de que no puede determinar el nombre de dominio calificado, es normal.</p>
<p style="margin-bottom:0;">Y se puede arreglar añadiendo ServerName $NOMBREDELSERVIDOR al archivo de configuración principal de apache: <em>/etc/apache2/apache2.conf</em> (el nombre del servidor es el nombre de la maquina que lo hospeda)</p>
<h2 class="western">Creando los repositorios:</h2>
<p style="margin-bottom:0;">Suponemos que queremos tener varios repositorios, creamos una carpeta donde ponerlos todos, un buen lugar para hacerlo es en: <em>/var/svn</em>, luego hacemos los repositorios y le cambiamos los permisos a los repositorios para que el usuario de apache (<em>www-data</em>), tenga total control sobre ellos.</p>
<p style="margin-bottom:0;">Por ejemplo:</p>
<p><code>sudo mkdir /var/svn<br />
sudo svnadmin create /var/svn/$REPOS<br />
sudo chown -R www-data:www-data /var/svn/$REPOS<br />
sudo chmod -R g+ws /var/svn/$REPOS</code></p>
<p style="margin-bottom:0;">Donde $REPOS, es el nombre del repositorio a crear, se pueden hacer varios repositorios. Que deberían vivir bajo la mima carpeta, en este caso <em>/var/svn</em>.</p>
<h2 class="western">Agregar usuarios al repositorio</h2>
<p style="margin-bottom:0;">Para que un usuario pueda consultar el repositorio, debe de tener un password, el encargado de hacer la validación sera Apache, y la manera como lo hará sera verificando que el usuario y el password, estén en un archivo de texto plano.</p>
<h3>Creando el archivo de password</h3>
<p style="margin-bottom:0;">Hay que ocupar la herramienta <strong>htpasswd</strong>, en versiones de Ubuntu anteriores a 7.04, la herramienta se llama htpasswd2, ambas son la misma herramienta, solo le quitaron el 2, en el nombre, así que es cuestión de usar el que nos corresponda.</p>
<p style="margin-bottom:0;">Ejemplo:</p>
<p><code>sudo htpasswd -c -m /etc/apache2/svn-auth-file $NOMBREUSUARIO</code></p>
<p style="margin-bottom:0;">En este momento nos preguntara cual va a ser el password del para el usuario $NOMBREDEUSUARIO y se crea el archivo de nombre <em>svn-auth-file</em>. El nombre del archivo puede ser cualquiera pero se sugiere algo que nos recuerde que son los passwords del svn, y puede vivir en cualquier lado, pero se recomienda que viva donde el apache lo hace.</p>
<p style="margin-bottom:0;">El modificador -c, es para que cree el archivo de passwords y el modificador -m para que encripte el password.</p>
<p style="margin-bottom:0;"><strong>Importante:</strong> Si queremos agregar un nuevo usuario usamos el comando <strong>sin</strong> el modificador -c y lo apuntamos al archivo que ya creamos, de esta manera los passwords de ambos usuarios están guardados en el mismo archivo. En nuestro ejemplo seria:</p>
<p><code>sudo htpasswd -m /etc/apache2/svn-auth-file $NOMBRENUEVOUSUARIO</code></p>
<h2 class="western">Agregando políticas de acceso</h2>
<p style="margin-bottom:0;">Vamos a hacer una archivo de control de acceso, lo mas simple es usar como plantilla alguno de los que viene en cualquier repositorio. Por ejemplo podemos ir al repositorio que acabamos de hacer y dentro de su directorio <em>conf</em>, hay un archivo de ejemplo: <em>authz</em></p>
<p style="margin-bottom:0;">Podemos tomar este archivo de ejemplo como plantilla. Y copiarlo al directorio de apache, cambiarle por los permisos adecuados y después editarlo con nuestras preferencias. Podemos ponerle cualquier nombre yo aquí lo llamo <em>svn-authz-file</em>.</p>
<p><code>sudo cp /var/svn/$REPOS/conf/authz /etc/apache2/svn-authz-file<br />
sudo chmod 644  /etc/apache2/svn-authz-file<br />
sudo gedit /etc/apache2/svn-authz-file</code></p>
<p style="margin-bottom:0;">Editar el archivo no es difícil y podemos ver que la plantilla ya trae un ejemplo con la sintaxis. Yo por ejemplo solo le agrego algo como esto:</p>
<p><code>[$REPOS:/]<br />
$NOMBREUSUARIO = rw<br />
$NOMBRENUEVOUSUARIO = r</code><br />
En donde $NOMBREUSUARIO puede leer y escribir el repositorio $REPOS y $NOMBRENUEVOUSUARIO solo puede leerlo.</p>
<h2>Poniendo todas las opciones de configuración a nuestro repositorio</h2>
<p style="margin-bottom:0;">Ahora solo resta decirle a apache que sirva de interfaz a nuestro repositorio con todas las opciones que le acabamos de dar.</p>
<p style="margin-bottom:0;">Para hacer esto editamos el archivo <em>dav_svn_conf</em> que se encuentra dentro de la carpeta <em>mods-available</em> del directorio de apache.</p>
<p><code>sudo gedit /etec/apache2/mods-available/dav_svn_conf</code></p>
<p style="margin-bottom:0;">Este archivo tiene de nuevo un ejemplo de llenado, cada repositorio tiene sus opciones dentro de las etiquetas <em>location</em>. Podemos repetir la que ya tiene por defecto y agregarle nuestras opciones.</p>
<p><code>&lt;Location /<strong>$REPOS</strong>&gt;<br />
DAV svn<br />
# our access control policy<br />
AuthzSVNAccessFile <strong>/etc/apache2/svn-authz-file</strong><br />
SVNPath "<strong>/var/svn/$REPOS</strong>"<br />
AuthType Basic<br />
AuthName "Subversion repository"<br />
AuthUserFile <strong>/etc/apache2/svn-auth-file</strong><br />
Require valid-user<br />
<strong>SSLRequireSSL</strong><br />
&lt;/Location&gt;</code></p>
<p style="margin-bottom:0;">De estas opciones debemos modificar dentro de la etiqueta de apertura de <em>location</em> el nombre de nuestro repositorio. En donde dice <strong>SVPath</strong> ponemos el lugar donde esta el repositorio. En la opción de  <em>AuthzSVNAccessFile</em> el archivo que creamos de políticas de control de acceso. Y en la opción de <em>AuthUserFile</em> el archivo donde están las contraseñas de los usuarios. No olvidemos añadir tambien la linea <strong>SSLRequireSSL</strong></p>
<h2>Reiniciamos apache</h2>
<p style="margin-bottom:0;">Por ultimo para que todos los cambios surtan efecto:</p>
<p><code>sudo /etc/init.d/apache2 restart</code></p>
<p style="margin-bottom:0;">Si algún archivo no quedo bien editado ahora se quejara, de no ser así podemos proceder a probarlo:</p>
<p style="margin-bottom:0;">Abrimos nuestro navegador web favorito y visitamos las dirección http://localhost/$REPOS y debe de contestarnos algo así como 403: Forbiden. Ahora visitamos el sitio http<strong>s</strong>://localhost/$REPOS y debe pedirnos usuario y contraseña, en caso de que la contraseña sea incorrecta o que el usuario que introducimos no tenga permiso de lectura sobre $REPOS volverá a contestarnos 403: Forbiden.</p>
<p style="margin-bottom:0;">Si el usuario se autentifica correctamente y tiene los permisos necesarios, debe mostrarnos el repositorio si aun no hemos hecho ningún import o commit, debe ser un repositorio vacío en la revisión 0.</p>
<p style="margin-bottom:0;">He probado que estos pasos funcionan en Ubuntu 6.10, 7.04 y 7.10</p>
<h2>Mas conocimientos</h2>
<p style="margin-bottom:0;">Recuerden que el mejor lugar para aprender mas de subversion es el <a href="http://svnbook.red-bean.com/">libro oficial</a>, que ademas es libre y existe una traducción al español.</p>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.nemediano.com.mx%2F2007%2Finstalar-svn-como-modulo-de-apache-con-ssl-y-autentificacion-basica-en-ubuntu%2F&amp;t=Instalar%20SVN%20como%20modulo%20de%20Apache%2C%20con%20SSL%20y%20autentificaci%C3%B3n%20b%C3%A1sica%2C%20en%20Ubuntu" id="facebook_share_icon_30" style="font-size:11px; line-height:13px; font-family:'lucida grande',tahoma,verdana,arial,sans-serif; text-decoration:none;"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif" alt="Share on Facebook" /></a>
	<script type="text/javascript">
	<!--
	var button = document.getElementById('facebook_share_link_30') || document.getElementById('facebook_share_icon_30') || document.getElementById('facebook_share_both_30') || document.getElementById('facebook_share_button_30');
	if (button) {
		button.onclick = function(e) {
			var url = this.href.replace(/share\.php/, 'sharer.php');
			window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
			return false;
		}
	
		if (button.id === 'facebook_share_button_30') {
			button.onmouseover = function(){
				this.style.color='#fff';
				this.style.borderColor = '#295582';
				this.style.backgroundColor = '#3b5998';
			}
			button.onmouseout = function(){
				this.style.color = '#3b5998';
				this.style.borderColor = '#d8dfea';
				this.style.backgroundColor = '#fff';
			}
		}
	}
	-->
	</script>
	]]></content:encoded>
			<wfw:commentRss>http://www.nemediano.com.mx/2007/instalar-svn-como-modulo-de-apache-con-ssl-y-autentificacion-basica-en-ubuntu/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Utilizando Geany para hacer codigo de C y C++</title>
		<link>http://www.nemediano.com.mx/2007/utilizando-geany-para-hacer-codigo-de-c-y-c/</link>
		<comments>http://www.nemediano.com.mx/2007/utilizando-geany-para-hacer-codigo-de-c-y-c/#comments</comments>
		<pubDate>Sat, 22 Sep 2007 01:53:45 +0000</pubDate>
		<dc:creator>nemediano</dc:creator>
				<category><![CDATA[Computación]]></category>
		<category><![CDATA[Mis demonios]]></category>
		<category><![CDATA[Recetario de Ubuntu]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[geany]]></category>
		<category><![CDATA[Ide]]></category>
		<category><![CDATA[opengl]]></category>

		<guid isPermaLink="false">http://nemediano.wordpress.com/2007/09/22/utilizando-geany-para-hacer-codigo-de-c-y-c/</guid>
		<description><![CDATA[Un editor que a mi me gusta mucho usar para escribir mis programas de C, que comúnmente llevan OpenGL es Geany, se trata de un editor muy ligero y sencillo de usar, esta escrito en GTK, por lo que corre independientemente de cualquier manejador de ventanas que estemos usando (ya sea Gnome, Xfce, o KDE), [...]]]></description>
			<content:encoded><![CDATA[<p>Un editor que a mi me gusta mucho usar para escribir mis programas de C, que comúnmente llevan OpenGL es <a title="Pagina oficial de Geany" href="http://geany.uvena.de/" target="_blank">Geany</a>, se trata de un editor muy ligero y sencillo de usar, esta escrito en GTK, por lo que corre independientemente de cualquier manejador de ventanas que estemos usando (ya sea Gnome, Xfce, o KDE), es un editor, no un IDE, por esto me refiero a que nonos va a hacer proyectos, ni nada de eso, solo nos va a dejar editar el texto.</p>
<p><span id="more-29"></span></p>
<p>Instalar Geany, no debe de dar mayor problema, pues se encuentra en los repositorios oficiales de Ubuntu, lo podemos hacer via apt-get, o synaptic, o incluso se encuentra disponible en agregar o quitar programas bajo la categoría de desarrollo, si su sistema esta en español (el Ubuntu), geany también vendrá en español.</p>
<p>Bueno, por que querría yo usar un editor de texto aparte de gedit? Pues por que geany me da ciertas ventajas que no me da por ejemplo gedit, al escribir código, estoy hablando a que nos da mas ventajas que el simple sintax highlight</p>
<p><a title="Una pantalla de Geany en accion" href="http://www.nemediano.com.mx/wp-content/uploads/2007/09/pantalla_geany.png"><img src="http://nemediano.files.wordpress.com/2007/09/pantalla_geany.thumbnail.png" alt="Una pantalla de Geany en accion" /></a></p>
<p>Pues aquí viene lo bonito del asunto, si queremos usar Geany para escribir código de OpenGL  y glut en Ubuntu, y ya sabemos hacer nuestros propios makefiles, como lo explique en el <a title="El post donde explico como hace makefiles" href="http://nemediano.wordpress.com/2007/09/01/como-hacer-makefiles-para-programar-en-opengl-y-glut/" target="_blank">post anterior</a>.</p>
<p>Ahora podemos usar todo esto a nuestro favor para tener un entorno de desarrollo muy amigable, para empezar guardemos todos nuestros archivos fuentes y makefile en una sola carpeta luego iniciamos geany.</p>
<p>Ahora suponemos que en nuestro makefile, define cierto nombre para el ejecutable por ejemplo &#8220;Modelo3D&#8221;, y que definimos un make all, de defualt, y que también pusimos un &#8220;make destroy&#8221;, que elimina los objetos y el ejecutable.</p>
<p>Pues abrimos Geany, de ahí abrimos todos nuestros archivos fuentes,  Archivo -&gt; abrir y luego nos vamos al menú que dice: <strong>construir</strong></p>
<p>En la ultima opción se encuentra  <strong>Selecciona Inclusiones y Argumentos</strong>, al entrar a esta opción vemos una ventana como esta:</p>
<p><a title="Seleccion de argumentos en Geany" href="http://www.nemediano.com.mx/wp-content/uploads/2007/09/pantallazo-selecciona-incluciones-y-argumentos.png"><img src="http://nemediano.files.wordpress.com/2007/09/pantallazo-selecciona-incluciones-y-argumentos.thumbnail.png" alt="Seleccion de argumentos en Geany" /></a><br />
Ahora vemos que Geany ya ha dado valores de default, pues sabe que estamos escribiendo código en C, por que abrimos un archivo .c, sin embargo como nosotros ya hicimos nuestro propio makefile, la vamos a cambiar esas opciones, para que llame a nuestro make.</p>
<p>Lo que tenga escrito en la primer caja de  de compilar es lo que se va a ejecutar, cuando apretemos el botón de compilar, ahora nosotros queremos que antes de compilar elimine todos los objetos y el ejecutable, y luego intente compilar todo, es decir queremos que ejecute &#8220;make destroy&#8221; y luego &#8220;make all&#8221;, y como esta instrucción se va a mandar al shell tal como la escribimos podemos escribir:<br />
<code>make destroy; make</code><br />
Ahora lo que escribamos en argumentso para el programa, es lo que ejecuta cuando presionamos el boton de ejecutar, así que podemos poner ahi ./nombre_de_ejecutable o para nuestro ejemplo:<br />
<code>./modelo3D</code><br />
<a title="Como queda la configuracion al final" href="http://www.nemediano.com.mx/wp-content/uploads/2007/09/pantallazo-selecciona-incluciones-y-argumentos-1.png"><img src="http://nemediano.files.wordpress.com/2007/09/pantallazo-selecciona-incluciones-y-argumentos-1.thumbnail.png" alt="Como queda la configuracion al final" /></a></p>
<p>Y listo, ahora podemos programar cómodamente en Geany, usando glut y OpenGL, cada que queramos compilar, solo presionamos el botón de compilar y al ejecutar el botón de ejecutar.</p>
<p>Algunas observaciones</p>
<ul>
<li>Geany es muy ligero y tiene la enorme ventaja que no hace archivos de proyecto, o de configuración, esto es una ventaja para programas pequeños.</li>
<li>La ventaja de tener total control de los argumentos con nuestro propio makefile.</li>
<li>También se puede importar código muy fácil, ya que geany, nos da lo mínimo, para poder escribir entre Windows y GNU/Linux, es decir nos deja cambiar el carácter de terminación de linea de los archivos fuentes y la codificación de caracteres, la codificación de GNU/Linux y en particular de Ubuntu es UTF8, la codificación en Windows es depende del idioma en que lo tengamos, pero seguro aparece en el menú de geany. La terminación de linea en Windows es CRLF y en GNU/Linux es LF.</li>
<li>Tenemos las opciones que mas comúnmente se usan al programar en un Editor muy ligero y que no para instalar no necesitamos traer montones de librerías como en los casos de editores mas poderosos.</li>
</ul>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.nemediano.com.mx%2F2007%2Futilizando-geany-para-hacer-codigo-de-c-y-c%2F&amp;t=Utilizando%20Geany%20para%20hacer%20codigo%20de%20C%20y%20C%2B%2B" id="facebook_share_icon_29" style="font-size:11px; line-height:13px; font-family:'lucida grande',tahoma,verdana,arial,sans-serif; text-decoration:none;"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif" alt="Share on Facebook" /></a>
	<script type="text/javascript">
	<!--
	var button = document.getElementById('facebook_share_link_29') || document.getElementById('facebook_share_icon_29') || document.getElementById('facebook_share_both_29') || document.getElementById('facebook_share_button_29');
	if (button) {
		button.onclick = function(e) {
			var url = this.href.replace(/share\.php/, 'sharer.php');
			window.open(url,'sharer','toolbar=0,status=0,width=626,height=436');
			return false;
		}
	
		if (button.id === 'facebook_share_button_29') {
			button.onmouseover = function(){
				this.style.color='#fff';
				this.style.borderColor = '#295582';
				this.style.backgroundColor = '#3b5998';
			}
			button.onmouseout = function(){
				this.style.color = '#3b5998';
				this.style.borderColor = '#d8dfea';
				this.style.backgroundColor = '#fff';
			}
		}
	}
	-->
	</script>
	]]></content:encoded>
			<wfw:commentRss>http://www.nemediano.com.mx/2007/utilizando-geany-para-hacer-codigo-de-c-y-c/feed/</wfw:commentRss>
		<slash:comments>46</slash:comments>
		</item>
	</channel>
</rss>

