lunes, 26 de marzo de 2012

Representación de objetos en 3 dimensiones y visualización de objetos

Matrices
Las matemáticas que hay tras estas transformaciones se simplifican gracias a las matrices. Cada una de las transformaciones de las que se acaba de hablar puede conseguirse multiplicando una matriz que contenga los vértices por una matriz que describa la transformación.

Ejemplos de matrices en OpenGL:
void glMatrixMode( enum mode ); Permite seleccionar la matriz sobre la cual se realizaran las operaciones, los posibles valores de mode son TEXTURE, MODELVIEW, COLOR o PROJECTION . Por ahora las más interesantes son MODELVIEW y PROJECTION, las otras se verán en su momento.

Void glLoadMatrix{fd} (T m[16]); Recibe una matriz de 4×4 que reemplaza la actual seleccionada. El arreglo es ordenado en forma de una matriz que tiene orden Y, a diferencia de las matrices convencionales que tienen orden X, lo que quiere decir que tiene la forma

void glMultMatrix{fd}( T m[16] ); Multiplica la matriz actual por la matriz m[16] y reemplaza la matriz actual con el resultado de la operación. La operación resultante sería algo así como A’ = A M , donde A es la matriz actual, M es la matriz suministrada y A’ es la nueva matriz que resulta de la operación y que reemplaza a A.

void glLoadTransposeMatrix{fd}( T m[16] ); Realiza una función similar a LoadMatrix(), con la diferencia que trabaja sobre una matriz en orden X así: que es evidentemente la transpuesta de la m que recibe LoadMatrix.

void glPushMatrix( void ); Coloca una copia de la matriz actual en la parte superior de la pila correspondiente.

void glPopMatrix( void ); Saca el elemento superior de la pila, que pasa a reemplazar a la matriz actual.
void glGetFloatv(enum value, float *data); Permite obtener una copia de aquello que se indica en value. Por ejemplo si se pasan como parámetros MODELVIEW_MATRIX y un apuntador a un arreglo de flotantes tamaño 16 se obtiene una copia de dicha matriz a través del arreglo.

Proyección
Como ya se ha visto en tutoriales anteriores, OpenGL maneja 2 tipos de proyección, en perspectiva y ortográfica, donde la primera corresponde a la visión “realista” de la escena, mientras que la segunda es una “plana” que no deforma las dimensiones de los objetos dependiendo de su distancia a la cámara.

Ortográfica: Para ajustar la proyección ortográfica se utiliza el siguiente grupo de funciones:

glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);

Esta función permite controlar los parámetros del volumen de vista izquierdo, derecho, abajo, arriba, cerca y lejos. Hay que recordar que debido a que no se posee percepción de profundidad en este modo el valor del volumen deberá corresponder en la mayoría de los casos a un volumen suficientemente grande para contener los objetos de la escena.

gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);

Esta función es simplemente una forma de la anterior, en donde se ha despreciado el valor de Z asignando los valores near = -1 y far = 1, generalmente se utiliza para escenas planas, en las que los objetos carecen de profundidad.

Perspectiva: Existen dos manera de manejar la proyección en perspectiva, a través de de una función gl o mediante la librería glu (una tercera puede ser realizar los cálculos de la matriz “manualmente”.

Transformaciones ModelView
Una tarea muy común en la creación de gráficos 2d, 3d y videojuegos es la de mover objetos par crear cierta animación. La primera idea que se nos viene a la cabeza en el caso de OpeGL es que todo modelo está formado por primitivas, toda primitiva por puntos y finalmente todo punto por una tripleta de coordenadas XYZ, así que si se cambian las coordenadas todo de ahí hacia arriba se mueve.

Coordenadas oculares
Las coordenadas oculares se sitúan en el punto de vista del observador, sin importar las transformaciones que tengan lugar. Por tanto, estas coordenadas representan un sistema virtual de coordenadas fijo usado como marco de referencia común.

Transformaciones
Las transformaciones son las que hacen posible la proyección de coordenadas 3D sobre superficies 2D. También son las encargadas de mover, rotar y escalar objetos. En realidad, estas transformaciones no se aplican a los modelos en sí, si no al sistema de coordenadas, de forma que si se quiere rotar un objeto, no lo se le rota, sino que se rota el eje sobre el que se sitúa.

El modelador
En esta sección se recogen las transformaciones del observador y del modelado puesto que, como se verá en el apartado 4.2.1.3, constituyen, al fin y al cabo, la misma transformación.

Transformaciones del observador

La transformación del observador es la primera que se aplica a la escena, y se usa para determinar el punto más ventajoso de la escena. Por defecto, el punto de vista está en el origen (0,0,0) mirando en dirección negativa del eje z. La transformación del observador permite colocar y apuntar la cámara donde y hacia donde se quiera. Todas las transformaciones posteriores tienen lugar basadas en el nuevo sistema de coordenadas modificado.


Transformaciones del modelo
Estas transformaciones se usan para situar, rotar y escalar los objetos de la escena. La apariencia final de los objetos depende en gran medida del orden con el que se hayan aplicado las transformaciones.

Transformaciones de la proyección
 La transformación de proyección se aplica a la orientación final del modelador. Esta proyección define el volumen de visualización y establece los planos de trabajo.

Transformaciones de la vista
 En el momento en que se ha terminado todo el proceso de transformaciones, solo queda un último paso: proyectar lo que hemos dibujado en 3D al 2D de la pantalla, en la ventana en la que estamos trabajando. 

Matrices

 Las matemáticas que hay tras estas transformaciones se simplifican gracias a las matrices. Cada una de las transformaciones de las que se acaba de hablar puede conseguirse multiplicando una matriz que contenga los vértices por una matriz que describa la transformación. Por tanto todas las transformaciones ejecutables con ogl pueden describirse como la multiplicación de dos o más matrices.

El canal de transformaciones

 Para poder llevar a cabo todas las transformaciones de las que se acaba de hablar, deben modificarse dos matrices: la matriz del Modelador y la matriz de Proyección. OpenGL proporciona muchas funciones de alto nivel que hacen muy sencillo la construcción de matrices para transformaciones. Éstas se aplican sobre la matriz que este activa en ese instante. Para activar una de las dos matrices utilizamos la función glMatrixMode.

La matriz del modelador

La matriz del modelador es una matriz 4x4 que representa el sistema de coordenadas transformado que se está usando para colocar y orientar los objetos. Si se multiplica la matriz del vértice (de tamaño 1x4) por ésta se obtiene otra matriz 1x4 con los vértices transformados sobre ese sistema de coordenadas.

jueves, 22 de marzo de 2012

Unidad III, ejecución de códigos y código de cubo y esfera modificado

Cubo

Curvas

 lab01

Laberinto XLS

EdifH

CODIGO DE CUBO Y ESFERA MODIFICADO
#include

GLfloat anguloCuboX = 0.0f;
GLfloat anguloCuboY = 0.0f;
GLfloat anguloEsfera = 0.0f;

GLint ancho=400;

GLint alto=400;

int hazPerspectiva = 0;

void reshape(int width, int height)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
   
    if(hazPerspectiva)
     gluPerspective(60.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f);
    else

      glOrtho(-4,4, -4, 4, 1, 10);

    glMatrixMode(GL_MODELVIEW);

    ancho = width;
    alto = height;
}

void drawCube(void)
{
    glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_QUADS);       //cara frontal
    glVertex3f(-1.0f, -1.0f,  1.0f);
    glVertex3f( 1.0f, -1.0f,  1.0f);
    glVertex3f( 1.0f,  1.0f,  1.0f);
    glVertex3f(-1.0f,  1.0f,  1.0f);

    glEnd();

    glColor3f(0.0f, 1.0f, 0.0f);

    glBegin(GL_QUADS);       //cara trasera
    glVertex3f( 1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f,  1.0f, -1.0f);
    glVertex3f( 1.0f,  1.0f, -1.0f);

    glEnd();

    glColor3f(0.0f, 0.0f, 1.0f);
    glBegin(GL_QUADS);       //cara lateral izq
    glVertex3f(-1.0f,-1.0f, -1.0f);
    glVertex3f(-1.0f,-1.0f,  1.0f);
    glVertex3f(-1.0f, 1.0f,  1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glEnd();

    glColor3f(1.0f, 1.0f, 0.0f);
    glBegin(GL_QUADS);       //cara lateral dcha
    glVertex3f(1.0f, -1.0f,  1.0f);
    glVertex3f(1.0f, -1.0f, -1.0f);
    glVertex3f(1.0f,  1.0f, -1.0f);
    glVertex3f(1.0f,  1.0f,  1.0f);
    glEnd();

    glColor3f(0.0f,      1.0f, 1.0f);
    glBegin(GL_QUADS);       //cara arriba
    glVertex3f(-1.0f, 1.0f,  1.0f);
    glVertex3f( 1.0f, 1.0f,  1.0f);
    glVertex3f( 1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glEnd();

    glColor3f(1.0f, 0.0f, 1.0f);
    glBegin(GL_QUADS);       //cara abajo
    glVertex3f( 1.0f,-1.0f, -1.0f);
    glVertex3f( 1.0f,-1.0f,  1.0f);
    glVertex3f(-1.0f,-1.0f,  1.0f);
    glVertex3f(-1.0f,-1.0f, -1.0f);
    glEnd();
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    glTranslatef(0.0f, 0.0f, -5.0f);
    glTranslatef(3,0,0);

    glRotatef(anguloCuboX, 1.0f, 0.0f, 0.0f);
    glRotatef(anguloCuboY, 0.0f, 1.0f, 0.0f);
    glScalef(0.5f, 0.5f, 0.5f);
    drawCube();

    glLoadIdentity();

    glTranslatef(0.0f, 0.0f, -5.0f);
  glRotatef(anguloEsfera, 0.0f, 1.0f, 0.0f);
    glTranslatef(0.0f, 2.0f, 0.0f);

    glColor3f(0.0f, 1.0f, 0.5f);
    glutWireSphere(0.5f, 8, 8);

    glFlush();
    glutSwapBuffers();

    anguloCuboX+=0.1f;
    anguloCuboY+=0.1f;
    anguloEsfera+=0.2f;
}

void init()
{
    glClearColor(0,0,0,0);
    glEnable(GL_DEPTH_TEST);
    ancho = 400;
    alto = 400;
}


void idle()
{
    display();
}


void keyboard(unsigned char key, int x, int y)
{
    switch(key)
    {
    case 'p':
    case 'P':
      hazPerspectiva=1;
      reshape(ancho,alto);
      break;

    case 'o':
    case 'O':
      hazPerspectiva=0;
      reshape(ancho,alto);
      break;

    case 27:   // escape
     // exit(0);
      break;
    }
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(ancho, alto);
    glutCreateWindow("Cubo 1");
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0;
}





jueves, 1 de marzo de 2012

Proyección ortogonal y proyección perspectiva

Proyecciones ortográficas
Una proyección ortográfica es cuadrada en todas sus caras. Esto produce una proyección paralela, útil para aplicaciones de tipo CAD o dibujos arquitectónicos, o también para tomar medidas, ya que las dimensiones de lo que representan no se ven alteradas por la proyección.
Una aproximación menos técnica pero mas comprensible de esta proyección es imaginar que se tiene un objeto fabricado con un material deformable, y se aplasta literalmente como una pared. Se obtendría el mismo objeto, pero plano, liso. Pues eso es lo que se vería por pantalla

Proyección perspectiva.
La proyección ortogonal no da sensación de profundidad porque el tamaño de los objetos no depende de su distancia al observador. Para conseguir este efecto necesitamos definir una proyección perspectiva. Esta proyección define un volumen de la vista que es una prisma truncado de base rectangular, como el de la siguiente figura:

1. puede diferenciar entre los dos tipos de proyección?
La ortogonal aun que pareciera que es 3D en realidad solo es 2D  tiene un único ángulo de visión y en perspectiva la profundidad con que se ve la imagen depende del ángulo de visión.
2. entiende para que se usan las matrices y como las maneja opengl? expliquelo.
Se usan para hacer operaciones con vectores y dependiendo que se desee lograr se utiliza una propiedad diferente de las matrices, ya sea rotación, traslación, etc..
3. Que es la matriz identidad y para que se utiliza en opengl?
Cumple con la propiedad de ser el elemento neutro del producto de matrices, podría ser utilizada multiplicándola con un escalar y hacer una escalacion con otra matriz vectores
4.Haga  otro programa con el cubo pero con proyección  en perspectiva
5. explique las diferencias
La diferencia seria que el primer cubo sin rotar se ve como si fuera en 2D por que solo se ve una cara  y en perspectiva, ya nos podríamos dar cuenta de la profundidad del objeto y verlo en 3D


jueves, 23 de febrero de 2012

2. Transformaciones geométricas

Un paquete gráfico permite al usuario especificar que parte de una imagen definida se debe visualizar y dónde esta parte se debe colocar en el dispositivo de visualización. Cualquier sistema de coordenadas que sea conveniente, referido al sistema de referencia de coordenadas del mundo, se puede usar para definir la imagen.

2.1. Transformaciones bidimensionales Traslación
Se aplica una traslación en un objeto para cambiar su posición a lo largo de la trayectoria de una línea recta de una dirección de coordenadas a otra. Convertimos un punto bidimensional al agregar las distancias de traslación, tx y ty a la posición de coordenadas original (x ,y) para mover el punto a una nueva posición (x’, y’).
Los polígonos se trasladan al sumar el vector de traslación a la posición de coordenadas de cada vértice y se vuelve a generar el polígono utilizando un nuevo conjunto de coordenadas y vértices y las especificaciones actuales de los atributos.

Rotación
Se aplica una rotación bidimensional en un objeto al cambiar su posición a lo largo de la trayectoria de una circunferencia en el plano de xy  para generar una rotación, especificamos un ángulo de rotación θ y la posición (xr , yr) del punto de rotación (o punto pivote) en torno al cual se gira el objeto.

2.2. Coordenadas homogéneas y representación matricial
En las aplicaciones de diseño y de creación de imágenes, realizamos traslaciones, rotaciones y  escalaciones para ajustar los componentes de la imagen en sus posiciones apropiadas. En este tema consideramos cómo se pueden volver a formular las representaciones de la matriz de modo que se pueden procesar de manera eficiente esas secuencias de transformación.

2.3. Composición de transformaciones bidimensionales Traslaciones
Se se aplican dos vectores de traslación sucesivos (t x1, ty1) y (t x2 , t y2 ) en la posición de coordenadas P, la localización transformada final P, la localización transformada final P’se calcula como:
donde se representan P y P’ como vectores de columna de coordenadas homogéneas. Podemos verificar este resultado al calcular el producto de la matriz para las dos agrupaciones asociativas. Asimismo, la matriz de transformación compuesta para esta secuencia de transformaciones es:
que demuestra que dos transformaciones sucesivas son aditivas.

Rotaciones
Dos rotaciones sucesivas que se aplican en el punto P producen la posición transformada
Al multiplicar las dos matrices de rotación, podemos verificar que dos rotaciones sucesivas son aditivas:
de modo que es posible calcular las coordenadas giradas finales con la matriz de rotación compuesta como

Escalaciones
Concatenar matrices de transformación para dos operaciones de escalación sucesivas produce la siguiente matriz de escalación compuesta:

La matriz resultante en este caso indica que las operaciones de escalación sucesivas son multiplicativas. Es decir, si debiéramos triplicar el tamaño de un objeto dos veces en una sucesión, el tamaño final sería nueve veces el tamaño original.

Rotación del punto pivote general
Con un paquete gráfico que sólo ofrezca una función de rotación para girar objetos con respecto del origen de las coordenadas, podemos generar casi cualquier punto pivote seleccionado (x r , y r ) al realizar la siguiente secuencia de operaciones de traslación-rotación-traslación:
1. Traslade el objeto de modo que se mueva la posición del punto pivote al origen de  las coordenadas.
2. Gire el objeto con respecto del origen de las coordenadas.
3. Traslade el objeto de manera que se regrese el punto pivote a su posición original.


Escalación del punto fijo general
La siguiente figura ilustra una secuencia de transformación para producir escalación con respecto de una posición fija seleccionada (x f , y f ) al utilizar una función de escalación que sólo puede escalar en relación con el origen de las coordenadas.

1. Traslade el objeto de modo que el punto fijo coincida con el origen de las coordenadas.
2. Escale el objeto con respecto del origen de las coordenadas
3. Utilice la traslación inversa del paso 1 para regresar el objeto a su posición original.

Propiedades de concatenación
La multiplicación de matrices es asociativa. Para tres matrices cualesquiera A, B y C, el producto matricial A·B·C se puede llevar a cabo al multiplicar primero a por B o multiplicar primero B por C:
A·B·C =(A·B)·C =A·(B·C )

2.4.Transformación ventana-área de vista
Algunos paquetes gráficos permiten que el programador especifique coordenadas de primitivas de salida en un sistema de coordenadas de mundo de punto flotante, usando las unidades que sean relevantes para el programa de aplicación: angstroms, micras, metros, millas, años luz, etcétera. Se emplea el término de mundo porque el programa de aplicación representa un mundo que se crea o presenta interactivamente para el usuario:
Como las primitivas de salida se expresan en coordenadas de mundo, hay que indicar al paquete de subrutinas gráficas cómo establecer la correspondencia entre las coordenadas de mundo y las coordenadas de pantalla (usaremos el término específico coordenadas de pantalla para relacionar este análisis específicamente con SRGP, pero podrían usarse dispositivos de impresión, en cuyo caso sería más apropiado el término coordenadas de dispositivo).

2.5.Transformaciones de composición general y de eficiencia computacional
Una transformación bidimensional general, que representa una combinación de traslaciones, rotaciones y escalaciones. Solo necesitamos efectuar cuatro multiplicaciones y cuatro adiciones para transformar las posiciones de las coordenadas. Este es el número máximo de cálculos que se requieren para cualquier secuencia de transformación, una vez que se han concatenado las matrices individuales y evaluadas los elementos de la matriz compuesta. Sin concatenación, se aplicarían las transformaciones individuales una a la vez y se podría reducir en forma considerable el número de cálculos. De esta manera, una implementación eficiente de las operaciones de transformación consiste en formular matrices de transformación, concatenar cualquier secuencia de transformación y calcular las coordenadas transformadas

2.6.Representación matricial de transformaciones tridimensionales
Así como las transformaciones bidimensionales se pueden representar con matrices de3 X 3 usando coordenadas homogéneas, las transformaciones tridimensionales se pueden representar con matrices de 4 X 4, siempre y cuando usemos representaciones de coordenadas homogéneas de los puntos en el espacio tridimensional. Así, en lugar de representar un punto como (x, y, z ), lo hacemos como (x, y, z, W ), donde dos de estos cuádruplos representan el mismo punto si uno es un multiplicador distinto de cero del otro: no se permite el cuádruplo (0, 0, 0, 0). Como sucede en el espacio bidimensional, la representación estándar de un punto (x, y, z, W ) con W ≠ 0 se indica (x/W, y/W, z/W, 1).

2.7.Composición de transformaciones tridimensionales
El objetivo es transformar los segmentos de línea dirigida P1P2 y P1P3 en la figura 2.18 de su posición inicial en la parte (a) a su posición final en la parte (b). De esta manera, el punto P1 se trasladará al origen P 1P2 quedará en el eje positivo y P 1P3 quedará en la mitad del eje positivo del plano (x, y ). Las longitudes de las líneas no se verán afectadas por la transformación. Se presentan dos formas de lograr la transformación deseada. El primer método es componer las transformaciones primitivas T , R x , Ry y Rz . Este método, aunque es algo tedioso, es fácil de ilustrar y su comprensión nos ayudará en nuestro conocimiento de las transformaciones. El segundo método, que utiliza las propiedades de las matrices ortogonales especiales que se analiza en la sección anterior, se explica de manera mas breve pero es más abstracto.

Glosario Unidad 2: Transformaciones

Coordenadas Geométricas:  son un instrumento usado para describir un punto en el espacio proyectivo.  Pueden usarse como un sistema alternativo de coordenadas para trabajar en el espacio euclídeo, pues éste puede verse como un subconjunto del espacio proyectivo. De ese modo, las coordenadas homogéneas son ampliamente usadas en infografía para la representación de escenas en tres dimensiones.

Stack: Es una lista ordinal o estructura de datos en la que el modo de acceso a sus elementos es de tipo LIFO (del inglés Last In First Out, último en entrar, primero en salir) que permite almacenar y recuperar datos. Esta estructura se aplica en multitud de ocasiones en el área de informática debido a su simplicidad y ordenación implícita de la propia estructura.

lunes, 20 de febrero de 2012

2.1 Trazo de líneas rectas y 2.2 Representación y trazo de polígonos

DDA

El analizador diferenciador digital (DDA - Digital Differential Analyzer) es un algoritmo de conversión de rastreo que se basa en el calculo ya sea de Dy o Dx por medio de las ecuaciones:

(4) Dy = m Dx

(5) Dx = Dy / m

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:

(6) 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:

(7) xk+1 = xk+ 1/m

Las ecuaciones (6) y (7) 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, y   yk+1 = yk - m o xk+1 = xk - 1/m



Algoritmo de Bresenham para trazar líneas

Un algoritmo preciso y efectivo para la generación de líneas de rastreo, desarrollado por Bresenham (1965), convierte mediante rastreo las líneas utilizando solo cálculos incrementales con enteros que se pueden adaptar para desplegar también curvas.

El algoritmo busca cual de dos pixeles es el que esta mas cerca según la trayectoria de la línea.

Consideremos el proceso de conversión para líneas con pendiente positiva 0 < m < 1.

Las posiciones de pixel a lo largo de la trayectoria de una línea se determinan al efectuar un muestreo de x en intervalos unitarios.

Si se inicia desde el extremo izquierdo (x0,y0) de una línea determinada, se pasa a cada columna sucesiva y se traza el pixel cuyo valor de y se aproxima mas a la trayectoria de la línea de rastreo.

Si suponemos que se debe desplegar el pixel en (xk,yk), a continuación se necesita decidir que pixel se debe desplegar en la columna xk+1.

Las alternativas son los pixeles (xk+1,yk), y (xk+1,yk+1).

Al realizar el muestreo en la posición xk+1 designamos la separación de pixeles verticales de la trayectoria de la línea matemática como d1 y d2.



La coordenada de y en la línea matemática en la posición de la columna de pixel xk+1 se calcula como:

(10) y = m (xk + 1) + b

Entonces

d1 = y - yk = m (xk + 1) + b yk                  y               d2 = (yk + 1) - y = yk + 1 - m (xk + 1) - b

La diferencia entre estas dos separaciones es

(11) d1 - d2 = 2 m (xk + 1) - 2 yk + 2 b - 1

Un parámetro de decisión pk para el paso k en el algoritmo de línea se puede obtener al reordenar la ecuación anterior, de modo que implique solo cálculos de enteros.

Esto se logra sustituyendo m = Dy / Dx donde Dx y Dy son las separaciones horizontal y vertical de las posiciones de los extremos de la línea y al definir:

(12) pk = Dx (d1 - d2) = Dx (2 Dy / Dx (xk + 1) - 2 yk + 2 b - 1)

= 2 Dy xk - 2 Dx yk + 2 Dy + 2 b Dx - Dx

= 2 Dy xk - 2 Dx yk + c

El signo de pk es el mismo que el de d1 - d2 puesto que Dx > 0 en el ejemplo.

El parámetro c es un constante, donde c = 2 Dy + 2 b Dx - Dx, que es independiente del pixel.

Si el pixel yk esta mas cerca de la trayectoria de la línea que el pixel yk + 1 (es decir d1 < d2), entonces el parámetro de decisión pk es negativo.

En ese caso, trazamos el pixel inferior; de otro mode, trazamos el pixel superior.

Los cambios de coordenadas a lo largo de la línea ocurren en pasos unitarios ya sea en la dirección de x o en la de y.

Por tanto, es posible obtener los valores de parámetros de decisión sucesivos al utilizar cálculos incrementales en enteros. En el paso k + 1, el parámetro de decisión se evalúa con base en la ecuación anterior como:

pk+1 = 2 Dy xk+1 - 2 Dx yk+1 + c

Al sustraer la ecuación (12) de la anterior obtenemos

pk+1 - pk = 2 Dy (xk+1 - xk) - 2 Dx( yk+1 - yk)

Pero xk+1 = xk + 1, de manera que

(13) pk+1 = pk + 2 Dy - 2 Dx( yk+1 - yk)

donde el termino yk+1 - yk es 0 o 1, dependiendo del signo del parámetro p. Este calculo recurso de los parámetros de decisión se realiza en cada posición entera de x, empezando en el extremo izquierdo de las coordenadas de la línea. El primer parámetro p0 se evalúa a partir de la ecuación (12) en la posición del pixel inicial (x0,y0), sustituyendo

con b = y0 - m x0 y m = Dy / Dx.

p0 = Dx (2 Dy / Dx(x0 + 1) - 2 y0 + 2 (y0 - (Dy / Dx) x0) - 1)

= 2 Dy x0 + 2 Dy - 2 Dx y0 + 2 Dx y0 - 2 Dy x0 - Dx

donde se obtiene la siguiente ecuación:

(14) p0 = 2 Dy - Dx

En resumen, los pasos son:

1. Se capturan los dos extremos de la línea y se almacena el extremo izquierdo en (x0,y0).

2. Se carga (x0,y0) en el bufer de estructura, o sea, se traza el primer punto.

3. Se calculan las constantes Dy, Dx, 2Dy, 2Dy-2Dx, y se obtiene el valor inicial para el parámetro de decisión como p0 = 2 Dy - Dx.

4. En cada xk a lo largo de la línea, que inicia en k = 0, se efectúa la prueba siguiente: si pk < 0, el siguiente punto que se debe trazar es (xk+1,yk) y pk +1 = pk + 2 Dy. De otro modo, el siguiente punto en trazarse es (xk+1,yk+1)

y pk +1 = pk + 2 Dy - 2Dx.

5. Se repite el paso 4 otras Dx veces.






















Referencias
http://cannes.itam.mx/Alfredo/Espaniol/Cursos/Grafica/Linea.pdf
http://arantxa.ii.uam.es/~pedro/graficos/teoria/Primitivas/Primitivas.htm