Monday, October 1, 2007

Dibujando un Reguilete

Vercion en PDF

Con QT y C++
Jose Angel Espinoza Portillo
Graficación
Septiembre - Octubre 2007


Preámbulo
Utilizando el framework original de trabajo llamado “linetest”. El cual contiene los archivos de código siguientes:


  • painter.cpp y painter.h: Implementación del QWidget es la ventana principal del sistema, aquí se implementan los botones, geometría, eventos y elementos que se observan en la ventana de la aplicación.

  • canvas.cpp y canvas.h: Implementa del QWidget que representa a el área en la cual se va a dibujar. Incluye funciones de trazado de lineas las cuales son la función en la que me base para dibujar el REGUILETE.

  • main.cpp: Es el código que iniciativa la aplicación y le da la ejecución a el Qt para que interprete las instrucciones especificadas en canvas.cpp.



Figura 1.

Insertar Botones a el FrameWork proporcionado
Se agrego el inicio del constructor de Painter::Painter() en painter.cpp


QPushButton *boton1 = new QPushButton("Direccion");
boton1->setFont( QFont( "Times", 18, QFont::Bold ) );
connect( boton1, SIGNAL(clicked()), canvas, SLOT(changeDirection()) );

QPushButton *boton2 = new QPushButton("Start/Stop");
boton2->setFont( QFont( "Times", 18, QFont::Bold ) );
connect( boton2, SIGNAL(clicked()), canvas, SLOT(switchMotioin()) );

Para crear la instancia en memoria de los botones con nombres boton1 y boton2.
Al final de la misma función se agrego:

leftBox->addWidget( boton1 );
leftBox->addWidget( boton2 );

Justo antes del “setLayout(grid);”, al compilar se vera una pantalla como en la Figura 1.

Comunicación entre el Canvas y el Painter
Este proceso a sido documentado anteriormente, así que me limito a agregar solo las modificaciones realizadas para este proyecto.
Se agregaron los Slots changeDirection y switchMotioin, para que puedan se accesados desde los botones del painter como se explico en el punto anterior y timeDone para se acezado desde un objeto QTimer, que se explicara a continuación.

Solucionando el Problema
Como un requisito de este problema es hacer que los reguiletes roten, se necesitó planear 3 partes:

  • Desarrollar una función drawReguilete a la cual le pasan por parámetros el numero de astas del reguilete y su centro y lo dibuja.

  • Agregar un QTimer para determinar el lapso para cambio de coordenadas rotación.

  • Programar las funciones que administren los estados de los últimos dos, puntos.


Desarrollando la función drawReguilete()
Basado en la implementación ya dada por el profesor para dibujar un destello la función de reguilete se implemento como sigue:

void Canvas::drawReguilete(int cx, int cy, int lados, QPainter *p){
int incrang = 360/lados; // Incremento del angulo para saber el angulo medio de cada hoja del reguilete
int l = 50; // Se define un largo l de las lineas de las hojas

int n = 360/incrang; //Se define el numero de repeticiones del algoritmo

for ( int i=0; isetPen(QColor("Blue"));
MidPointLine( cx, cy, px, py, p ); // Se dibuja la linea superior
MidPointLine( cx, cy, px2, py2, p );// Se dibuja la linea inferior
MidPointLine( px2, py2, px, py, p );// Se dibuja la linea que une las anteriores para cerrarla
}
}

Agregando el QTimer
Esta es un objeto que te llama una función cada determinado tiempo que el programador le especifique, para implementarla en el código, se agrego la siguiente librería en canvas.cpp:

#include

y dentro del constructor Canvas::Canvas() se agrego el siguiente codigo:

tiempo = new QTimer(this);
connect( tiempo, SIGNAL(timeout()), this, SLOT(timeDone()));

El cual instancia en memoria el el objeto QTimer, en la variable tiempo, y la conecta en su SIGNAL timeout() al objeto canvas en su SLOT timeDone(), el cual se describe a continuación:

void Canvas::timeDone(){
angulo += (10 * direccion);
repaint();
}

En este código se puede ver que se presenta la variable dirección, esta es manejada por las funciones de administración de estados y define la dirección de rotación de los reguiletes, también se observa la variable ángulo que se usa en el dibujado de el reguilete, como el ángulo acumulado de rotación del sistema.

Funciones de administración de estados.
Las siguientes funciones son las que responden a los SLOTS changeDirection y switchMotioin las cuales administran el cambio de estados de el reguilete por medio de la variables globales dirección y tiempo.

void Canvas::changeDirection(){
direccion *= -1;
}

void Canvas::switchMotioin(){
if (tiempo->isActive()){
tiempo->stop();
}else{
tiempo->start(400);
}
}

En changeDirection solo se multiplica su contenido por -1 haciendo que a todo lo que sea multiplicado esta variable tendrá una dirección contraria a la original.
Y en switchMotioin se pregunta a tiempo si esta activo (si se esta ejecutando algún tonteo de lapsos), si es así lo detiene de lo contrario lo inicia.

Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home