Logo Studenta

Proyecto01 - Rogelio Manríquez Cobián (9)

¡Estudia con miles de materiales!

Vista previa del material en texto

Proyecto 01: Aplicación de dibujo asistido por 
computadora. 
Elizabeth Amavizca Cuellar 
Gráficos por computadora 
Dr. Carlos Hugo García Capulín 
11 de noviembre de 2022 
 e.amavizcacuellar@ugto.mx 
 
Gael Alexis Morales Flores 
Gráficos por computadora 
Dr. Carlos Hugo García Capulín 
11 de noviembre de 2022 
ga.moralesflores@ugto.mx 
 
Rogelio Manríquez Cobián 
Gráficos por computadora 
Dr. Carlos Hugo García Capulín 
11 de noviembre de 2022 
r.manriquezcobian@ugto.mx 
 
Resumen— En este documento se realiza una aplicación de 
dibujo asistido por computadora, esta aplicación es de escritorio 
permitiendo al usuario dibujar diferentes figuras geométricas y 
realizar transformaciones con estas. 
Términos clave—figuras, geometría, dibujo, plano. 
I. INTRODUCCIÓN 
En este proyecto se emplea el uso de la API OpenGL, la 
cual es una herramienta de gráficos que especifica una interfaz 
de software estándar para hardware de procesamiento de 
gráficos 2D y 3D, de igual manera se utiliza la biblioteca 
GLUT para las utilidades de control de ventanas y el 
monitoreo de las entradas del teclado y ratón. 
Con estas herramientas de desarrollo, se implementará una 
aplicación de dibujo asistido por computadora tipo “Paint”, en 
la cual se hará el manejo de elementos geométricos básicos y 
transformaciones geométricas para su correcto 
funcionamiento permitiendo que el usuario tenga interacción 
con la aplicación mediante el uso del ratón y teclado; de modo 
que, toda la codificación del proyecto será utilizando el 
lenguaje de programación C. 
Por lo tanto, en el siguiente bloque se estará explicando el 
desarrollo de cómo se realizó la aplicación de dibujo para 
luego observar los resultados obtenidos mediante un video y 
discutir sobre la funcionalidad de la aplicación. 
II. DESARROLLO 
A continuación, se describen las estructuras de datos 
creadas especialmente para la manipulación de las figuras 
geométricas dentro del programa. Es necesario mencionar que 
las estructuras correspondientes a las figuras tienen en común 
4 atributos, estos atributos son: 
⁘ Gui: define si la figura es para la interfaz de usuario. 
⁘ Tipo de línea: define si la línea es punteada o recta. 
⁘ Grosor: define el grosor de las líneas de la figura. 
⁘ Color: define el color de la figura. 
⁘ Ángulo: define el ángulo de inclinación de la figura. 
A. Estructura punto. 
Esta estructura de datos contiene las variables que pueden 
esperarse de un punto, contiene el conjunto de coordenadas 
(X, Y). 
typedef struct{ 
 float x; 
 float y; 
}PUNTO; 
B. Estructura de datos línea. 
Esta estructura de datos contiene lo necesario para trazar 
una línea, se tienen dos puntos correspondientes al inicio y al 
fin de la línea que, a su vez, tienen coordenadas (X, Y). 
typedef struct{ 
 PUNTO ini; 
 PUNTO fin; 
 char gui; 
 char tipoLinea; 
 unsigned int grosor; 
 float angulo; 
 COLOR color; 
}LINEA; 
C. Estructura de datos cuadrado. 
Esta estructura contiene un atributo de tipo punto que 
corresponde al pivote de la figura, este se encuentra en la 
parte inferior izquierda del cuadrado y un atributo de tipo 
flotante que hace referencia al valor de cada lado del 
cuadrado. 
typedef struct{ 
 PUNTO piv; 
 float lado; 
 char gui; 
 char tipoLinea; 
 unsigned int grosor; 
 float angulo; 
 COLOR color; 
}CUADRADO; 
D. Estructura de datos rectángulo. 
La estructura contiene un atributo pivote de tipo punto, 
además de dos valores de tipo flotante correspondientes al 
ancho y alto del rectángulo. 
typedef struct{ 
 PUNTO piv; 
 float ancho; 
 float alto; 
 char gui; 
 char tipoLinea; 
 unsigned int grosor; 
 float angulo; 
 COLOR; 
}RECTANGULO; 
E. Estructura de datos círculo. 
El círculo contiene un atributo de tipo punto c 
correspondiente al centro del círculo y uno de tipo flotante 
que se refiere al radio de la figura. 
typedef struct{ 
 PUNTO c; 
 float radio; 
 char gui; 
 char tipoLinea; 
 unsigned int grosor; 
 float angulo; 
 COLOR color; 
}CIRCULO; 
mailto:e.amavizcacuellar@ugto.mx
mailto:ga.moralesflores@ugto.mx
mailto:r.manriquezcobian@ugto.mx
F. Estructura de datos polígono. 
Al igual que el círculo esta figura contiene un atributo c 
correspondiente al centro, un radio de tipo flotante y un 
número de lados de tipo entero. 
typedef struct{ 
 PUNTO c; 
 float radio; 
 int numLados; 
 char gui; 
 char tipoLinea; 
 unsigned int grosor; 
 float angulo; 
 COLOR color; 
}POLIGONO; 
G. Estructura de datos elipse. 
Como cualquier elipse se tiene un punto correspondiente 
al centro de esta, también se tiene un eje mayor y un eje 
menor que son atributos de tipo flotante. 
typedef struct{ 
 PUNTO c; 
 float eje_mayor; 
 float eje_menor; 
 char gui; 
 char tipoLinea; 
 unsigned int grosor; 
 float angulo; 
 COLOR color; 
}ELIPSE; 
H. Estructura de datos triángulo isósceles. 
Esta figura contiene un pivote que es una variable de tipo 
punto y, como cualquier triángulo, posee una altura y una 
base de tipo flotante. 
typedef struct{ 
 PUNTO piv; 
 float base; 
 float altura; 
 char gui; 
 char tipoLinea; 
 unsigned int grosor; 
 float angulo; 
 COLOR color; 
}TRIANGULO_ISO; 
I. Estructura de datos triángulo rectángulo. 
El triángulo rectángulo posee los mismos atributos que el 
triángulo isósceles, es posible diferenciarlos en el plano 
debido al método de dibujado implementado. 
typedef struct{ 
 PUNTO piv; 
 float base; 
 float altura; 
 char gui; 
 char tipoLinea; 
 unsigned int grosor; 
 float angulo; 
 COLOR color; 
}TRIANGULO_RECT; 
Durante el programa se hace uso de diferentes variables 
globales, estas son utilizadas para actividades como selección 
de figura, valores constantes para el escalamiento y cálculos, 
coordenadas del ratón y detección de dibujado de figuras. 
const float pi = 3.14159; 
const float escalaArriba = 1.1, 
 escalaAbajo = 0.9, 
 angulo = 10; 
unsigned int seleccionFigura = 0; 
char coordenadas[40] = "(0,0)"; 
char primerPunto[8] = {1, 1, 1, 1, 1, 1, 1, 1}; 
char puntoFinal = 0; 
Posteriormente se realiza la creación de las figuras que se 
utilizan durante el código, en este caso es una figura de cada 
tipo y se utilizan más figuras del mismo tipo para la interfaz 
de usuario, estas figuras se distinguen por contener la letra g 
previo a su nombre. 
// FIGURAS GEOMÉTRICAS PARA MANIPULAR 
LINEA L, gL, gL1, gL2, gL3; 
CUADRADO CU, gCU, gCU1; 
RECTANGULO R, gR; 
POLIGONO P, gP; 
CIRCULO CI, gCI; 
ELIPSE E, gE; 
TRIANGULO_ISO TI, gTI; 
TRIANGULO_RECT TR, gTR; 
A continuación se describen las funciones contenidas en 
el código que no son referentes a la interacción con el usuario, 
estas se explicaran en el orden de ejecución en el programa. 
A. Función main. 
En esta función se realizan las configuraciones necesarias 
para el programa, en este caso se inicializa la librería GLUT, 
se configuran parámetros de la ventana, título, funciones para 
el manejo del ratón y teclado, también se realiza la 
configuración de las figuras utilizadas para la interfaz de 
usuario. 
int main(int argc, char **argv){ 
 glutInit(&argc,argv); 
 glutInitWindowSize(tamVentana, tamVentana); 
 glutCreateWindow("Proyecto 1:…"); 
 // CONFIGURACIÓN FIGURAS GUI 
 figurasGUI(); 
 glMatrixMode(GL_PROJECTION); 
 glLoadIdentity(); 
 // DIVISIÓN DEL LIENZO EN 20x20 
 glOrtho(-10, 10, -10, 10, 1.0, -1.0); 
 glMatrixMode(GL_MODELVIEW); 
 // FUNCIÓN DE DISPLAY 
 glutDisplayFunc(display); 
 // FUNCIONES PARA EL RATÓN 
 glutPassiveMotionFunc(ratonPasivo); 
 glutMotionFunc(ratonActivo); 
 glutMouseFunc(raton); 
 // FUNCIONES PARA EL TECLADO 
 glutSpecialFunc(teclasEspeciales); 
 glutKeyboardFunc(teclasNormales); 
 glutMainLoop(); 
 return 0; 
} 
B. Función display. 
En esta función se realiza una limpieza del buffer y se 
ejecutan dos funciones del programa que se encargan de 
mostrar todo lo correspondiente a la interfaz de usuario y 
mostrar las figuras dibujadas en el plano. 
void display(void){glClearColor(1,1,1,1); 
 glClear(GL_COLOR_BUFFER_BIT); 
 mostrarGUI(); 
 mostrarFiguras(); 
 glFlush(); 
} 
C. Función mostrar GUI. 
Como su nombre lo indica esta función se encarga de 
mostrar todos los elementos gráficos necesarios para la 
interfaz de usuario, en este caso se dibujan rectángulos y se 
dibujan figuras que son de tipo GUI, además de mostrar los 
textos en la interfaz para el usuario. 
void mostrarGUI(){ 
 AsignaColor(NEGRO); 
 // BORDES SUPERIOR E INFERIORES 
 glRectf(-10.0, 10.0, 10.0, 8.8); 
 glRectf(-10.0, -10.0, -7.8, -9.5); 
 // BOTÓN LÍNEA 
 AsignaColor(GRIS_OSCURO); 
 glRectf(-9.5, 9.9, -8.5, 8.9); 
 linea(gL); 
⋮ 
 AsignaColor(BLANCO); 
 dibujarTexto("Color", -9.98, 5.55); 
 dibujarTexto("[ Figura seleccionada ]", 0, 9.5); 
 switch(seleccionFigura){ 
 case 0: 
 dibujarTexto("[ Ninguna ]", 0, 9.0); 
 break; 
 case 1: 
 dibujarTexto("[ Linea ]", 0, 9.0); 
 break; 
⋮ 
 } 
 AsignaColor(BLANCO); 
 dibujarTexto(coordenadas, -9.8, -9.9); 
} 
D. Función mostrar figuras. 
Debido a que solo se dibuja una figura de cada tipo al 
momento de mostrar las figuras se comprueba si el usuario ha 
dibujado o no esta figura, es decir, la ha seleccionado y hecho 
clic izquierdo en el plano. Una parte de esta función es que 
obtiene el tipo de línea mediante los atributos de cada figura 
y su grosor para dibujarse de la forma que el usuario desee. 
void mostrarFiguras(void){ 
 if(!primerPunto[0]){ 
 glLineWidth(L.grosor); 
 if(L.tipoLinea){ 
 glEnable(GL_LINE_STIPPLE); 
 glLineStipple(1, 0x000F); 
 } 
 linea(L); 
 if(L.tipoLinea) 
 glDisable(GL_LINE_STIPPLE); 
 glLineWidth(1.0); 
 } 
 if(!primerPunto[1]){ 
⋮ 
 if(!primerPunto[7]){ 
 glLineWidth(TR.grosor); 
 if(TR.tipoLinea){ 
 glEnable(GL_LINE_STIPPLE); 
 glLineStipple(1, 0x000F); 
 } 
 trianguloRect(TR); 
 if(TR.tipoLinea) 
 glDisable(GL_LINE_STIPPLE); 
 glLineWidth(1.0); 
 } 
 glutPostRedisplay(); 
} 
E. Funciones para dibujar figuras. 
Estas funciones se encargan de dibujar en el plano las 
figuras dentro del programa, estas reciben la figura 
correspondiente y, dependiendo sus valores de atributos se 
dibujan en una posición, ángulo y color diferente. 
// FUNCIONES DE DIBUJADO DE FIGURAS 
void linea(LINEA L); 
void cuadrado(CUADRADO C); 
void rectangulo(RECTANGULO R); 
void poligono(POLIGONO P); 
void circulo(CIRCULO CI); 
void elipse(ELIPSE E); 
void trianguloIso(TRIANGULO_ISO T); 
void trianguloRect(TRIANGULO_RECT T); 
Tras realizar una breve explicación del funcionamiento de 
las funciones que no interactúan directamente con el usuario 
se realiza una explicación de las funciones que sí interactúan 
con el usuario, específicamente se describirán las funciones 
correspondientes a la interacción utilizando el teclado y ratón. 
A. Función de ratón (botones). 
GLUT permite detectar si el usuario ha presionado un 
botón del ratón, esto se aprovecha para implementar la 
selección de figura, color, etc. Es necesario mencionar que las 
coordenadas correspondientes al ratón otorgadas por GLUT 
son necesarias de convertir a coordenadas del plano para 
utilizarlas, esto se hace mediante una función propia. 
void raton(int boton, int estado, int x, int y){ 
 PUNTO pt = CVent_a_Cplano(… ); 
 // AL PRESIONAR EL BOTÓN 
 if(estado == GLUT_DOWN) 
 switch(boton){ 
 case GLUT_LEFT_BUTTON: 
 clicIzquierdo(pt); 
 break; 
 case GLUT_RIGHT_BUTTON: 
 clicDerecho(pt.x, pt.y); 
 break; 
 } 
 // AL SOLTAR EL BOTÓN 
 if(estado == GLUT_UP) 
 switch(boton){ 
 case GLUT_LEFT_BUTTON: 
 if(seleccionFigura==1&&puntoFinal==0) 
 puntoFinal = 1; 
 break; 
 } 
} 
Para las acciones a realizar por cada botón se han 
realizado funciones específicas para simplificar el código, 
estas funciones corresponden a la pulsación del clic izquierdo 
y derecho. 
B. Función clic derecho. 
El clic derecho se encarga de realizar la selección de la 
figura a manipular, cambiar el color de la figura seleccionada 
y eliminar las figuras en el plano. 
void clicDerecho(float x_, float y_){ 
 // REGIONES DE FIGURAS GEOMÉTRICAS 
 if(((x_>=-9.5)&&(x_<=-8.5))&&((y_>=8.9)&&(y_<=9.9))) 
 seleccionFigura = 1; // REGIÓN DE LÍNEA 
 else if(((x_>=-8.4)&&(x_<=-7.4))&&((y_>=8.9)&&(y_<=9.9))) 
 seleccionFigura = 2; // REGIÓN DE CUADRADO 
⋮ 
 // REGIONES DE COLORES 
 if(((x_>=-9.9)&&(x_<=-9.1))&&((y_<=5.4)&&(y_>=4.6))) 
 cambiarColor(AZUL); 
 else if(((x_>=-9.9)&&(x_<=-9.1))&&((y_<=4.5)&&(y_>=3.7))) 
 cambiarColor(VERDE); 
⋮ 
 // REGIONES DE TRANSFORMACIONES GEOMÉTRICAS 
 if(((x_>=8.5)&&(x_<=9.5))&&((y_<=9.9)&&(y_>=8.9))) 
 borrarFiguras(); 
 else if(((x_>=7.4)&&(x_<=8.4))&&((y_<=9.9)&&(y_>= 8.9))) 
 borrarFigura(); 
} 
C. Función clic izquierdo. 
El clic derecho se encarga de dibujar por primera vez las 
figuras, inicializa la figura con valores preestablecidos y 
permite que puedan dibujarse en el plano mediante otra 
función que comprueba las figuras dibujadas. 
void clicIzquierdo(PUNTO pt){ 
 puntoInicial = pt; 
 switch(seleccionFigura){ 
 case 1: // FIGURA LÍNEA 
 if(primerPunto[0]){ 
 L.color = NEGRO; 
 L.ini = pt; 
 L.gui= 0; 
 L.grosor = 1; 
 L.tipoLinea = 0; 
 primerPunto[0] = 0; 
 } 
 break; 
⋮ 
 case 8: // FIGURA TRIÁNGULO RECTÁNGULO 
 if(primerPunto[7]){ 
 TR.color = NEGRO; 
 TR.altura = 3; 
 TR.base = 3; 
 TR.piv = pt; 
 TR.grosor = 1; 
 TR.tipoLinea = 0; 
 primerPunto[7] = 0; 
 } 
 break; 
 } 
} 
D. Función de ratón pasivo. 
Esta función aprovechando la configuración ofrecida por 
GLUT con nombre glutPassiveMotionFunc se utiliza para 
almacenar constantemente la posición del ratón dentro del 
plano para posteriormente imprimirse con otra función. 
void ratonPasivo(int x, int y){ 
 PUNTO pt=CVent_a_Cplano(x,y,tamVentana,tamVentana,-10,10,-10,10); 
 sprintf(coordenadas,"(%.1f,%.1f)",pt.x,pt.y); 
} 
E. Función ratón activo. 
Considerando el funcionamiento de esta función con la 
configuración de GLUT que ofrece utilizando 
glutMotionFunc se aprovecha para la visualización del 
dibujado de la línea por primera vez y para realizar la 
traslación de las figuras, las coordenadas dadas por la 
posición del ratón son convertidas para trasladar las figuras 
por el plano. 
Void ratonActivo(int x, int y){ 
 PUNTO pt = Cvent_a_Cplano(x, y, tamVentana, 
tamVentana, -10, 10, -10, 10); 
 float tx, ty, theta; 
 sprintf(coordenadas,”(%.1f,%.1f)”,pt.x,pt.y); 
 glutPostRedisplay(); 
 switch(seleccionFigura){ 
 case 1: // FIGURA LÍNEA 
 if (puntoFinal == 1){ 
 tx = pt.x – puntoInicial.x; 
 ty = pt.y – puntoInicial.y; 
 puntoInicial = pt; 
 L.ini.x += tx; 
 L.ini.y += ty; 
 L.fin.x += tx; 
 L.fin.y += ty; 
 } 
 else 
 L.fin = pt; 
 break; 
⋮ 
case 8: // FIGURA TRIÁNGULO RECTÁNGULO 
 if(¡primerPunto[7]) 
 TR.piv = pt; 
 break; 
 } 
} 
Comprendiendo el funcionamiento de las funciones que 
interactúan con el usuario mediante el ratón se explica 
brevemente las funciones que interactúan con el usuario 
mediante el teclado. 
A. Función teclas especiales. 
De la misma forma que se implementa el ratón se utiliza 
la configuración ofrecida por GLUT glutSpecialFunc para la 
interacción mediante el teclado con las teclas especiales, en 
este caso se implementan las pulsaciones correspondientes a 
las teclas de navegación para la rotación y escalamiento de 
las figuras. 
void teclasEspeciales(int tecla, int x, int y){ 
 switch(tecla){ 
 case GLUT_KEY_LEFT: 
 teclaIzquierda(); 
 break; 
 caseGLUT_KEY_RIGHT: 
 teclaDerecha(); 
 break; 
 case GLUT_KEY_UP: 
 teclaArriba(); 
 break; 
 case GLUT_KEY_DOWN: 
 teclaAbajo(); 
 break; 
 } 
 glutPostRedisplay(); 
} 
Para la rotación de las figuras se utilizan la tecla con 
dirección izquierda y derecha, esto para rotar en sentido 
horario y antihorario. 
B. Función tecla derecha. 
Para la rotación con sentido horario se utiliza un ángulo 
dado en grados para rotar la figura seleccionada (este ángulo 
puede ser modificado cambiando el valor de la variable 
global) sumando este al ángulo de inclinación actual de la 
figura seleccionada. 
void teclaDerecha(void){ 
 switch(seleccionFigura){ 
 case 1: // FIGURA LÍNEA 
 L.angulo += angulo; 
 break; 
⋮ 
 case 8: // FIGURA TRIÁNGULO RECTÁNGULO 
 TR.angulo += angulo; 
 break; 
 } 
} 
C. Función tecla izquierda. 
Para el sentido antihorario se realiza la resta 
correspondiente a los ángulos de inclinación actual de la 
figura seleccionada. 
void teclaIzquierda(void){ 
 switch(seleccionFigura){ 
 case 1: // FIGURA LÍNEA 
 L.angulo -= angulo; 
 break; 
⋮ 
 case 8: // FIGURA TRIÁNGULO RECTÁNGULO 
 TR.angulo -= angulo; 
 break; 
 } 
} 
Para el escalamiento de las figuras se utilizan las teclas 
con dirección arriba y abajo, de esta forma se aumenta o 
disminuye el tamaño de las figuras, el valor de escala puede 
ser modificado mediante las variables globales 
implementadas. 
D. Función tecla arriba. 
Aprovechando el escalamiento para aumentar el tamaño 
de la figura se utiliza un valor mayor a la unidad, para este 
escalamiento se implementa la interacción con la tecla con 
dirección arriba, la siguiente función se encarga de aumentar 
ligeramente las dimensiones de la figura. 
void teclaArriba(void){ 
 switch(seleccionFigura){ 
 case 1: // FIGURA LÍNEA 
 L.ini.x *= escalaArriba; 
 L.ini.y *= escalaArriba; 
 L.fin.x *= escalaArriba; 
 L.fin.y *= escalaArriba; 
 break; 
⋮ 
 case 8: // FIGURA TRIÁNGULO RECTÁNGULO 
 TR.base *= escalaArriba; 
 TR.altura *= escalaArriba; 
 break; 
 } 
} 
E. Función tecla abajo. 
Para la disminución de tamaño de las figuras se 
implementa la interacción con la tecla con dirección abajo, en 
este caso se utiliza una escala menor a la unidad para 
modificar las dimensiones de las figuras. 
void teclaAbajo(void){ 
 switch(seleccionFigura){ 
 case 1: // FIGURA LÍNEA 
 L.ini.x *= escalaAbajo; 
 L.ini.y *= escalaAbajo; 
 L.fin.x *= escalaAbajo; 
 L.fin.y *= escalaAbajo; 
 break; 
⋮ 
 case 8: // FIGURA TRIÁNGULO RECTÁNGULO 
 TR.base *= escalaAbajo; 
 TR.altura *= escalaAbajo; 
 break; 
 } 
} 
Después de explicar las teclas especiales configuradas 
para el programa se describen las teclas normales 
configuradas en la siguiente función. 
A. Función de teclas normales. 
Para esta función se configura un total de seis teclas, estas 
son utilizadas para cerrar el programa, cambiar el tipo de 
línea de las figuras, el grosor de los bordes de las figuras y 
aumentar el número de lados del polígono. 
void teclasNormales(unsigned char tecla,int x,int y){ 
 switch(tecla){ 
 case 27: 
 exit(0); 
 break; 
 case 'l': 
 teclaL(); 
 break; 
 case 'q': 
 if(P.numLados<7&&seleccionFigura==4) 
 P.numLados++; 
 break; 
 case 'w': 
 if(P.numLados>4&&seleccionFigura==4) 
 P.numLados--; 
 break; 
 case '+': 
 masGrosor(); 
 break; 
 case '-': 
 menosGrosor(); 
 break; 
 } 
} 
B. Función de cambio de tipo de línea. 
Para el cambio de tipo de línea de las figuras se 
implementa la siguiente función donde se realiza un cambio 
en el atributo de la figura seleccionada. 
void teclaL(void){ 
 switch(seleccionFigura){ 
 case 1: // FIGURA LÍNEA 
 L.tipoLinea = !L.tipoLinea; 
 break; 
⋮ 
 case 8: // FIGURA TRIÁNGULO RECTÁNGULO 
 TR.tipoLinea = !TR.tipoLinea; 
 break; 
 } 
} 
C. Función más grosor. 
Esta función aumenta el grosor correspondiente a la figura 
seleccionada durante la ejecución del programa, para 
aumentar el grosor se hace un incremento en el atributo de la 
figura. 
void masGrosor(void){ 
 switch(seleccionFigura){ 
 case 1: // FIGURA LÍNEA 
 L.grosor += 1; 
 break; 
⋮ 
 case 8: // FIGURA TRIÁNGULO RECTÁNGULO 
 TR.grosor += 1; 
 break; 
 } 
} 
D. Función menos grosor. 
Esta función disminuye el grosor correspondiente a la 
figura seleccionada durante la ejecución del programa, para 
esto se decrementa el atributo de la figura. 
void menosGrosor(void){ 
 switch(seleccionFigura){ 
 case 1: // FIGURA LÍNEA 
 L.grosor -= 1; 
 break; 
⋮ 
 case 8: // FIGURA TRIÁNGULO RECTÁNGULO 
 TR.grosor -= 1; 
 break; 
 } 
} 
Por último, se tienen funciones que son utilizadas en el 
programa, pero no han sido explicadas anteriormente. 
E. Función coordenadas ventana a plano. 
Esta función se encarga de realizar una conversión de las 
coordenadas otorgadas del ratón a coordenadas que puedan 
interpretarse dentro del plano en el rango [-10, 10] para la 
interacción con el usuario, esta recibe las coordenadas de la 
ventana y regresa un punto con ambas coordenadas 
convertidas. 
PUNTO CVent_a_Cplano(int x, int y,int AnchoV, int 
AltoV, float xini, float xfin, float yini, float 
yfin){ 
 PUNTO pos; 
 float RangoX = xfin - xini; 
 float RangoY = yfin - yini; 
 float porcentaje; 
 porcentaje = ((float)x/AnchoV); 
 pos.x = (porcentaje*(RangoX)) - (RangoX)/2; 
 porcentaje = ((float)y/AltoV); 
 pos.y=((1-porcentaje)*(RangoY))-(RangoX)/2; 
 return pos; 
} 
F. Función cambiar color. 
Esta función es utilizada cuando el usuario tiene una 
figura seleccionada y hace clic en un botón de color, esta se 
encarga de cambiar el atributo de color de la figura al color 
que reciba mediante el clic realizado. 
void cambiarColor(COLOR color){ 
 switch(seleccionFigura){ 
 case 1: // COLOR LÍNEA 
 L.color = color; 
 break; 
⋮ 
 case 8: // COLOR TRIÁNGULO RECTÁNGULO 
 TR.color = color; 
 break; 
 } 
} 
G. Función borrar figuras. 
Esta función es invocada cuando se utiliza el botón 
ubicado en la esquina superior derecha, su objetivo es limpiar 
el plano eliminando todas las figuras dibujadas para que, si 
vuelven a dibujarse, sus atributos sean reiniciados teniendo 
una figura base nuevamente (grosor, ángulo, color). 
void borrarFiguras(void){ 
 int k; 
 puntoFinal = 0; 
 for(k = 0; k<8; k++) 
 primerPunto[k] = 1; 
} 
H. Función borrar figura. 
A diferencia de la función borrar figuras en este caso se 
elimina solamente la figura que esté seleccionada en la 
ejecución del programa de forma que, cuando se hace clic en 
el botón la figura desaparezca y cuando vuelva a ser dibujada 
sea una figura base sin conservar los atributos anteriores. 
void borrarFigura(void){ 
 switch(seleccionFigura){ 
 case 1: // FIGURA LÍNEA 
 puntoFinal = 0; 
 primerPunto[0] = 1; 
 break; 
⋮ 
 case 8: // FIGURA TRIÁNGULO RECTÁNGULO 
 primerPunto[7] = 1; 
 break; 
 } 
} 
III. PRUEBAS Y RESULTADOS 
Para la demostración de pruebas y resultados se recurre a 
la visualización de un video grabado demostrando el 
funcionamiento del código implementado. Enlace al video de 
la aplicación de dibujo en OneDrive: 
 
Video demostrativo. [2] 
Para analizar el código del proyecto y poder ejecutarlo 
junto con las instrucciones de compilación; este se encontrará 
en un repositorio de GitHub que se puede consultar en la 
sección de “REFERENCIAS”. [1] 
IV. CONCLUSIONES 
Gael Alexis Morales Flores. 
Durante la implementación del programa se han 
aprendido una gran cantidad de cosas, fue requerido analizarpreviamente el objetivo a cumplir para posteriormente 
comenzar con el diseño del programa, la interacción con el 
usuario es importante por lo que se ha intentado simplificar 
lo más posible para un fácil entendimiento. La forma en que 
las figuras hacen “lo mismo” pero en código es diferente ha 
sido muy importante para evitar problemas de lógica. 
Finalmente se ha obtenido una aplicación funcional que 
cumple con los requisitos correctamente y un código intuitivo 
fácil de manipular y entender. 
Elizabeth Amavizca Cuellar. 
En la realización del proyecto nos surgieron varias 
situaciones las cuales pudimos resolver gracias a la ayuda del 
profesor e investigación propia, tuvimos inconvenientes al 
momento de encontrar una forma en la que el entorno de 
nuestro programa fuese eficiente y amable con el cliente, 
debimos tener en cuenta lo que sería más cómodo al momento 
de utilizar nuestro programa; así mismo en nuestras 
investigaciones pudimos encontrar maneras nuevas que 
harían más compacto nuestro código. 
Rogelio Manríquez Cobián. 
Como primer comentario acerca del proyecto, se agradece 
al compañero de equipo Gael Morales por su gran ayuda y 
paciencia durante el desarrollo de la aplicación de dibujo. 
Entonces, como observaciones acerca del proyecto, se 
pensaba que realizar la aplicación sería una tarea difícil ya 
que, se desconocía la manera de la implementación y 
funcionamiento de éste, sin embargo, durante el transcurso 
del curso, hemos visto muchas herramientas de dibujo y 
temas de geometría que en conjunto han sido muy útiles para 
el desarrollo del proyecto. 
Por otro lado, algunas curiosidades que ocurrieron 
durante la codificación de la aplicación fue que se estuvo 
agregando funcionalidades para que el usuario tenga una 
interacción con la aplicación como lo es el uso de ratón y 
teclado, esta implementación fue sencilla ya que las 
herramientas de GLUT permiten que la codificación sea aún 
más sencilla. Y acerca, de las transformaciones geométricas 
se estuvo trabajando constantemente, ya que solo se tenía 
como referencia previa de uso la figura línea, así que después 
de estar realizando pruebas, se encontró una manera, en la 
cual se podía hacer uso para las demás figuras. 
Para concluir, este proyecto dejó enseñanzas muy útiles 
principalmente de cómo utilizar OpenGL y sus herramientas 
como GLUT, sin embargo, sí que es muy importante saber 
principios de geometría básica para el manejo de las figuras. 
Así que, espero que seguir utilizando estas herramientas para 
la creación de otras aplicaciones de tipo 2D, y con ello, 
introducirme al uso de entornos 3D. 
https://ugtomx-my.sharepoint.com/:v:/g/personal/ga_moralesflores_ugto_mx/EcJ9Yg7FcOREhCA45l3_YOABp6LCUcc-_eqTASMNSOD-Dg?e=2B3dCQ
https://ugtomx-my.sharepoint.com/:v:/g/personal/ga_moralesflores_ugto_mx/EcJ9Yg7FcOREhCA45l3_YOABp6LCUcc-_eqTASMNSOD-Dg?e=2B3dCQ
https://ugtomx-my.sharepoint.com/:v:/g/personal/ga_moralesflores_ugto_mx/EcJ9Yg7FcOREhCA45l3_YOABp6LCUcc-_eqTASMNSOD-Dg?e=2B3dCQ�
REFERENCIAS 
[1] Github. Repositorio GPC_Proyecto01. Enlace: clic aquí. 
[2] Video demostrativo: clic aquí. 
https://github.com/Pokilul/GPC_Proyecto01
https://ugtomx-my.sharepoint.com/:v:/g/personal/ga_moralesflores_ugto_mx/EcJ9Yg7FcOREhCA45l3_YOABp6LCUcc-_eqTASMNSOD-Dg?e=2B3dCQ
	I. Introducción
	II. Desarrollo
	A. Estructura punto.
	B. Estructura de datos línea.
	C. Estructura de datos cuadrado.
	D. Estructura de datos rectángulo.
	E. Estructura de datos círculo.
	F. Estructura de datos polígono.
	G. Estructura de datos elipse.
	H. Estructura de datos triángulo isósceles.
	I. Estructura de datos triángulo rectángulo.
	Durante el programa se hace uso de diferentes variables globales, estas son utilizadas para actividades como selección de figura, valores constantes para el escalamiento y cálculos, coordenadas del ratón y detección de dibujado de figuras.
	Posteriormente se realiza la creación de las figuras que se utilizan durante el código, en este caso es una figura de cada tipo y se utilizan más figuras del mismo tipo para la interfaz de usuario, estas figuras se distinguen por contener la letra g p...
	A continuación se describen las funciones contenidas en el código que no son referentes a la interacción con el usuario, estas se explicaran en el orden de ejecución en el programa.
	A. Función main.
	B. Función display.
	C. Función mostrar GUI.
	D. Función mostrar figuras.
	E. Funciones para dibujar figuras.
	A. Función de ratón (botones).
	B. Función clic derecho.
	C. Función clic izquierdo.
	D. Función de ratón pasivo.
	E. Función ratón activo.
	A. Función teclas especiales.
	B. Función tecla derecha.
	C. Función tecla izquierda.
	D. Función tecla arriba.
	E. Función tecla abajo.
	A. Función de teclas normales.
	B. Función de cambio de tipo de línea.
	C. Función más grosor.
	D. Función menos grosor.
	E. Función coordenadas ventana a plano.
	F. Función cambiar color.
	G. Función borrar figuras.
	H. Función borrar figura.
	III. Pruebas y Resultados
	IV. Conclusiones
	Referencias

Continuar navegando