l' algoritmo di Bresenham

Slides:



Advertisements
Presentazioni simili
Matematica e statistica Versione didascalica: parte 3
Advertisements

Funzioni di due variabili
Sistema di riferimento sulla retta
Ricorsione Procedure e funzioni ricorsive. Definizioni Un oggetto si dice ricorsivo se è definito totalmente o parzialmente in termini di sé stesso La.
MATLAB.
MATLAB. Outline Grafica 2D Esercizi Grafica 3D Esercizi.
OPERAZIONI SULLE SUPERFICI
Geometria descrittiva dinamica
LE CONICHE L’ ellisse.
LE DERIVATE APPROCCIO INTUITIVO.
LE TRASFORMAZIONI GALILEIANE
(una interferenza nel caso di una sola fenditura)
I VETTORI di Federico Barbarossa
PENDENZA DELLA RETTA di Federico Barbarossa Per lo schermo intero, clic su tasto destro e scegli. Per avanzare con la presentazione, frecce. Per chiudere,
DOMANDA ED ELASTICITA’
Grafica Raster La grafica in 2D con coordinate intere viene detta grafica raster. In questa parte tratteremo le operazioni fondamentali per disegnare su.
Qual è l’obiettivo del consumatore?
Informatica 2. Concetti fondamentali di programmazione Programmare vuol dire scrivere un algoritmo in un linguaggio che faccia funzionare un calcolatore.
Differenziale di una funzione
Computer Graphics Marco Tarini Università dellInsubria Facoltà di Scienze MFN di Varese Corso di Laurea in Informatica Anno Accademico 2005/06 Lezione.
Computer Graphics Marco Tarini Lezione 7: rasterizzazione la fabbrica dei frammenti Università dellInsubria Facoltà di Scienze MFN - Varese Corso di Laurea.
Sistemi Multimediali II Marco Tarini Università dellInsubria Facoltà di Scienze MFN di Varese Corso di Laurea in Informatica Anno Accademico 2004/05 Lezione.
Costruzione di Interfacce Lezione 8 Rasterizzazione
ASINTOTI CONCETTO DI ASINTOTO
Le forze conservative g P2 P1 U= energia potenziale
Il moto armonico Altro esempio interessante di moto è quello armonico caratterizzato dal fatto che l’accelerazione è proporzionale all’opposto della posizione:
Sistema di riferimento su una retta
CORSO DI MODELLI DI SISTEMI BIOLOGICI
coordinate utente e di finestra
Grandezze scalari e vettoriali
Physics 2211: Lecture 22, Pg 1 Agenda di oggi Dinamica del centro di massa Momento lineare Esempi.
PIXEL & DPI.
1 Y Modello di regressione semplice Supponiamo che una variabile Y sia funzione lineare di unaltra variabile X, con parametri incogniti 1 e 2 che vogliamo.
Spazi vettoriali astratti Somma e prodotto di n-ple Struttura di R n.
Velocità ed accelerazione
14 giugno 2011 Rasterizzazione Prof. Roberto Pirrone.
“Il piano cartesiano e la retta”
CONVERSAZIONALE Esempio di utilizzo della programmazione guidata
ENERGIA SOLARE.
Figure sul reticolo cartesiano
INTRODUZIONE A MATLAB LEZIONE 4 Sara Poltronieri slide3.4 matlabintro
LE PERIFERICHE TEDESCHI ALESSIO DORJAN MUSABELLIU.
Posizionamento Come posizionare gli elementi HTML nella pagina web e come JavaScript può muoverli cambiando la loro posizione nel tempo.
complementi di matematica
PIANO CARTESIANO.
La Funzione Sinusoidale
DERIVATA DI UNA FUNZIONE
SPAZI TOPOLOGICI: topologia locale (a cui siamo interessati)
Vettori Finche’ il moto si svolge in una sola dimensione – moto unidimensionale, moto rettilineo – non abbiamo bisogno di vettori La posizione e’ individuata.
Programmazione grafica 1
DERIVATA DI UNA FUNZIONE
Corso di Programmazione Grafica e Laboratorio Daniele Marini
Vettori dello spazio bidimensionale (R 2)
Assonometria isometrica di un parallelepipedo
Frontespizio Economia Politica Anno accademico
Prof Riccardi Agostino - ITC "Da Vinci"
TECNOLOGIE INFORMATICHE NELLA DIDATTICA
Vettori A B VETTORE è un segmento orientato caratterizzato da: C D
Tag FRAMESET. I frame sono un particolare tipo di struttura HTML, che consente di suddividere la finestra del browser in diversi riquadri distinti. Un'insieme.
Grafica Vettoriale e Grafica BitMap o Raster Matjaž Hmeljak.
La traslazione.
INTRODUZIONE ALLA GEOMETRIA
Rasterizzazione Antonio Cisternino
Istruzioni per l’uso GRAFICI CARTESIANI di Federico Barbarossa Per lo schermo intero, “clic” su tasto destro e scegli. Per avanzare con la presentazione,
Avviare la presentazione col tasto “Invio”
APPUNTI DI GEOMETRIA ANALITICA DELLA RETTA
Le funzioni matematiche e il piano cartesiano
Esercizio-Tre blocchi di massa rispettivamente m 1 =5Kg, m 2 =2 Kg e m 3 =3Kg poggiano su un piano orizzontale e sono uniti da due funi (vedi figura).
Test di Fisica Soluzioni.
Video Grafica Immagini. Modalità Video Risoluzione –Numero di pixel visualizzati sul monitor; per esempio 800 x 600, 1024 x 768, 1280 x 1024 Profondità.
Transcript della presentazione:

l' algoritmo di Bresenham

l' algoritmo di Bresenham GRAFICA INCREMENTALE come si disegna un segmento di retta su un reticolo di pixel senza prodotto ne' divisione: l' algoritmo di Bresenham risale al 1961, pubblicato nel 1965

Introduzione alla Grafica Digitale - tracciare un segmento schermo a raggi catodici, disegno di tipo vettoriale (vedi Tektronix, history ...) una linea era tracciata sullo schermo comandando direttamente la posizione del pennello luminoso da una posizione iniziale (x1,y1) ad una posizione finale (x2,y2), il segmento P1--P2 e' un vettore (spazio 2D) ovvero una coppia di punti orientata ovvero un punto + una direzione ed una lunghezza: 3 P2(x1,y1) P1(x1,y1)

Introduzione alla Grafica Digitale - tracciare un segmento per il plotter o tracciatore meccanico si pone il problema di come tracciare una linea con una penna comandata da due motori incrementali passo passo (uno per il tamburo porta carta l'altro per il carrello porta penna) i motori sono essenzialmente digitali, capaci di far avanzare la penna di un passo (fisso) nel senso delle x o nel senso delle y, o in entrambi (diagonale esatta) carrello porta penna tamburo porta carrello 4

problema su un plotter o tracciatore meccanico (i plotter sono ancora in uso ... anni 61 .. 08) di come tracciare una linea con una penna (varie tecnologie, dalla biro, ai pennini in china, al pennello, all;ink-jet, alla carta termica ecc) comandata da due motori incrementali (digitali!) che fanno muovere la penna di un passo fisso nel senso delle x, delle y, o entrambi (diagonale esatta); sulla pagina seguente un "home made plotter" (un plotter e il suo driver sono stati fatti da due studenti del corso di Calcolatori elettronici 2 (Architettura di ..) per hobby e poi presentati come tesina per l'esame; 5

come si vede dalla foto, era fatto con il gioco "FisherTechnik" 6 come si vede dalla foto, era fatto con il gioco "FisherTechnik"

Introduzione alla Grafica Digitale - tracciare un segmento il problema di come tracciare una linea con una penna che puo' avanzare di un passo (fisso) nel senso delle x o nel senso delle y, o in entrambi (diagonale esatta) si ripropone comunque sugli schermi a reticolo dagli stessi anni 60 in poi, (primi schermi grafici 1960) schermi grafici a reticolo a basso costo (300 x 200 circa (*) (Apple2,1977,1300$ con 4kbyte), schermi a tubo vettoriali a immagine persistente a fosfori verdi (Tektronix anni 70-80), "super" schermi di oggi (2007) (3840x2400) -------------------------------- (*) 280x192 a 4 colori 7

Introduzione alla Grafica Digitale - tracciare un segmento (*) (da Wikipedia) (*) IBM 1401 calcolatore commerciale usato spesso come controller per plotter,

Introduzione alla Grafica Digitale - tracciare un segmento Una linea disegnata con un plotter oppure su uno schermo a reticolo (sul monitor posso disegnare un "punto" di dimensione fissa = pixel ) diventa una linea spezzata: richiesta la linea blu orizzontale dx diagonale dx,dy verticale dy 9 con il plotter devo disegnare una linea approssimante, perche' la penna puo' avanzare solo di un passo fisso: nel senso delle x (orizzontale) o nel senso delle y (verticale) o in entrambi i sensi - diagonale esatta

Introduzione alla Grafica Digitale - tracciare un segmento Una linea su uno schermo a reticolo (posso disegnare un "punto" di dimensione fissa = pixel ) diventa una successione di pixel come in figura (linea spezzata) : 10 coordinate schermo: x e y sono interi

Introduzione alla Grafica Digitale - tracciare un segmento segmento da un punto P1(x1,y1) - a un punto P2(x2,y2) nota: punto dato in coordinate schermo, con due interi x1,y1 ** x valore da xmin (in genere zero) a xmax (larghezza dello schermo in pixel), ** y da ymin a ymax (y=0 bordo in basso / in alto dello schermo) non posso tracciare il segmento geometrico astratto, devo tracciare una sequenza di pixel con posizioni x1,y1, ... x2,y2, dove si incrementa x ad ogni passo se l' inclinazione del segmento e' minore o uguale a 450 , oppure incremento y se il segmento ha inclinazione maggiore di 45 0 11

Introduzione alla Grafica Digitale - tracciare un segmento segmento da un punto P1(x1,y1) - a un punto P2(x2,y2) punto dato in coordinate schermo, con due interi x1,y1 ** x va da xmin a xmax (da zero a larghezza schermo in pixel), ** y da ymin a ymax (da 0 a altezza dello schermo) devo tracciare una sequenza di pixel con posizioni x1,y1, xa,ya, xb,yb, ... x2,y2, dove se l' inclinazione del segmento e' minore o uguale a 450 e quindi vi sono piu' xk diversi che yk diversi, e si procede incrementando x ad ogni passo oppure se il segmento ha inclinazione maggiore di 45 0 e allora vi saranno piu' y distinte che x distinte, e si procede incrementando y ad ogni passo 12

Introduzione alla Grafica Digitale - tracciare un segmento quindi: y = m * x + b per disegnare un segmento da P1 a P2 devo controllare l'inclinazione m : se m<=1, procedo a passi fissi (un pixel) lungo le x - la y viene incrementata di un passo dy minore di un pixel, e quindi arrotondata (fig. a destra sopra) --------------------------------------------------------------- per una retta con m>1 vado a passo fisso lungo le y, e la x sara' arrotondata, come nella figura a destra sotto, m<=1 y x x= k k+2 k+4 k+1 k+3 k+7 y m>1 13 k+5 k+4 k+3 k+2 k+1 x y=k

(*) nota: ad ogni passo c'e' da fare un prodotto e una somma Introduzione alla Grafica Digitale - tracciare un segmento // versione semplice 1, // con aritmetica float float a,b,x,y; ..dx=xend-xstart; dy=yend-ystart;.. if( fabs(dx) >= fabs(dy) ){ m = dy / dx; // m<=1 // dove y= m*x+b; dy= m*dx b= ystart - m * xstart; x= xstart; // si parte da qui do{ y = m*x+b; // (*) nota putpix( (int)x, (int)y ); x=x+1; // sempre unitario! } while( x<= xend ); } else ... pagina seguente (*) nota: ad ogni passo c'e' da fare un prodotto e una somma y x 14 k k+2 k+4 k+7 k+1 k+3

Introduzione alla Grafica Digitale - tracciare un segmento //vers.semplice 1, aritm.float float a,b,x,y; ..dx=xend-xstart; dy=yend-ystart; ... else { // fabs(dy) > fabs(dx) mre = dx/dy; // mre < 1 // dove x= mre*y+b; dy= m*dx b= xstart - mre * ystart; y= ystart; // si parte da qui do{ x = mre * y + b; putpix( (int)x, (int)y ); y=y+1; //sempre unitario! } while( y<= yend ); } // if ( fabs(dx).. y k+5 k+4 k+3 k+2 k+1 k x 15

Introduzione alla Grafica Digitale - tracciare un segmento //versione semplice 2, aritmetica float float x=xstart, y=ystart, ddx,ddy,fsteps; dx=xend-xstart; dy=yend-ystart; if( fabs(dx) > fabs(dy) ){ // m<1 steps=fabs(dx); fsteps=(float)steps; ddx= dx/fsteps; ddy= dy/fsteps; putpix(round(x),round(y)); for(k=0; k<steps;k++) { x=x+ddx; y=y+ddy; } // } else ... nota: ad ogni passo c'e' da fare una somma, ma.. y 16 x k k+2 k+4 k+7 k+1 k+3

//vers. semplice 2, in float, parte else ... Introduzione alla Grafica Digitale - tracciare un segmento //vers. semplice 2, in float, parte else ... float x=xstart, y=ystart, ddx,ddy,fsteps; dx=xend-xstart; dy=yend-ystart; ... } else { // ( fabs(dx) < fabs(dy) ), m>1 steps=fabs(dy); // dx,dy interi fsteps=(float)steps; ddx= dx/fsteps; ddy= dy/fsteps; putpix (round(x),round(y)); for(k=0; k<steps;k++) { x=x+ddx; y=y+ddy; } // } // if(fabs(dx)>fabs(dy)..else y k+5 k+4 k+3 k+2 k+1 x k 17

float x=xstart, y=ystart, ddx, ddy, fsteps; tracciare un segmento versione semplice 2, aritmetica float ... float x=xstart, y=ystart, ddx, ddy, fsteps; dx=xend-xstart; dy=yend-ystart; if( fabs(dx) > fabs(dy) ){ // m<1(m=dy/dx) steps=fabs(dx); fsteps=(float)steps; ddx= dx/fsteps; ddy= dy/fsteps; putpix(round(x),round(y)); for(k=0; k<steps;k++) { x=x+ddx; y=y+ddy; } // for } else { // fabs(dx)<fabs(dy), m>1 steps=fabs(dy); fsteps=(float)steps; ddx= dx/fsteps; ddy= dy/fsteps; putpix (round(x),round(y)); } // for } // if ..else y x ad ogni passo c'e' da fare solo una somma, ma ... problema: accumulo err float in x=x+ddx; e y=y+ddy; con segmento lungo non arrivo a xend, yend inoltre (1962!) l' aritmetica float richiede piu' tempo ... 18

tracciare un segmento: algoritmo di Bresenham algoritmo di Bresenham per tracciare un segmento con solo uso di aritmetica intera (Bresenham, J.E., "Algorithm for Computer Control of a Digital plotter", IBM Systems Journal, 4(1), pp.25-30, 1965) esso si basa su un criterio di scelta del pixel da tracciare che usa solo interi: consideriamo il caso con m<1, cioe' xstart<xend (ottante direzione ENE, come in figura a destra) per il segmento in figura, al passo k+1 dobbiamo decidere se tracciare il pixel (x+1,y) oppure (x+1,y+1) y 19 y+1 y x k k+1 k+2 k+3 k+4

per xk+1 : y = m*xk+1 + b = m * (xk+1) +b ... y non e' int ! tracciare un segmento: algoritmo di Bresenham tracciato il pixel al passo k, dobbiamo decidere dove mettere il pixel al passo k+1; e a tal fine si ricorda l' equazione della retta che passa per P1 e P2: y=m*x+b, con yst=m*xst+b, e yend=m*xend+b; per xk : yk = m*xk + b, e, ricordando che xk+1 = xk + 1 per xk+1 : y = m*xk+1 + b = m * (xk+1) +b ... y non e' int ! al passo k+1 si decide tra il pixel (x k+1 ,yk ) e (x k+1 ,yk+1 ) a seconda se y(xk+1) e' piu' vicino a yk+1 oppure a yk : dupp=yk+1-y =(yk+1)-m*(xk+1)-b dlow = y - yk = m * (xk+1)+b - yk dlo -dup =2*m*(xk+1)+2b-yk-yk-1 dupper y P2 y k+1 20 y y k x P1 X k X k+1 dlower

dupper y x dlower dlo -dup=2*m*(xk+1)+2b-yk-yk-1 tracciare un segmento: algoritmo di Bresenham linea P1(xst,yst)-P2(xend,yend); per xk e' yk = m*xk +b, per xk+1 ho: y = m*xk+1+b = m*(xk+1)+b; devo decidere tra (x k+1 ,yk ) e (x k+1 ,yk+1 ) , cioe' (y non e'intero!) tra yk+1 e yk dupp=yk+1-y =(yk+1) - m*(xk+1) - b dlow = y - yk = m * (xk+1)+b - yk dlo -dup=2*m*(xk+1)+2b-yk-yk-1 come criterio di decisione si usa pk = dx* ( dlo -dup ) con dx=xend-xstart e m = dy/dx nota che pk e' un intero, e nota il segno di dlo -dup : se dlo<dup allora pk e' negativo, e si sceglie il pixel sotto, se dlo>dup allora pk e' positivo, e si sceglie il pixel sopra ! dupper y P2 y k+1 21 y y k x P1 X k X k+1 dlower

tracciare un segmento: algoritmo di Bresenham Bresenham: il calcolo di pk da pk-1 si puo' fare senza prodotti e solo con int !!! yst=m*xst+b; yend=m*xend+b; per xk e' yk = m*xk +b, per xk+1 e' yk+1 =m*xk+1 +b = m*(xk+1)+b ; dupp = yk+1-y = (yk+1) - m*(xk+1)-b ; dlow = y - yk = m *(xk+1)+b - yk; dlow -dupp = 2*m*(xk+1)+2b-yk- yk-1; il criterio di decisione pk per scegliere yk+1 o yk+1 e' dato dal pk-1 : pk = dx* ( dlow -dupp ), dove se dx=xend-xstart e m = dy/dx : pk= dx*(2*m*(xk+1)+2b-yk- yk-1) pk= 2*dy*(xk+1) -2*dx*yk +c (c = 2*dy+dx*(2*b-1) sara' eliminato nel calcolo di pk+1 da pk ) pk+1=2*dy*(xk+1+1) -2*dx*yk+1 +c pk+1-pk=2*dy*(xk+1-xk)-2*dx*(yk+1-yk) dupper y P2 y k+1 y y k x P1 X k X k+1 22 pk+1 = pk + 2*dy*(xk+1-xk) -2*dx*(yk+1 -yk ) dove xk+1-xk e' 1 e dove z = yk+1-yk e' 0 se pk < 0, altrimenti z = 1: pk+1 = pk + 2*dy - 2*dx*z ; e con il valore iniziale p0 = 2*dy - dx; dlower da cui l'algoritmo di B.->

il prossimo pixel e' (xk+1 ,yk ) e il prossimo p = p+2*dy, tracciare un segmento: algoritmo di Bresenham ricordiamo: pk+1 = pk + 2*dy -2*dx * z, dove se pk e'negativo, allora z = 0 altrimenti 1, e p0 = 2*dy - dx; ==>> da cui algoritmo (versione 1) dati (x1,y1) e (x2,y2), con x1<x2; poni x=x1,y=y1; traccia pixel (x,y); calcola dx=(x2-x1); dy=(y2-y1); p=2*dy - dx; (val. iniz. del parametro di decisione) ripeti dx-1 volte { se p<0 allora (z=0, e ) il prossimo pixel e' (xk+1 ,yk ) e il prossimo p = p+2*dy, altrimenti (z=1, e ) il pixel e' (x k+1 ,yk+1 ) e il prossimo p = p+2*dy-2*dx; incrementa x di 1 } ripeti dupper y P2 y k+1 23 y y k x P1 X k X k+1 dlower

void BresenhamX(int x1, int y1, int x2, int y2) { tracciare un segmento: algoritmo di Bresenham da cui infine: void BresenhamX(int x1, int y1, int x2, int y2) { int x=x1, y=y1; // only octant ENE, m<=1, dx>dy int dx = x2 - x1, dy = y2 - y1; int Two_dy = 2*dy, TwoDyMinusDx=2*(dy-dx); int error = Two_dy - dx; // prima era pk putpix(x,y); // *** starting point while (x<x2) { x++; // here only octant ENE, m<=1; if (error < 0) error = error + Two_dy; else { // error > 0, go up one y: y = y + 1; error = error + TwoDyMinusDx; } // if error putpix(x,y); // *** on new x,y } // while x } // Bresenham 24 nota: nel ciclo solo un test e due somme di interi

o, in forma leggermente diversa: struct tPunto{ int x; int y; }; ... tracciare un segmento: algoritmo di Bresenham o, in forma leggermente diversa: struct tPunto{ int x; int y; }; ... void bresenham( tPuntoI a, tPuntoI b){ // deve essere a.x < b.x e 0 < H/W < 1, // quadrante x>0,y>0, m<1 int y = a.y, W = b.x-a.x, H = b.y-a.y; //dx,dy int E = 2*H-W; // criterio errore for(int x=a.x; x<=b.x; x++) { // ciclo pixel setPixel(x,y); // ad ogni passo x++, per y: if(E<0) E += 2*H; // per il prossimo pixel else { y++; // si sale di un pixel E += 2*( H-W); } // if } // for x } // bresenham

Introduzione alla Grafica Digitale - tracciare un segmento la versione completa dell'algoritmo di Bresenham per tracciare una linea e' un po' piu' lunga, perche' deve considerare i vari casi che possono presentarsi: ** caso di linea molto inclinata (m>1, ovvero dy>dx) ** caso di punto di inizio "invertito" rispetto il punto di fine, ovvero: (m<1) xend<xstart, oppure (m>1) yend<ystart il caso m>1 si risolve scambiando le x con le y, il caso m<1, xstart>xend si risolve scambiando il punto di inizio con il punto di fine; riportiamo la versione completa, dall'esercizio OGL...Bresenham 26

void LineBres(int xstart,int ystart,int xend,int yend) { int i,tmp,x,y,dx,dy,Signdx,Signdy,Two_dx,Two_dy,Swap,error; if(abs(xstart-xend)<2) { // vertical: y=ystart; if (ystart < yend) dy=1; else dy=-1; do { setPixel(xstart,y); y=y+dy; } while( abs(yend-y)>1); return; } // if verticale if(xstart>xend){scamb(&xstart,&xend);scamb(&ystart,&yend);} x=xstart; y=ystart; dx=xend-xstart; dy=yend-ystart; Signdx = isign(dx); Signdy = isign(dy); dx = abs(dx); dy = abs(dy); if (dy>dx) { tmp=dx;dx=dy; dy=tmp; Swap=1; } else Swap = 0; Two_dx = 2*dx; Two_dy = 2*dy; error = Two_dy - dx; for (i=1; i<=dx; i++) { setPixel(x,y); if (error > 0) { if( Swap ) x = x + Signdx; else y = y + Signdy; error = error - Two_dx; } if ( Swap ) y = y + Signdy; else x = x + Signdx; error = error + Two_dy; } // for setPixel(x,y); } // LineBres

traccia un segmento di linea retta algoritmo di Bresenham, programma EGD_2A_D

Introduzione alla Grafica Digitale - tracciare un segmento Le librerie core (GL) lib, GLU (GL Utility lib), GLUT (GL utility Toolkit lib) hanno definiti vari oggetti, tra cui le curve di Bezier (core), le superfici quadriche (GLU), vari solidi (cono,cubo,sfera, ottaedro, icosaedro, toro, la tea-pot, ma non hanno il cerchio e l'ellisse, (che si ottengono come casi particolari dagli oggetti sopramenzionati); cerchio e ellisse si possono/devono tracciare con algoritmi discreti DDA; non riportiamo lo sviluppo, (bibliogr) ; si veda ad es. il OGL6B (algor.di Bresenham per cerchio) 29

nel caso del cerchio, si calcola un ottavo del cerchio, e poi si tracciano le altre sette parti per simmetria: // il primo punto : setP(xc+dx, yc+dy); // 1 // a gli altri: // 1) cambia segno setP(xc-dx, yc+dy); // 3 setP(xc+dx, yc-dy); // 4 setP(xc-dx, yc-dy); // 2 // 2) per simmetria: setP(xc+dy, yc+dx); // 8 setP(xc-dy, yc+dx); // 5 setP(xc+dy, yc-dx); // 6 setP(xc-dy, yc-dx); // 7 3 1 5 8 7 6 4 2

Bresenham per il cerchio vedi pagina seguente: Bibliografia: Hearn,D., Baker,M.P., "Computer Graphics with OpenGL", Pearson Prentice-Hall, 2004, 3.rd ed., par.3-5, pp.92-109 Bresenham,J.E., "Algorithm for Computer Control of a Digital Plotter", IBM Systems Journal, 4(1), pp.25-30, 1965 Bresenham,J.E., "A Linear Algorithm for Incrementing Digital Display of Circular Arcs", Communication of the ACM, 20(2), pp.1 1977 3 1 5 8 7 6 4 2

void DDACircle (int xc,int yc, int radius) { // vedi bibliografia per la // derivazione del procedimento int dx,dy; // circle point int p = 1-radius; dx=0; dy=radius; // point at alfa=90degr, on top of circle set8Pixel( xc,yc, dx, dy ); while( dx<dy ) { dx++; if(p<0) p= p+ 2*dx +1; else { dy--; p= p+ 2*( dx-dy ) +1;} set8Pixel( xc,yc, dx, dy ); // pag seg. } // while dx } // DDACircle

void set8Pixel(int xc,int yc, int dx,int dy, double r, double g, double b ) /* replicate 8 times symmetrically in the 8 octants */ { setPixel(xc+dx, yc+dy, r,g,b ); setPixel(xc-dx, yc+dy, r,g,b ); setPixel(xc+dx, yc-dy, r,g,b ); setPixel(xc-dx, yc-dy, r,g,b ); setPixel(xc+dy, yc+dx, r,g,b ); setPixel(xc-dy, yc+dx, r,g,b ); setPixel(xc+dy, yc-dx, r,g,b ); setPixel(xc-dy, yc-dx, r,g,b ); } /* set8Pixel */

cerchio disegnato con l'algoritmo di Bresenham (programma EGD_22_CIRCLE)

I programmi dimostrativi degli algoritmi di Bresenham riportati nel secondo capitolo EGD_07_2D_2_3 usano "pixel" grandi, ovvero rettangoli di una matrice di rettangoli: /* the simulated 1 bit raster memory */ int RasterMem[RASTERxSIZE][RASTERySIZE]; ... void plotpix(int x,int y, td r, td g, td b ) { RasterMem[x][y] = 1; glColor3f(r,g,b ); glRecti( PixelSizeX * x , PixelSizeY * y , PixelSizeX * (x+1), PixelSizeY * (y+1) ); } /* plotpix */ void Simple(int x1,int y1,int x2,int y2){ float a,b,x,y,dx,dy;..dy=y2-y1; dx=x2-x1; a=dy/dx; b=y1-a*x1; /*y=a*x+b;->b=y-a*x;*/ x=x1; do{ y = a*x+b; plotpix( (int)x, (int)y, 1.0,1.0,1.0); x=x+1; } while( x<= x2 ); ...

Oggi l'algoritmo di Bresenham e' realizzato a livello hardware, nell'unita' di processo grafica, e viene ricordato per il suo valore storico (si pensi che al tempo (1961) i calcolatori spesso non avevano un'unita' aritmetica completa, ma sapevano solo sommare due interi positivi - il prodotto era quindi realizzato a software, con una procedura ad hoc, e l'evitare il prodotto velocizzava l'algoritmo di molto .