Aggiornamento della struttura Il cuore dell'algoritmo e' la routine che, assegnato un segmento da
disegnare, ne disegna le sole parti visibili e al contempo aggiorna
la lista di span disponibili. Per vederne il funzionamento consideriamo
di voler disegnare il segmento (xa,xb) e guardiamo quali casi si possono
presentare per una free span (x0,x1):
Tipi di interazione fra span
In questa figura sono raccolti tutti i possibili tipi di interazione
fra un segmento da disegnare (xa,xb) e una span disponibile (x0,x1).
|
| | | Caso 1: x1 <= xa In questo caso possiamo semplicemente ignorare la span disponibile
e passare a considerare la prossima span della scanline.
| | | | Caso 2: x0<xa; xa<x1<=xb In questo caso l'area da disegnare e' (xa,x1) e la span deve essere
modificata ponendo xa come limite superiore.
| | | | Caso 3: x0<xa; x1>xb Questo e' il caso peggiore e richiede il disegno del segmento
completo (xa,xb), la modifica del limite superiore della span a xa
e la creazione di una nuova span (xb,x1). Una volta effettuate queste
operazioni e' pero' possibile considerare conclusa l'elaborazione
per questa scanline.
| | | | Caso 4: x0>=xa; x1<=xb In questo caso il segmento da disegnare e' (x0,x1) e la span
puo' essere rimossa dalla lista di questa scanline. L'elaborazione
deve pero' continuare per eventuali altre span presenti.
| | | | Caso 5: xa<x0<xb; x1>xb In questo caso il segmento da disegnare e' (x0,xb) e il limite
inferiore della span deve essere modificato in xb. Fatto questo
l'elaborazione della scanline e' completata.
| | | | Caso 6: x0>=xb Questo caso non richiede nessuna elaborazione e indica che non e'
necessario proseguire l'analisi di altre span di questa scanline.
|
La funzione seguente effettua il disegno di un segmento e l'aggiornamento
della lista di span della scanline. Si tratta della traduzione in
linguaggio C della casistica elencata precedentemente.
void DrawSegment(int y,int xa,int xb)
{
Span *old,*current,*n;
for (old=NULL,current=FirstSpan[y];
current!=NULL;
old=current,current=current->next)
{
if (current->x1<=xa) // Caso 1
continue;
if (current->x0<xa)
{
if (current->x1<=xb) // Caso 2
{
DrawPart(y,xa,current->x1);
current->x1=xa;
}
else // Caso 3
{
DrawPart(y,xa,xb);
n=NewSpan();
n->next=current->next;
current->next=n;
n->x1=current->x1;
current->x1=xa; n->x0=xb;
return;
}
}
else
{
if (current->x0>=xb) // Caso 6
return;
if (current->x1<=xb) // Caso 4
{
DrawPart(y,current->x0,current->x1);
n=current->next; FreeSpan(current);
if (old) old->next=n;
else FirstSpan[y]=n;
current=n;
if (current==NULL) return;
}
else // Caso 5
{
DrawPart(y,current->x0,xb);
current->x0=xb;
}
}
}
}
|
|
|