2012-04-08 37 views
8

Mi tarea de gráficos por computadora es implementar algoritmos OpenGL utilizando solo la capacidad de dibujar puntos.Dibujando líneas con el algoritmo de línea de Bresenham

Así que obviamente necesito hacer que drawLine() funcione antes de que pueda dibujar algo más. drawLine() tiene que hacerse usando enteros solamente. Sin punto flotante

Esto es lo que me enseñaron. Básicamente, las líneas se pueden dividir en 4 categorías diferentes, empinadas positivas, positivas superficiales, negativas empinadas y negativas superficiales. Esta es la imagen que debo dibujar:

expected result

y esta es la imagen de mi programa está llegando:

actual result

Los colores se hacen por nosotros. Nos dan vértices y necesitamos usar el algoritmo Bresenham's Line para dibujar las líneas basadas en los puntos de inicio y final.

Esto es lo que tengo hasta ahora:

int dx = end.x - start.x; 
int dy = end.y - start.y; 

//initialize varibales 
int d; 
int dL; 
int dU; 

if (dy > 0){ 
     if (dy > dx){ 
       //+steep 
       d = dy - 2*dx; 
       dL = -2*dx; 
       dU = 2*dy - 2*dx; 

       for (int x = start.x, y = start.y; y <= end.y; y++){ 
         Vertex v(x,y); 
         drawPoint(v); 

         if (d >= 1){ 
           d += dL; 
         }else{ 
           x++; 
           d += dU; 
         } 
       }    
     } else { 
       //+shallow 
       d = 2*dy - dx; 
       dL = 2*dy; 
       dU = 2*dy - 2*dx; 

       for (int x = start.x, y = start.y; x <= end.x; x++) { 
         Vertex v(x,y); 
         drawPoint(v); 

         // if choosing L, next y will stay the same, we only need 
         // to update d by dL 
         if (d <= 0) { 
           d += dL; 
         // otherwise choose U, y moves up 1 
         } else { 
           y++; 
           d += dU; 
         } 
       } 
     } 
} else { 
     if (-dy > dx){ 
       cout << "-steep\n"; 
       //-steep 
       d = dy - 2*dx; 
       //south 
       dL = 2*dx; 
       //southeast 
       dU = 2*dy - 2*dx; 

       for (int x = start.x, y = start.y; y >= end.y; --y){ 
         Vertex v(x,y); 
         drawPoint(v); 

         //if choosing L, next x will stay the same, we only need 
         //to update d 
         if (d >= 1){ 
           d -= dL; 
         } else { 
           x++; 
           d -= dU; 
         } 
       } 

     } else { 
       cout << "-shallow\n"; 
       //-shallow 
       d = 2*dy - dx; 
       dL = 2*dy; 
       dU = 2*dy - 2*dx; 

       for (int x = start.x, y = start.y; x <= end.x; x++){ 
         Vertex v(x,y); 
         drawPoint(v); 

         if (d >= 0){ 
           d += dL; 
         } else { 
           --y; 
           d -= dU; 
         } 
       } 
     } 
} 

Sé que mi error va a ser algo tonto, pero sinceramente no puedo averiguar lo que estoy haciendo mal. ¿Por qué algunas de las líneas se dibujan incorrectamente como se muestra arriba?

+0

lo que no funciona? –

+0

Si miras las dos imágenes en el párrafo arriba de mi código, el "2 ° cuadrante" y el "4 ° cuadrante" no están dibujando bien. Los pongo entre comillas porque el punto (0,0) está en la esquina inferior izquierda de la imagen. Básicamente, la primera declaración else contiene el código que no está funcionando correctamente, -shallow y -steep. – ToastyMallows

+0

ejecuta tu código en 2 ejemplos simples, uno que funciona y el que no funciona. Di (0,0), (5, 5) y (0,5), (5,0), traza a través de ambos y observa si divergieron. Este será un ejercicio mucho mejor que tener a alguien en SO que lo haga por usted. –

Respuesta

0

Por si alguien se preguntaba cuál era el problema, todavía no sé de qué se trataba. Lo que terminé haciendo fue volver a factorizar mi código para que el -shallow y -steep usaran el mismo algoritmo que + shallow y + steep, respectivamente. Después de ajustar las coordenadas x, y (anulando la coordenada xoy), cuando fui a trazarlas negué mi negación original para que se trazara en el lugar correcto.

+0

No estoy familiarizado con el lenguaje C, pero tal vez algunos de los valores fracionales se tengan que convertir en valores absolutos. –

5

Puede encontrar el código completo en C++ para dibujar una línea usando Bresenham Algoritmo en el http://www.etechplanet.com/codesnippets/computer-graphics-draw-a-line-using-bresenham-algorithm.aspx:

/*BRESENHAAM ALGORITHM FOR LINE DRAWING*/ 
#include<iostream.h> 
#include<graphics.h> 
#include<stdio.h> 
#include<conio.h> 
#include<stdlib.h> 
#include<math.h> 
#include<dos.h> 
void bhm_line(int,int,int,int,int); 
void main() 
{ 
int ghdriver=DETECT,ghmode,errorcode,x1,x2,y1,y2; 
initgraph(&ghdriver,&ghmode,"..\\bgi"); 
errorcode = graphresult(); 
if(errorcode !=grOk) 
{ 
    cout<<"Graphics error:%s\n"<<grapherrormsg(errorcode); 
    cout<<"Press any key to halt:"; 
    getch(); 
    exit(1); 
} 
clrscr(); 
cout<<"Enter the coordinates (x1,y1): "; 
cin>>x1>>y1; 
cout<<"Enter the coordinates (x2,y2): "; 
cin>>x2>>y2; 
bhm_line(x1,y1,x2,y2,1); 
getch(); 
} 
void bhm_line(int x1,int y1,int x2,int y2,int c) 
{ 
int x,y,dx,dy,dx1,dy1,px,py,xe,ye,i; 
dx=x2-x1; 
dy=y2-y1; 
dx1=fabs(dx); 
dy1=fabs(dy); 
px=2*dy1-dx1; 
py=2*dx1-dy1; 
if(dy1<=dx1) 
{ 
    if(dx>=0) 
    { 
    x=x1; 
    y=y1; 
    xe=x2; 
    } 
    else 
    { 
    x=x2; 
    y=y2; 
    xe=x1; 
    } 
    putpixel(x,y,c); 
    for(i=0;x<xe;i++) 
    { 
    x=x+1; 
    if(px<0) 
    { 
    px=px+2*dy1; 
    } 
    else 
    { 
    if((dx<0 && dy<0) || (dx>0 && dy>0)) 
    { 
    y=y+1; 
    } 
    else 
    { 
    y=y-1; 
    } 
    px=px+2*(dy1-dx1); 
    } 
    delay(0); 
    putpixel(x,y,c); 
    } 
} 
else 
{ 
    if(dy>=0) 
    { 
    x=x1; 
    y=y1; 
    ye=y2; 
    } 
    else 
    { 
    x=x2; 
    y=y2; 
    ye=y1; 
    } 
    putpixel(x,y,c); 
    for(i=0;y<ye;i++) 
    { 
    y=y+1; 
    if(py<=0) 
    { 
    py=py+2*dx1; 
    } 
    else 
    { 
    if((dx<0 && dy<0) || (dx>0 && dy>0)) 
    { 
    x=x+1; 
    } 
    else 
    { 
    x=x-1; 
    } 
    py=py+2*(dx1-dy1); 
    } 
    delay(0); 
    putpixel(x,y,c); 
    } 
} 
} 
+3

Esta es una respuesta de solo enlace; por favor edite su respuesta para incluir el código real, y no solo el enlace. – LittleBobbyTables

+0

¿Cuál es el "retraso (0)" en bhm_line()? –

Cuestiones relacionadas