butterfly and sky




butterfly and sky


Originally uploaded by dsevilla.



.







Originally uploaded by dsevilla.



Solución al acertijo de C++

Hace unos días planteé un problema, y como nadie lo ha resuelto, plantearé la solución. Como recordaréis, quería hacer una función que retornara el centro de un rectángulo que podría ser de tipo Gdk::Rectangle ó Pango::Rectangle, por lo que creé la siguiente función template:


template <class Rect> Rect
middleOfRect(Rect& r)
{
Rect _r;

_r.set_x(r.get_x() + r.get_width() / 2);
_r.set_y(r.get_y() + r.get_height() / 2);

return _r;
}


Y dije que tenía un problema. ¿Qué pasa si por ejemplo Rect es "const Gtk::Rectangle? El código no funcionará, porque como se ve, dentro de la función se crea un elemento de tipo Rect, que no se puede modificar. Como C++ no tiene sintaxis para referirse a un tipo «sin const» dentro de un template, la única solución que se me ocurre es modificarla de tal manera que dependa de dos argumentos, y que se retorne uno de ellos modificado:


template <class Rect1, class Rect2> void
middleOfRect(Rect1& r, Rect2& rdest)
{
rdest.set_x(r.get_x() + r.get_width() / 2);
rdest.set_y(r.get_y() + r.get_height() / 2);
}


Nótese cómo ahora la función modifica rdest, que obligatoriamente tiene que ser no-const, y que no se retorna ningún elemento; sólo se modifica el parámetro rdest.

Así, por ejemplo, podríamos tener:


Gdk::Rectangle middle;
const Gdk::Rectangle& r = element.boundingRect();

middleOfRect( r, middle );

// usar "middle" aquí


Espero que no se hagan muy pesados este tipo de entradas...

Cómo crear una cámara con una caja de cerillas

Pues sí. A ver si tengo un rato y lo pruebo. Cada vez me gusta más la fotografía. Cuando tenga tiempo, me voy a poner a investigarlo:



amanecer en los alcázares




amanecer en los alcázares


Originally uploaded by dsevilla.



Más de C++

Siento ser tan pesado, pero es en lo que estoy trabajando últimamente. En el último post incluí una manera de tratar de igual forma a un Pango::Rectangle y un Gdk::Rectangle teniendo en cuenta que tienen el mismo interfaz. Pues bien, se me ocurrió hacer una cosa parecida para encontrar el punto medio de un rectángulo. El punto medio se retorna como las coordenadas x e y de un nuevo rectángulo devuelto:


template <class Rect> Rect
middleOfRect(Rect& r)
{
Rect _r;

_r.set_x(r.get_x() + r.get_width() / 2);
_r.set_y(r.get_y() + r.get_height() / 2);

return _r;
}


Sé que estamos en verano y todo eso, pero precisamente por ello, os dejo un reto. Esta función tiene un problema que hace que en C++ no funcione con _ciertos_ valores de clase Rect (y no me refiero al hecho del redondeo en la división, etc.) ¿Sabéis cuál es? Mañana, si nadie lo ha sacado, publicaré la solución. Como pista diré que es un problema intrínseco de los templates de C++.

Trabajo de verano

Este verano estoy aprovechando para avanzar lo que me queda pendiente de programar de la tesis, que con suerte será finiquitada este año. Más que nunca veo el final, por lo que estoy contento.

En esta última instancia estoy haciendo un programa gráfico de edición de «ensamblados» de componentes. Hablaré más sobre ello, pero por ahora sólo quiero apuntar un par de cosas sobre el trabajo gráfico que estoy realizando. Escogí (ahora veo que tuve suerte y elegí bien), gtkmm, la versión C++ de GTK. Ya me había sorprendido antes por lo bien construida que estaba a partir de un sistema de objetos basado en C como es GTK, generando automáticamente la mayoría del código de Gtkmm. Además, Pango es la octava maravilla del mundo (créanme), simplificando sobremanera la tipografía de una aplicación gráfica en Gnome. Pero también hablaré más de eso. Por ahora me gustaría sólo incluir una solución a un pequeño problema que presenta esta librería y que se me ha ocurrido y me parece a la vez ingeniosa y que muestra las capacidades de C++.

La clase rectángulo (Gdk::Rectangle) tiene las funciones habituales, get _ x(), get _ y(), get _ width() y get _ height(). Para realizar dibujos y cálculos sobre áreas de la pantalla es necesario usar esta clase. El caso es que si también se utiliza Pango, uno también dispone de la clase Pango::Rectangle, con exactamente las mismas funciones de acceso y modificación.

Durante el desarrollo de la aplicación he tenido que usar ambos tipos de rectángulos, pero se me ocurrió hacer una función que desplazaba una cantidad x e y un rectángulo:


static void
displaceRect (Gdk::Rectangle& r, int x, int y)
{
r.set_x (x + r.get_x());
r.set_y (y + r.get_y());
}


Esta funciona my bien para Gdk::Rectangle, pero no para Pango::Rectangle. La solución obvia hubiera sido reescribir la función sobrecargada para el otro tipo de rectángulo y con el mismo código. Pero entonces pensé en los «templates» de C++. Es sencillo hacer un _template_ para clases que tienen el mismo interfaz (por ejemplo, porque tienen relaciones de herencia), pero también se puede hacer si las clases tienen el mismo interfaz y no están realacionadas por herencia. Así, la función quedó:


template <class Rect> void
displaceRect (Rect& r, int x, int y)
{
r.set_x (x + r.get_x());
r.set_y (y + r.get_y());
}


Que ahora vale tanto para Gdk::Rectangle como para Pango::Rectangle, y automáticamente, además. Que nadie me pregunte por qué me gusta C++ :)

.







Originally uploaded by dsevilla.



flying in blue




flying in blue


Originally uploaded by dsevilla.