Aplicacion_Graficando_Lineas
-
Upload
bonilla-gonzalez -
Category
Documents
-
view
221 -
download
4
description
Transcript of Aplicacion_Graficando_Lineas
S.E.P. D.G.E.S.T. D.I.T.D.
INSTITUTO TECNOLÓGICO SUPERIOR DE LIBRES Organismo Público Descentralizado del Gobierno del Estado de Puebla
INGENIERÍA EN SISTEMAS COMPUTACIONALES
“GRAFICACIÓN”
PRACTICA 3 “EJECUCIÓN DEL ALGORITMO DDA”
PRESENTA:
BONILLA GONZALEZ PABLO SÁNCHEZ BRISEÑO EVELIN ALEJANDRA
LIBRES, PUEBLA, FEBRERO 2012
1.- Algoritmo de Línea DDA
El analizador diferenciador digital (DDA - Digital Diferencial Analyzer) es un
algoritmo de conversión de rastreo que se basa en el calculo ya sea de Dy o Dx
por medio de ecuaciones.
Se efectúa un muestreo de la línea en intervalos unitarios en una coordenada y
se determina los valores enteros correspondientes mas próximos a la
trayectoria de la línea para la otra coordenada.
Tomemos una línea con pendiente positiva, si la pendiente | m | £ 1, se hace el
muestreo en x en intervalos unitarios (Dx = 1 y Dy = m dado que m = Dy / Dx) y
se calcula cada valor sucesivo de y como:
yk+1 = yk+ m
El subíndice toma valores enteros a partir de 1 y aumenta a razón de 1 hasta
alcanzar el valor final. Ya que m puede ser cualquier numero real entre 0 y 1,
los valores calculados de y deben redondearse al entero mas cercano.
Para líneas con una pendiente | m | > 1, se revierten las funciones de x y y, o
sea, se realiza un muestreo de y en intervalos unitarios (Dy = 1 y Dx = 1/m
dado que m = Dy / Dx) y se calcula cada valor sucesivo de x como:
xk+1 = xk+ 1/m
Las ecuaciones anteriores se basan en la suposición de que las líneas deben
procesarse del extremo izquierdo al derecho.
Si este procesamiento se revierte, entonces Dx o Dy serian
-1,yk+1 = yk - m o xk+1 = xk - 1/m(x I ,round(y I )) (xi ,y I ) (xi+1,round(y i+m))
(xi+1,y i+m) línea
Deseada Dx Dy
El procedimiento completo de dibujo seria el siguiente:
void Line(Display* display, Window win, GC gc, int x0, int y0, int x1, int y1)
{
float x, y, xs, ys;
int dx, dy, steps;
dx = x1 - x0;
dy = y1 - y0;
/* se asigna el punto de donde se comenzara a dibujar la línea */
x = x0;
y = y0;
/* verificar si la pendiente es mayor de x o y, para luego asignarla a steps */
if (abs(dx) > abs(dy))
steps = abs(dx);
else
steps = abs(dy);
/* se divide por la pendiente mayor, para dar xs o ys igual a 1 (o -1) */Alfredo
Weitzenfeld Gráfica: Línea 3
if (steps == 0) {
XDrawPoint(display,win,gc,round(x),round(y));
fprintf(stderr,”this line is a point”);
return;
}
xs = dx/steps;
ys = dy/steps;
/* se cicla uno a la vez hasta llegar al numero de steps máximo */
for (i = 0; i <= steps; i++)
{
XDrawPoint(display,win,gc,round(x),round(y)); /* round(x) -> x+0.5 */
x = x + xs;
y = y + ys;
}
}
El problema con este algoritmo es que se debe redondear números flotantes a
enteros y hacer operaciones sobre números flotantes, lo cual toma tiempo.
Para líneas largas, la acumulación de errores de redondeo en adiciones
sucesivas del incremento de punto flotante puede provocar que las posiciones
del pixel calculadas se desvíen de la trayectoria real de la línea.
Se puede mejorar el desempeño del algoritmo al separar los incrementos m y
1/m en partes enteras y fraccionarias, de forma que todos los cálculos se
reduzcan a operaciones de enteros. [1]
2 INSTALACIÓN DE TAO FRAMEWORK
Se copea el archivo Freeglut.dll de la carpeta lib del Tao Framework y se pega
en C:\Windows\system.
Posteriormente se ejecuta una aplicación en consola con el lenguaje C# de
Visual Studio.Net y se agregan las referencia de las librería Tao.FreeGlut y
Tao.OpenGl, como ultimo paso importamos las librerias a nuestro aplicación,
como se muestra a continuacion:
using Tao.FreeGlut;
using Tao.OpenGl;
A continuación se muestra el código fuente de la aplicación trazando una línea
Ejercicio 1
Línea
Código:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tao.FreeGlut;
using Tao.OpenGl;
namespace ConsoleApplication1
{
class Program
{
static double x1, y1, x2, y2;
static void Main(string[] args)
{
Console.WriteLine("introduzca el valor de X1");
x1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("introduzca el valor de Y1");
y1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("introduzca el valor de X2");
x2 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("introduzca el valor de Y2");
y2 = Convert.ToDouble(Console.ReadLine());
Glut.glutInit();//funciones propias de opengl
Glut.glutInitDisplayMode(Glut.GLUT_SINGLE |
Glut.GLUT_RGB);
Glut.glutInitWindowSize(640, 480);//creamos una ventana
Glut.glutCreateWindow("**************Algoritmo
DDA**************");//colocamos titulo a la ventana
//llamamos a la funcion dda
Glut.glutDisplayFunc(dda);
Glut.glutMainLoop();
}
public static void dda()
{
//componentes necesarios de opengl
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);//limpia el buffer de
la pantall
Gl.glColor3f(0.6F, 0.6F, 0.6F);//poner color a los pixeles
Gl.glLoadIdentity();//''muy importante;
Gl.glPointSize(2.0f);//medida de los puntos
Gl.glBegin(Gl.GL_POINTS);//funcion para dibujar puntos
//dibujando el plano
float z = -1, w = 1, c = 0;
for (int i = 0; i < 200; i++)
{
Gl.glColor3f(w, c, z);
Gl.glVertex2d(z, 0);
Gl.glVertex2d(0, w);
z += .01f;
w -= .01f;
c += .1f;
}
Gl.glEnd();//termina funcion para dibujar puntos
///pasamos las
Gl.glPointSize(5.0f);//sirve para el tamaño de los pixeles
Gl.glColor3f(0.6f, 1.0f, 0.6f);//sirve para el color de
los pixeles
ddaDibujar(x1, y1, x2, y2);
}
public static void ddaDibujar(double x1, double y1, double x2,
double y2)
{
double xinicial = x1, yinicial = y1, xfinal = x2, yfinal =
y2, x, y;
double deltax, deltay, xincremento, yincremento;
double pasos;
deltax = xfinal - xinicial;
deltay = yfinal - yinicial;
if (Math.Abs(deltax) > Math.Abs(deltay))
pasos = Math.Abs(deltax);
else
pasos = Math.Abs(deltay);
xincremento = (deltax / pasos) / 10;
yincremento = (deltay / pasos) / 10;
x = xinicial;
y = yinicial;
Gl.glBegin(Gl.GL_POINTS);
Gl.glVertex2d(x, y);//funcion que pinta un pixel en las
coordenadas especificadas
for (double k = .1; k <= pasos; k += .1)
{
x = (x + xincremento);
y = (y + yincremento);
Gl.glVertex2d(x, y);
}
Gl.glEnd();
//termina dda
}
}
}
La aplicación debera quedar de la siguiente manera:
Figura 1. Pantalla para introducir coordenadas iniciales y finales para la línea.
Figura 2. Línea dibujada en las coordenas respectivas.
Figura 3. Xinicial= -0.5, Yinicial=-0.7, Xfinal=.5, Yfinal=.7.
Figura 4. Xinicial= 0.3, Yinicial=0.3, Xfinal=1, Yfinal=1.
EJERCICIO 1
LINEA PUNTEADA: Realizar una aplicación que dibuje una línea punteada con
ayuda del algoritmo DDA en Visual Studio.net con el lenguaje C#.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tao.FreeGlut;
using Tao.OpenGl;
namespace ConsoleApplication1
{
class Program
{
static double x1, y1, x2, y2;
static void Main(string[] args)
{
Console.WriteLine("introduzca el valor de X1");
x1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("introduzca el valor de Y1");
y1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("introduzca el valor de X2");
x2 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("introduzca el valor de Y2");
y2 = Convert.ToDouble(Console.ReadLine());
Glut.glutInit();//funciones propias de opengl
Glut.glutInitDisplayMode(Glut.GLUT_SINGLE |
Glut.GLUT_RGB);
Glut.glutInitWindowSize(640, 480);//creamos una ventana
Glut.glutCreateWindow("**************Algoritmo
DDA**************");//colocamos titulo a la ventana
//llamamos a la funcion dda
Glut.glutDisplayFunc(dda);
Glut.glutMainLoop();
}
public static void dda()
{
//componentes necesarios de opengl
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);//limpia el buffer de
la pantall
Gl.glColor3f(0.6F, 0.6F, 0.6F);//poner color a los pixeles
Gl.glLoadIdentity();//''muy importante;
Gl.glPointSize(2.0f);//medida de los puntos
Gl.glBegin(Gl.GL_POINTS);//funcion para dibujar puntos
//dibujando el plano
float z = -1, w = 1, c = 0;
for (int i = 0; i < 200; i++)
{
Gl.glColor3f(w, c, z);
Gl.glVertex2d(z, 0);
Gl.glVertex2d(0, w);
z += .01f;
w -= .01f;
c += .1f;
}
Gl.glEnd();//termina funcion para dibujar puntos
///pasamos las
Gl.glPointSize(5.0f);//sirve para el tamaño de los pixeles
Gl.glColor3f(0.6f, 1.0f, 0.6f);//sirve para el color de
los pixeles
ddaDibujar(x1, y1, x2, y2);
}
public static void ddaDibujar(double x1, double y1, double x2,
double y2)
{
double xinicial = x1, yinicial = y1, xfinal = x2, yfinal =
y2, x, y;
double deltax, deltay, xincremento, yincremento;
double pasos;
deltax = xfinal - xinicial;
deltay = yfinal - yinicial;
if (Math.Abs(deltax) > Math.Abs(deltay))
pasos = Math.Abs(deltax);
else
pasos = Math.Abs(deltay);
xincremento = (deltax / pasos) / 5;
yincremento = (deltay / pasos) / 5;
x = xinicial;
y = yinicial;
Gl.glBegin(Gl.GL_POINTS);
Gl.glVertex2d(x, y);//funcion que pinta un pixel en las
coordenadas especificadas
for (double k = .1; k <= pasos; k += .1)
{
x = (x + xincremento);
y = (y + yincremento);
Gl.glVertex2d(x, y);
}
Gl.glEnd();
//termina dda
}
}
}
EJERCICIO 2
Realizar una aplicación que dibuje una línea mas gruesa que la anterior con
ayuda del algoritmo DDA en Visual Studio.net con el lenguaje C#.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tao.FreeGlut;
using Tao.OpenGl;
namespace ConsoleApplication1
{
class Program
{
static double x1, y1, x2, y2;
static void Main(string[] args)
{
Console.WriteLine("introduzca el valor de X1 INICIAL");
x1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("introduzca el valor de Y1 INICIAL");
y1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("introduzca el valor de X2 INICIAL");
x2 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("introduzca el valor de Y2 INICIAL");
y2 = Convert.ToDouble(Console.ReadLine());
Glut.glutInit();//funciones propias de opengl
Glut.glutInitDisplayMode(Glut.GLUT_SINGLE
Glut.GLUT_RGB);
Glut.glutInitWindowSize(1200, 780);//creamos una ventana
Glut.glutCreateWindow("**************Algoritmo DDA con
grosor mas grande **************");//colocamos titulo a la ventana
//llamamos a la funcion dda
Glut.glutDisplayFunc(dda);
Glut.glutMainLoop();
}
public static void dda()
{
//componentes necesarios de opengl
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);//limpia el buffer de
la pantall
Gl.glColor3f(0.3F, 0.3F, 0.3F);//poner color a los pixeles
Gl.glLoadIdentity();//''muy importante;
Gl.glPointSize(5.0f);//medida de los puntos
Gl.glBegin(Gl.GL_POINTS);//funcion para dibujar puntos
//dibujando el plano
float z = -1, w = 1, c = 1;
for (int i = 0; i < 200; i++)
{
Gl.glColor3f(w, c, z);
Gl.glVertex2d(z, 0);
Gl.glVertex2d(0, w);
z += .01f;
w -= .01f;
c += .1f;
}
Gl.glEnd();//termina funcion para dibujar puntos
///pasamos las
Gl.glPointSize(5.0f);//sirve para el tamaño de los
pixeles
Gl.glColor3f(0.6f, 1.0f, 0.6f);//sirve para el color
de los pixeles
ddaDibujar(x1, y1, x2, y2);
}
public static void ddaDibujar(double x1, double y1, double x2,
double y2)
{
double xinicial = x1, yinicial = y1, xfinal = x2, yfinal =
y2, x, y;
double deltax, deltay, xincremento, yincremento;
double pasos;
deltax = xfinal - xinicial;
deltay = yfinal - yinicial;
if (Math.Abs(deltax) > Math.Abs(deltay))
pasos = Math.Abs(deltax);
else
pasos = Math.Abs(deltay);
xincremento = (deltax / pasos) /10;
yincremento = (deltay / pasos) / 10;
x = xinicial;
y = yinicial;
Gl.glBegin(Gl.GL_POINTS);
Gl.glVertex2d(x, y);//funcion que pinta un pixel en las
coordenadas especificadas
for (double k = .1; k <= pasos; k += .1)
{
x = (x + xincremento);
y = (y + yincremento);
Gl.glVertex2d(x, y);
}
//Gl.glEnd();
//termina dda
// ******************************************************
double p2;
double p3;
double p4;
double p5;
p2 = xinicial + .01;
p4 = yinicial + .01;
p5 = yfinal + .01;
p3 = xfinal +.01;
deltax = (p3 - p2);
deltay = (p5 - p4);
if (Math.Abs(deltax) > Math.Abs(deltay))
pasos = Math.Abs(deltax);
else
pasos = Math.Abs(deltay);
xincremento = (deltax / pasos) /10;
yincremento = (deltay / pasos) / 10;
x = p2+.1;
y = p4;
Gl.glBegin(Gl.GL_POINTS);
Gl.glVertex2d(x, y);//funcion que pinta un pixel en las
coordenadas especificadas
for (double k = .1; k <= pasos; k += .1)
{
x = (x + xincremento);
y = (y + yincremento);
Gl.glVertex2d(x, y);
}
p2 = xinicial + .01;
p4 = yinicial + .01;
p5 = yfinal + .01;
p3 = xfinal + .01;
deltax = (p3 - p2);
deltay = (p5 - p4);
if (Math.Abs(deltax) > Math.Abs(deltay))
pasos = Math.Abs(deltax);
else
pasos = Math.Abs(deltay);
xincremento = (deltax / pasos) / 10;
yincremento = (deltay / pasos) / 10;
x = p2 ;
y = p4 + .1;
Gl.glBegin(Gl.GL_POINTS);
Gl.glVertex2d(x, y);//funcion que pinta un pixel en las
coordenadas especificadas
for (double k = .1; k <= pasos; k += .1)
{
x = (x + xincremento);
y = (y + yincremento);
Gl.glVertex2d(x, y);
}
Gl.glEnd();
//termina dda
}
}
}
El programa compilado y ejecutado debera quedar de la siguiente manera:
Figura 7. Interfaz para introducir las coordenadas correspondientes.
Figura 8. Xinicial= 0.5, Yinicial=0.5, Xfinal=1, Yfinal=1.
Figura 9. Xinicial= 0.5, Yinicial=0.5, Xfinal=1, Yfinal=1.
Figura 10. Xinicial= - 0.9, Yinicial=- 0.8, Xfinal=8, Yfinal=9
FUENTES DE INFORMACIÓN
1.- Graficación, Departamento Académico de Computación Instituto
Tecnológico Autónomo de México
http://cannes.itam.mx/Alfredo/Espaniol/Cursos/Grafica/Linea.pdf
2.- OpenGL: CSGL y The Tao Framework en Csharp. Autor: Ing. Jesús Hernández León. Docente del Instituto Tecnológico Superior de Libres. Revisado en: http://opengl.blogspot.es
Sitios de trabajo en línea 1. Issuu. Sitio para la publicación de trabajos en línea. Vínculo: http://issuu.com/ 2.- Hotmail. Sitio para enviar vinculo electrónicamente: http://www.hotmail.com/