LaTeX y compañía

Informacion sobre LaTeX y programas relacionados

9.5.11

Flechas con borde en TikZ

A veces es deseable añadir un borde a una línea, especialmente si ésta línea pasa por una zona del dibujo en la que hay tramas en tonos oscuros que dificultan la visión. Compara las dos imágenes inferiores:

Parece que debería ser sencillo añadir un borde a una línea, o que TikZ debería tener una opción para esto, pero lo cierto es que no la tiene, por lo que habrá que recurrir a trucos más o menos sucios.

Por ejemplo, TikZ tiene la capacidad de dibujar líneas dobles, lo cual en realidad es realizado por el método de pintar primero una más gruesa de lo deseado (por defecto en color negro), para después pintar encima de ella otra línea menor grosor (por defecto en color blanco). Esto crea la sensación de que hay una línea doble negra con un espacio blanco separando:

\tikz 
{
  \draw (0,0) node (A) {A}
        (2,1) node (B) {B};
  \draw[double] (A) -- (B);
}

Es posible hacer que la linea más gruesa inicial sea blanca, y la más fina interior sea negra, de modo que se consiga el efecto de "borde" buscado:

\tikz 
{
  \draw (0,0) node (A) {A}
        (2,1) node (B) {B};
  \fill[gray] (1,.5) circle (4mm);
  \draw[white,double=black] (A) -- (B);
}

Sin embargo la solución anterior plantea problemas si queremos colocar una punta de flecha al final (o al principio, o en ambos lados) de la línea, ya que la punta de flecha es dibujada en el mismo color que la línea exterior más gruesa(en el ejemplo anterior sería blanca, y por tanto no visible) y además sin borde.

Por tanto el añadir [double] a nuestra línea no nos sirve si ésta tiene una punta de flecha, como en el ejemplo inicial. Para conseguir el efecto deseado, tenemos que usar el mismo truco que usa TikZ con [double], pero incluyendo a la punta de flecha. Esto es, tenemos que dibujar primero la línea en blanco (o en el color que queramos darle al borde de la línea), y más gruesa de lo normal, incluyendo las puntas de flecha que también saldrán más gruesas, y seguidamente pintar encima en negro (o en el color que queramos que nuestra línea tenga por dentro) la misma línea y con la misma flecha, pero en un grosor menor (lo que hará que la flecha también sea más pequeña.

En realidad aparece otro problema. Si hacemos lo anterior, la punta de flecha "gorda" que pintamos en la primera pasada y la de la más fina que pintamos en la segunda, ambas terminarían en las mismas coordenadas, con lo que la punta de flecha no tendría el borde deseado. La figura inferior te aclarará a qué me refiero:

\usetikzlibrary{arrows}
\tikz 
{
  \fill[gray] (1,.5) circle (5mm);
  \draw[yellow, -latex', line width=2pt] (0,0) -- (1,.5);  
  \draw[black, -latex', line width=1pt] (0,0) -- (1,.5);
}

Observa cómo he creado la figura anterior. El primer \draw dibuja el "borde" en amarillo, mediante el truco de pintar la línea más gorda (line width=2pt). El segundo \draw pinta el interior de la línea, en negro y con un grosor menor (line width=1pt).

La punta de flecha se añade mediante la opción de sintaxis muy oscura -latex', que quizás merece la pena explicar. Cuando se quiere añadir una punta de flecha al final, habitualmente se pone la opción ->, que intenta parecerse a un segmento con una punta de flecha al final. Si queremos que sea el extremo inicial de la línea el que lleve la punta, la opción es <-. Para una línea con flechas en ambos extremos la opción es <->.

Las opciones anteriores añaden a la línea la punta de flecha "por defecto" que es más bien fea. Si se quieren añadir otros tipos de punta de flecha, es necesario poner el \usetikzlibrary{arrows} que aparece al principio. Esto nos da nuevos tipos de punta de flecha, y todos ellos tienen un nombre que se basa en las opciones antes decritas, pero cambiando > o < por otra cosa. Una de estas puntas de flecha se llama latex' (con apóstrofe y todo, es que hay otra que se llama latex a secas). Esto explica la extraña sintaxis de la opción -latex' que significa por tanto "añade al final de la línea una punta de flecha del tipo latex', que es, como ves en la figura anterior una punta con sus bordes levemente curvos.

Pero a lo que íbamos, el truco no ha funcionado porque las puntas de flecha se solapan a partir de la coordenada de sus puntas, en lugar de sus centros. La solución es por tanto dibujar la segunda línea (la negra) más corta que la primera, para que la flecha negra caiga "justo encima" de la amarilla. Es decir, en lugar de llegar hasta la coordenada (1,0.5) donde está el centro del círculo, debe terminar "un poco antes". El problema es ¿cuánto antes? Y ¿cómo calcular las coordenadas (x,y) del punto en que debe terminar?

La respuesta tiene dos partes. Primero ¿cuánto más corta hay que hacer la línea? Por desgracia la respuesta depende del tipo de flecha usado, y del grosor de la línea (tanto de la "exterior" como de la "interior"). Tras ensayos y errores he llegado a que hacer la línea interior 1.8pt más corta que la exterior da buenos resultados para este tipo de punta de flecha, y usando estos grosores de línea.

Segundo: si ya sé que la línea negra ha de ser 1.8pt más corta que la amarilla, ¿cómo calcular las coordenadas finales de esa línea? Parece que ha de ser enormemente complicado, pues hay que tener en cuenta la pendiente de la línea, etc. Por suerte TikZ tiene una opción llamada "shorten >", que permite especificar una cantida a acortar al final de la línea. Cuidado con el nombre de la opción, que es raro. El nombre de esta opción contiene un ">", como ves, y separado por un espacio de "shorten". A esta opción se le asigna un valor mediante el signo =, por lo que en nuestro caso quedaría así: "shorten >=1.8pt". Y el resultado es:

\usetikzlibrary{arrows}
\tikz 
{
  \fill[gray] (1,.5) circle (5mm);
  \draw[yellow, -latex', line width=2pt] (0,0) -- (1,.5);  
  \draw[black, -latex', line width=1pt, shorten >=1.8pt] 
                                         (0,0) -- (1,.5);
}

Esta es la idea básica. Ahora mejoraremos la legibilidad del código haciendo uso de los estilos de TikZ. Voy a crear un estilo llamado "flecha con borde" que se ocupe de hacer todo lo anterior, es decir, de añadir una punta de flecha al final de la línea, de pintar primero una línea más gorda en el color que el usuario prefiera, y después otra línea interior más fina y que sea 1.8pt más corta. Para poder hacer esto, TikZ proporciona la opción llamada preaction, que puede formar parte de un estilo y se ejecuta antes de que TikZ dibuje el código "normal" correspondiente a esa línea.

En nuestro caso, aprovecharemos la opción preaction del estilo flecha con borde para dibujar la línea gorda que va debajo, y en otro color. Después usaremos otras opciones del estilo flecha con borde para especificar el grosor y menor longitud de la que va encima. El código es el siguiente:

\usetikzlibrary{arrows}
\tikzset{
  flecha con borde/.style={
     line width=1pt, 
     shorten >=1.8pt,
     -latex',
     preaction={draw, #1, line width=2pt, shorten >=0pt}, 
  }
  flecha con borde/.default=white,
} 
\tikz 
{
  \fill[gray] (1,.5) circle (5mm);
  \draw[red, flecha con borde] (0,0) -- (1,.5);
}

Empecemos por el final, y fíjate en cómo ha quedado ahora la línea que dibuja la flecha. Simplemente \draw[red, flecha con borde] y las coordenadas de inicio y fin de la línea. Obviamente red es el color en el que quiero dibujar la línea, con su flecha, y flecha con borde es el nombre del estilo que se ocupa de añadirle un borde blanco, o de otro color si por ejemplo hubiera puesto flecha con borde=yellow. Fíjate que los nombres de estilos o de cualquier otra opción TikZ pueden llevar espacios, lo cual queda mucho más legible que algo como FlechaConBorde o flecha_con_borde.

Y ahora veamos cómo se ha definido el estilo. Se ha hecho fuera de la figura (de este modo este estilo puede ser usado por diferentes figuras del documento) a través de la macro \tikzset. En realidad esta macro no es sólo para definir estilos, sino para asignar valores a las "claves" que usa TikZ. TikZ maneja todas sus opciones y su configuración a través de un sofisticado mecanismo de "claves", similar en concepto a la que proporciona el paquete keyval, pero diferente. En ciertos aspectos más sencilla de usar. En nuestro caso, usamos \tikzset para crear un estilo, de modo que me centraré en este uso.

Para crear un nuevo estilo, basta inventar un nombre para él (pongamos "ejemplo", y hacer uso de la "clave" ejemplo/.style a la que asignamos todas las opciones que queremos que se ejecuten cuando usemos ese estilo. Así, puedo definir un estilo que fije un color de línea y un grosor y un tipo de punta de flecha, y cada vez que use ese estilo se aplicarán estas opciones (aunque algunas de ellas pueden ser sobreescritas por otras opciones presentes en cada figura).

Además, los estilos pueden recibir un parámetro (sólo uno), al cual nos referimos dentro del estilo como #1. Por ejemplo, en nuestra flecha con borde he elegido que el color del borde sea un parámetro, de modo que el usuario pueda poner, como dije antes, flecha con borde=yellow. Podría haber elegido que el parámetro fuese el grosor de la línea, por ejemplo, pero en este caso no lo encontré tan útil. Si quisiera tener varios aspectos parametrizables, tendría que hacer uso de otras "claves" y acceder a ellas. Otro día hablo de eso.

Observa lo que hay escrito tras flecha con borde/.style=, verás que se abre una llave y después se listan una serie de parejas "clave=valor", aunque en algunos casos aparece solo "clave" sin ningún valor asignado. Esta lista de parejas va separada por comas. Así, en nuestro caso tenemos las claves:

  • line width que recibe el valor 1pt y será el grosor de la línea a dibujar (la interna). Se dibujará en el color que se haya especificado en el comando \draw que esté usando este estilo, y si no se especifica otro, será en negro.
  • shorten > que recibe el valor 1.8pt y es la cantidad a acortar al final de la línea.
  • -latex' que es una opción que no recibe valor y que indica el tipo de flecha que se usará al final de la línea (TikZ busca si en el nombre de una opción hay un guión, e intenta interpretarlo como un tipo de flecha, de modo que la opción -loquesea se intenta interpretar como arrows=-loquesea).
  • preaction que recibe como valor otra lista de opciones entre llaves. Cuando aparece la clave preaction, TikZ dibuja dos veces la línea, la primera con las opciones dadas en esta clave, y la segunda con las opciones que se apliquen en ese momento. Esto nos permite dibujar el "borde gordo" antes de que se dibuje la línea más fina. Como opciones para este borde gordo tenemos:
    • draw esta opción (sin valores asignados) causa que TikZ dibuje realmente algo. Sin ella no dibujaría la línea gorda.
    • #1 esta opción es el parámetro que se le haya pasado a la clave flecha con borde. Se supone que es un color, y será por tanto el color con que se dibujará la "línea gorda con flecha gorda". Veremos después cómo hacer que si el usuario no especifica ningún color, se dibuje en blanco.
    • line width con el valor 2pt fija el grosor de esta "línea gorda".
    • shorten > con el valor cero hace que esta línea no sea más corta de lo normal. ¿Por qué es necesario especificar ésto? ¿No es eso la opción por defecto? Ocurre que cuando se ejecuta la preaction, están también activas todas las opciones de estilo de ese momento, en particular todas las opciones de flecha con borde, por lo que hay que sobreescribir (redefinir) las que queramos que sean diferentes, tales como el grosor de línea, el color y la cantidad a acortar al final.
      Puedes ver que no he especificado en el preaction la punta de flecha. No es necesario por que sigue activa la del estilo principal.

Finalmente, cuando el estilo que definimos usa parámetros, es conveniente especificar un valor por defecto para cuando el usuario no se lo asigna. En nuestro caso queremos que el borde sea blanco, y eso se logra con la clave flecha con borde/.default. El valor que asignemos a esa clave, será el valor que se reciba en #1 dentro del estilo, si el usuario no asigna otro.

La explicación ha sido larga, pero han aparecido en ella muchas cosas interesantes. La más importante en mi opinión, la capacidad de crear estilos parametrizados que ayudarán mucho a simplificar el código de las figuras que lo usen, además de servir para uniformizar el aspecto de estas figuras y simplificar los cambios de estilo que afecten a varias de ellas.

Etiquetas:

 
5.5.11

¿Cómo se llama este símbolo?

Uno de los términos de búsqueda más usado por la gente que llega a mi blog es el de "símbolos latex". Esto muestra claramente que una necesidad frecuente del usuario de latex es localizar el paquete y el código que es necesario para mostrar un símbolo concreto.

Ya escribí en un viejo post acerca del Comprehensive LaTeX symbol list (el cual aparece también en la zona de enlaces de la derecha, como "Lista de símbolos"), el cual, como su nombre indica, contiene prácticamente todos los símbolos matemáticos o inusuales que se pueden necesitar, y por si acaso, también instrucciones para hacer tus propios símbolos. No obstante, incluso con ese documento a mano, se requieren ciertas dotes detectivescas para encontrar lo que se necesita.

Y aquí es donde puede ser útil Detexify. El sitio ya no es nuevo, pero nunca lo había mencionado, y creo que a pesar del tiempo que lleva en marcha sigue siendo poco conocido.

La idea detrás de Detexify no puede ser más simple. Dibuja a mano alzada (bueno, con el ratón) cómo es el símbolo que buscas, y él te dice qué paquete debes incluir y qué comando ejecutar.

A pesar de la sencillez de la idea, la tecnología detrás de ella es compleja. Y para que funcione correctamente el sistema debe ser "entrenado" por los usuarios. Por suerte, ya que he tardado tanto en escribir acerca de este sitio, probablemente su entrenamiento ya esté completado. Y si no, ¡siempre puedes colaborar a él!

 
4.5.11

LaTeX previewer y primer contacto con TikZ

LaTeX previewer es un sitio web realmente útil. Te permite escribir un poco de código latex (por ejemplo, una ecuación), y te muestra el resultado de compilarlo, ya sea en forma de bitmap (PNG) o vectorial (SVG).

Al margen de poder usarlo para crear rápidamente una versión PNG o SVG de una fórmula, la verdadera utilidad que yo le encuentro es la de poder probar rápidamente una idea "a ver cómo queda", sin tener que escribir un .tex completo, compilarlo, y abrir el visor PDF.

Y esta utilidad se convierte en una verdadera maravilla cuando estás aprendiendo TikZ. Te permite experimentar con las diferentes sintaxis y ejemplitos que vas encontrando en el manual, e incluso puede usarse como herramienta de trabajo en figuras no muy complejas. Más de una vez he creado mis figuras con LaTeX previewer y cuando las tuve a mi gusto, corté y pegué el código en mi documento.

Para abrir boca, tú mismo puedes probar a introducir el siguiente fragmento de código (TikZ) y compilarlo para ver el resultado. Para que funcione correctamente, no debes olvidar primero pulsar el botón "Packages" y asegurarte de añadir el paquete tikz.

\begin{tikzpicture}
\path (0,0) coordinate (A) {}
  (1,1) coordinate (B) {}
  (3,0) coordinate (C) {};
\draw[dashed] (A) -- (B) -- (C);
\foreach \punto in {A,B,C}
\fill[red] (\punto) circle (2pt) node[above,blue] {\punto};
\end{tikzpicture}

Comentario al código

Aprovecho la entrada para ir desgranando un poco la curiosa sintaxis de TikZ. Como ves, cuando se quiere meter un dibujo TikZ en un documento, se abre un entorno llamado tikzpicture y dentro de él los comandos tikz. No necesita ir a su vez dentro de un entorno figure, a menos que quieras que "flote" y tenga un pie de figura. Esto permite también hacer mini-figuras "en el texto". Cuando la figura es tan simple que cabe en una sola línea de código, puedes usar el comando \tikz en lugar del entorno tikzpicture. Así (pruébalo también en el previewer):

\def\puntorojo{\tikz\fill[red] circle(.5ex);}

R\puntorojo{}j\puntorojo{}.

Lo primero que llama la atención en TikZ es que su sintaxis usa corchetes, llaves y paréntesis en una forma que al principio parece caótica o caprichosa. También algunas veces tiene palabras reservadas que comienzan por \ como otros comandos tex (\path, \draw, \fill, mientras que otras no llevan la barra delante (node, circle). En realidad hay un orden dentro del caos y cuando te acostumbras ya no necesitas pensarlo. Esta es la regla general:

  • Corchetes [ ] para indicar opciones (estilos) de los comandos de dibujo, como por ejemplo el color, aunque hay muchos más.
  • Paréntesis ( ) para especificar las coordenadas de un punto, como en (0,0), o los nombres que queramos asignarles a esas coordenadas, como (A), (B), etc. También se usan paréntesis para pasar parámetros a algunas funciones TikZ, como por ejemplo para especificar el radio del círculo en la función circle.
  • Llaves para delimitar argumentos a los comandos que comienzan por \, como en latex, aunque no se usan muy a menudo con este cometido. En el ejemplo hay un caso en {A,B,C} que es un argumento de \foreach. También se usan llaves para delimitar los contenidos de un "nodo" (que es como TikZ llama a lo que yo llamaría "etiqueta", es decir, un texto situado en un lugar concreto del dibujo para anotar o describir parte del mismo). El texto que ponemos entre llaves en este caso es cualquier cosa válida para LaTeX, lo que implica que podemos usar fórmulas, matemáticas, lo que sea (¡incluso tablas!). En el ejemplo este uso aparece en {\punto}, aunque requiere un poco más de explicación, porque \punto es una macro cuyo valor se va asignando en el bucle \foreach. Más adelante explico esto.
  • Para especificar "caminos" (que son secuencias de coordenadas, en las cuales podemos ir poniendo texto, u otros elementos gráficos), o para pintar esos caminos con un trazo, se usan primitivas de TikZ, que están definidas como comandos LaTeX y por tanto sus nombres comienzan por \, como \path, \draw, \fill, etc. También hay otras macros que proporcionan utilidades especiales, como hacer bucles (\foreach), definir estilos, realizar cálculos de expresiones matemáticas, etc. De éstas últimas no hay en este primer ejemplo, pero ya vendrán.
  • Por último, si como parte de un camino queremos meter en él algún objeto geométrico "predefinido" tal como un círculo, rectángulo, rejilla, etc. o tambíen un "nodo" (que como ya dije es un tipo de elemento gráfico que simplemente es un contenedor de texto LaTeX), las palabras reservadas para estos objetos no comienzan por la barra. Así tenemos: node, circle, etc. La sintaxis que sigue a estas palabras es un poco variable, ya que depende de la palabra en cuestión. Por ejemplo, tras node podemos poner corchetes, si vamos a especificar opciones del nodo (como above, blue), y también podemos poner paréntesis si queremos asignarle un nombre a ese nodo para usarlo más adelante para referirnos a él (en el ejemplo no se da este caso), y finalmente, de forma obligatoria deberemos usar llaves para especificar el contenido del nodo, es decirl el texto que aparecerá ahí. Incluso si en algún caso queremos crear un nodo que no contenga texto, aún así deben ponerse las llaves. En cambio, si el objeto es circle, como vemos la sintaxis obliga a que usemos paréntesis a continuación, para especificar el radio del círculo. Aquí es donde la sintaxis puede parecer más inconsistente, y donde la práctica es insustituible.

Una vez aclarada la sintaxis, veamos línea a línea qué hace nuestro código:

\path (0,0) coordinate (A) {}
  (1,1) coordinate (B) {}
  (3,0) coordinate (C) {};

Lo anterior podría haber ido en una sola línea. Para TikZ es un solo comando, y el punto y coma final (obligatorio) es la marca de dónde termina. El comando \path espera una secuencia de coordenadas, y en cada una de ellas podría ir algún objeto gráfico o no. El resultado de \path es invisible, a menos que contenga objetos gráficos en las coordenadas especificadas.

En este ejemplo, el camino está compuesto por tres coordenadas. La primera es (0,0>, y en ella colocamos un objeto gráfico que es coordinate. Una coordinate es un objeto invisible, cuya única función es poder asignarle un nombre a la coordenada que acabamos de usar. En el ejemplo, a esa coordenada le asignamos el nombre (A). Internamente TikZ implementa el objeto coordinate como un tipo de node, pero sin dimensiones. Esto explica que obligatoriamente aparezca {}, pues las llaves son obligatorias para indicar el contenido del nodo, incluso cuando el contenido está vacío como en este caso.

De forma análoga se asigna el nombre (B) a la coordenada en (1,1) y el nombre (C) a la que hay en (3,0). Por cierto que habrás notado que las coordenadas no llevan unidades. Por defecto se trata de centrímetros.

\draw[dashed] (A) -- (B) -- (C);

El comando \draw es como \path, es decir, espera una secuencia de coordenadas y opcionalmente objetos gráficos a poner en ellas, pero a diferencia de \path que es "invisible", el comando \draw pinta líneas o curvas uniendo esas coordenadas. En nuestro caso, el conector usado entre coordenadas ha sido --, lo que indica que debe dibujarse un segmento rectilíneo entre ellas. Para las coordenadas podría haber puesto números como (0,0), etc, pero he usado en cambio los nombres que había asignado anteriormente a esas cordenadas, lo que hace el código más legible y fácil de mantener. Observa también que el comando \draw lleva una opción de estilo [dashed] que causa que la línea dibujada sea discontinua.

\foreach \punto in {A,B,C}

Aquí viene uno de los comandos más interesantes de TikZ. Tanto es así que tiene su paquete separado, por si quieres usar \foreach para otras cosas que no sean dibujos, sin tener que incluir TikZ completo (para este caso \usepackage{foreach}). Como imaginas por su nombre, este comando permite realizar bucles. El primer parámetro tras \foreach es el nombre de una macro que tú eliges para la ocasión. Esta macro irá tomando diferentes valores en cada iteración del bucle. Después debe aparecer la palabra reservada in y por último, entre llaves y separado por comas, la lista de valores que quieres que tome la macro. En nuestro caso, el bucle iterará tres veces y \punto irá tomando los valores A, B y C en cada iteración. (En realidad \foreach es aún más potente, pero ya lo iremos viendo en otras entradas).

Por último, \foreach necesita el código a ejecutar en cada iteración del bucle. Este código debería ir entre llaves, pero si se trata de un código "de una línea" (un comando TikZ terminado en punto y coma), puedes omitir las llaves, como he hecho yo en este caso.

 \fill[red] (\punto) circle (2pt) node[above,blue] {\punto};

En la primera iteración, \punto se expande como A, por lo que la línea anterior se convierte en esta otra:

 \fill[red] (A) circle (2pt) node[above,blue] {A};

Veamos qué significa. En primer lugar tenemos \fill, que es como \path, solo que rellena el camino dibujado y los objetos que hay en él. El color de relleno es una opción de estilo, [red], y el camino en sí, en este caso, se compone de una única coordenada, (A). En dicha coordenada ponemos dos objetos gráficos en esta ocasión. El primero es el círculo de radio 2pt, y el segundo es un node que contiene el texto A (observa las llaves alrededor del contenido del nodo). Además el nodo recibe dos opciones de estilo: above indica que el texto del nodo debe aparecer encima de la coordenada en cuestión (saldrá encima del círculo). blue obviamente es el color del texto.

Es decir, pintará un circulito rojo en la coordenada (A) y encima de él, el texto "A". Y en la siguiente iteración del bucle hará lo propio con la coordenada B, y finalmente la C. Potente ¿eh?

Sintaxis alternativas

TikZ ofrece muchas formas diferentes de expresar la misma figura, lo cual está bien para que cada cual encuentre la que mejor se ajusta a su forma de pensar sobre el problema. A veces sin embargo tanta variedad produce duda y confusión, sobre todo mientras se está aprendiendo. Veamos algunas otras formas en las que podía haber codificado la figura anterior.

En lugar de hacer primero un \path sobre el cual ir definiendo coordenadas, para después dibujarlas con \draw, podría haberlo hecho todo en el mismo paso, así:

\draw[dashed] (0,0) coordinate (A) {}  
           -- (1,1) coordinate (B) {}  
           -- (3,0) coordinate (C) {};
Observa que, además de cambiar \path por \draw[dashed], he tenido que añadir el operador -- para conectar las coordenadas. Sin él tampoco sería visible la línea, ya que si en un comando \draw aparece una coordenada que no está precedida de --, lo que hace TikZ es simplemente "levantar el lápiz" y moverse a esa posición, sin dibujar línea hasta esa coordenada

En la sintaxis anterior, y también la primera en que usé \path parece un poco torpe el tener que poner todas esas llaves sin nada dentro. Como ya se explicó, se debe a que coordinate es un tipo de node y se requiere especificar su contenido textual entre llaves, incluso cuando esté vacío. Para colmo, es que en un nodo de tipo coordinate ¡debe ir obligatoriamente vacío! Parece un contrasentido que se nos obligue a especificar un contenido vacío en este caso, cuando ha de serlo forzosamente.

Por ello, TikZ proporciona el comando \coordinate que sirve para especificar una secuencia de nodos de tipo coordinate, con la idea de asignarles nombres como en el ejemplo anterior, y con la ventaja de que no es necesario especificar en este caso el contenido vacío de cada nodo. En este caso, sin embargo, cambia ligeramente la forma de asignar coordenadas al nodo, ya que en lugar de estar dando una serie de coordenadas y en cada una de ellas poniendo un objeto coordinate, lo que haremos será especificar un objeto coordinate asignarle una posici, mediante la función at.

Es decir, en lugar de:

\path (0,0) coordinate (A) {};
pondríamos
\coordinate (A) at (0,0);
Usando esta sintaxis el código queda un poco más limpio, si bien hay que separar cada coordenada en un comando \coordinate independiente, a diferencia de \path o \draw que permiten en un solo comando especificar varias coordenadas.
\coordinate (A) at (0,0);
\coordinate (B) at (1,1);
\coordinate (C) at (3,0);

Etiquetas:

 
3.5.11

¡TikZ es increible!

Hace mucho tiempo que no escribía en este blog. Cuando lo comencé (ya hace más de 7 años), mi herramienta favorita para hacer gráficos con LaTeX era metapost. Puede verse esta debilidad mía echando un vistazo a los primeros posts de esta bitácora.

Ya en su momento, cuando tuve que elegir qué lenguaje/herramienta utilizar para "dibujar" con LaTeX (pongo comillas porque en este caso la acción de dibujar consiste en escribir, pero ya nos entendemos ¿no?), acababa de aparecer en escena una cosa llamada PGF/TikZ que aún estaba un poco verde. De modo que en su momento me decidí por MetaPost, pero mantuve un ojo en la evolución de TikZ, pues permitía algo importante en aquel momento: que los gráficos generados pudieran ser usables tanto compilando con latex (con la idea de generar PostScript), como con pdflatex (para generar PDF), a partir del mismo fuente.

Dediqué mucho tiempo a metapost, y ya se sabe que cuando se domina una herramienta hay una lógica reticencia a probar otras. Sin embargo, hojeando el manual de TikZ muchos de los ejemplos me parecían fascinantes, y cada vez era me parecía más interesante el aprender este lenguaje, pero el manual (¡700 páginas!) me echaba bastante para atrás.

Finalmente me decidí a ir haciendo mis primeras pruebas con TikZ. Ya llevo dos años usandolo continuamente para todos los dibujos que he necesitado crear, y tengo que decir que nunca me he arrepentido de la decisión. La idea de crear "estilos" que definen cómo formatear gráficamente las categorías de objetos que nosotros mismos definimos es muy potente. Cambiando solo un par de líneas al principio de nuestro fuente podemos hacer que, por ejemplo, todas las cajas que usemos en todos los diagramas de cajas de nuestro libro, cambien su color de fondo, o el estilo de sus bordes, etc.

Un sitio excelente donde poder hacerse una idea de la potencia de TikZ es Texample.net, lugar dedicado a coleccionar ejemplos de gráficas de toda índole realizadas con TikZ. Durante un tiempo vigilé esa web periódicamente para estar al tanto de lo que se podía hacer con TikZ. Incluso hay allí alguna contribución mía. Por desgracia, la última actualización de ese sitio tiene ya más de un año. Y el último mensaje del autor es para comunicar que no tiene apenas tiempo para mantenerlo y pedir ayuda para ello. Desde entonces silencio.

Para aportar mi granito de arena, planeo ir escribiendo en este blog pequeños fragmentos de TikZ correspondientes a figuras del "mundo real", que he tenido que realizar para mis proyectos o para otros que me lo han pedido, tratando de explicar de paso algunos truquillos para hacer el código más flexible, o más legible, o más interesante en definitiva.

Permanezcan atentos a este espacio :-)

Etiquetas:

 
17.3.09

FAQ de LaTeX Visual

La FAQ de LaTeX Visual (o más exactamente The Visual LaTeX FAQ, ya que el original está en inglés) es un documento que al parecer lleva ya más de tres años publicado, pero que yo acabo de descubrir. Nunca es tarde.

Se trata de un curioso documento PDF que contiene cantidad de ejemplos resueltos de situaciones que más de uno habrá vivido varias veces mientras componía documentos en LaTeX, tales como dos figuras en un mismo entorno que se quieren alinear por arriba, cambio de márgenes a mitad de documento, inicio de un párrafo con una "letra capital" (de mayor tamaño que las demás), texto a doble espacio, enumeraciones interrumpidas por un párrafo que se reanudan a continuación, y un largo etcétera.

Lo llamativo del documento es la forma en que presenta toda esta información. El texto visible realmente no es importante (no es más que texto de relleno en latín). Lo importante es que cada uno de estos "ejemplos" se pueden observar directamente resueltos en el PDF y rodeados de una caja verde, sin más explicaciones. Al poner el ratón encima de la caja verde, aparece un "popup" (sólo si lo estamos visualizando con Acrobat Reader) que explica un poco más de qué trata ese caso particular.

Por ejemplo (imagen inferior), al pie de la primera página, donde iría el número de página, vemos un rectángulo vacío con borde verde. Dejando el ratón encima, el popup nos dice "How to get rid of page numbers". Y si hacemos clic en ese punto, se abrirá el navegador Web y nos llevará directamente a la entrada de la FAQ donde se resuelve esa duda.

En algunos lugares los rectángulos son rojos en lugar de verdes, indicando en este caso que se ha obtenido un resultado inesperado o erróneo (por ejemplo: texto borroso en el pdf, palabras pegadas, o referencias a páginas incorrectas). En este caso el enlace nos lleva a la explicación y solución del problema.

Es difícil de explicar, y lo mejor es que lo veas por tí mismo. Me ha parecido una forma muy original y efectiva de resumir muchas dudas frecuentes, con enlaces a sus soluciones.

 
9.3.09

Aqui veo texto chino

Esta entrada puede parecer off-topic (lo es), pero no he podido resistirme a ponerla. Además, como veremos, no está tan alejada de tema como pueda parecer.

Haz lo siguiente: abre el bloc de notas de Windows. Escribe dentro el siguiente texto (sin pulsar retorno de carro al final de la línea):

Aqui veo texto chino

Guarda el documento con el nombre que quieras y sal del bloc de notas. Ahora abre de nuevo el documento y... ¡sorpresa! ¡Todo sale en chino! Compruebalo.

A pesar de que pueda parecer un huevo de pascua, es en realidad un bug del bloc de notas. El asunto está explicado en Wikipedia, y aquí es donde hay una pequeña relación con el tema del blog. El asunto de las diferentes codificaciones de un fichero (latin1, utf8, etc) es un tema que aparece frecuentemente al migrar documentos latex de una plataforma a otra.

El problema básicamente proviene de que un archivo de texto "plano" no contiene información acerca de qué codificación utilizó el editor que lo creó. Ante esta ausencia de información, al abrir el documento el editor puede tomar diferentes estrategias: asumir que está en una odificación ampliamente utilizada como pueda ser ISO-8859-1 o Windows-1512, intentar "adivinar" qué codificación puede estar usando el fichero haciendo un análisis de los códigos que contiene, o no intentar adivinar ni suponer nada, sino dejar que el usuario especifique cómo debe interpretarse el fichero (ya sea mediante opciones del editor o ya sea leyendo el valor de las variables de entorno que especifican el lenguaje nativo del usuario).

En el caso del bloc de notas de Windows, la opción elegida es la segunda, esto es, intentar adivinar la codificación del fichero. Como vemos, su algoritmo falla en algunos casos ya que el texto que yo he puesto más arriba, escrito en castellano y en codificación ASCII, es tomado por texto chino en Unicode. Según Wikipedia, bug se dispara por cualquier texto corto formados por secuencias de 4 códigos ASCII + espacio + 3 ASCII + espacio + 3 ASCII + espacio + 5 ASCII. Aunque, como puede comprobarse, el texto que yo he descubierto no sigue esta secuencia estrictamente y sin embargo también dispara el bug (parece que la clave es el inicio 4+3+3)

Ah, tampoco he podido resistirme a traducir con Google el texto chino resultante. Al parecer dice algo como "Brasero muy árido, torsión de retención-Ching Chao" :-D

 
20.12.08

Marcando "por hacer"

A menudo, mientras estamos escribiendo un documento largo, nos encontramos con que dejamos algunas partes meramente esbozadas (o incluso en blanco) con la intención de volver sobre ellas más adelante para completarlas o mejorarlas. Naturalmente, estas partes del documento deberían ser marcadas de alguna forma. Cada uno tenemos nuestros truquitos al respecto. Algunos de los más comunes son:

  • Poner un comentario dentro del código fuente LaTeX, con una cadena de texto especial tal como "A REVISAR", de modo que podamos hacer una búsqueda posterior en el fichero para encontrar rápidamente estos puntos. El inconveniente de este enfoque es que en la versión PDF o impresa, tales comentarios no aparecen, por lo que si estamos dando a leer la versión preliminar a otra persona, no tendrá una pista clara de qué partes están incompletas y cuáles no.
  • Introducir esas cadenas especiales en el propio texto, no en comentarios. Esto deja constancia tanto en la versión de código fuente como en la versión impresa. El problema es que quizás esas anotaciones "para uno mismo" no deberían estar en el texto principal, pues estorban un poco su lectura.
  • Utilizar notas al margen (esto es, el comando \marginpar), para introducir las anotaciones específicas. Esto soluciona los dos problemas anteriores, pero aún tiene un pequeño inconveniente. La nota al margen aparecerá "más o menos" a la altura de la línea en la que se utilizó \marginpar, pero no siempre exactamente donde uno querría. Además, si la nota se refiere a un punto concreto dentro de la línea (p.ej: un espacio entre dos palabras) no hay forma de especificar este dato.
  • Para solucionar lo anterior yo me había creado mi propio comando que insertaba en el texto principal una fea y visible caja negra, junto con una nota al margen que explicaba la razón de esa marca. La caja negra actuaba a modo de "llamada" para la nota al margen.

Pero desde hace unos días tenemos otra alternativa, que yo pienso utilizar la próxima vez que me vea en esta necesidad. Se trata del paquete Todonotes. La idea es similar a la que yo estaba usando, pero con muchas facilidades para configurar el aspecto final de la nota al margen y de su punto de inserción en el texto principal. Entre otras cosas, permite especificar el color del texto y del fondo de la nota, asi como del borde de la caja que la contiene, y une esta caja mediante una línea al texto principal, al punto donde se insertó la nota en el código fuente. También permite crear notas "en línea", esto es, que no van al margen. Finalmente, casi lo más importante, puede generar una "Lista de notas" que recoge todos los puntos del documento marcados con este tipo de anotaciones, con referencias a cada página y al color usado. Por si no me he explicado bien, creo que un vistazo al manual aclarará perfectamente lo que este paquete puede hacer.

 
 

Powered by Blogger