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
Y dije que tenía un problema. ¿Qué pasa si por ejemplo
Nótese cómo ahora la función modifica
Así, por ejemplo, podríamos tener:
Espero que no se hagan muy pesados este tipo de entradas...
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:


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
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++.
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 (
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:
Esta funciona my bien para
Que ahora vale tanto para
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++ :)






