2012-04-08 1 views
8

Моя домашняя работа по компьютерной графике заключается в реализации алгоритмов OpenGL с использованием только способности нарисовать точки.Чертежные линии с линейным алгоритмом Брешенема

Так что, очевидно, мне нужно получить drawLine(), прежде чем я смогу нарисовать что-нибудь еще. drawLine() должен выполняться только с использованием целых чисел. Нет плавающей запятой.

Это то, чему меня учили. В принципе, линии могут быть разбиты на 4 разные категории, положительные крутые, положительные мелкие, отрицательные крутые и отрицательные мелкие. Это изображение я должен рисовать:

expected result

и это картина моей программы рисования:

actual result

Цвет сделал для нас. Нам даны вершины, и нам нужно использовать алгоритм линии Брешенема для рисования линий на основе начальной и конечной точек.

Это то, что я до сих пор:

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; 
         } 
       } 
     } 
} 

Я знаю, что моя ошибка будет что-то глупо, но я честно не могу понять, что я делаю неправильно. Почему некоторые из строк рисуются неправильно, как показано выше?

+0

что не работает? –

+0

Если вы посмотрите на два изображения в параграфе выше моего кода, «2-й квадрант» и «четвертый квадрант» не будут правильно рисовать. Я помещаю их в кавычки, потому что точка (0,0) находится в нижнем левом углу изображения. В основном, первый оператор else содержит код, который работает некорректно, -shallow и -steep. – ToastyMallows

+0

запустите свой код на 2 простых примерах, один из которых работает, а тот, который этого не делает. Скажите (0,0), (5, 5) и (0,5), (5,0), проследите через оба и увидите, они расходятся. Это будет намного лучше, чем делать кого-то, кто сделает это за вас. –

ответ

0

Если кто-то задавался вопросом, в чем проблема, я до сих пор не знаю, что это было. То, что я закончил, было переоценено моим кодом, так что -shallow и -steep использовали тот же алгоритм, что и + мелкий и + крутой, соответственно. После корректировки координат x, y (отрицая координату x или y), когда я пошел на их график, я отрицал свое первоначальное отрицание, чтобы оно отображалось в нужном месте.

+0

Я не знаком с языком C, но, возможно, некоторые из значений fraktional должны быть преобразованы в абсолютные значения? –

5

Вы можете найти полный код в C++, чтобы нарисовать линию с помощью алгоритма Bresenham на 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

Это ответ только для ссылок; отредактируйте свой ответ, чтобы включить фактический код, а не только ссылку. – LittleBobbyTables

+0

Что такое «delay (0)» в bhm_line()? –