25
Clipping de linhas e polígonos

Clipping de linhas e polígonos. Casos de clipping de linhas

Embed Size (px)

Citation preview

Page 1: Clipping de linhas e polígonos. Casos de clipping de linhas

Clipping de linhas e polígonos

Page 2: Clipping de linhas e polígonos. Casos de clipping de linhas

Casos de clipping de linhas

Page 3: Clipping de linhas e polígonos. Casos de clipping de linhas

Códigos das regiões

typedef struct { unsigned char all; unsigned char left; unsigned char right; unsigned char bottom; unsigned char top;} outcode;

typedef struct { unsigned char all; unsigned char left; unsigned char right; unsigned char bottom; unsigned char top;} outcode;

tbrl

1001 1000 1010

0001 0000 0010

0101 0100 0110

Page 4: Clipping de linhas e polígonos. Casos de clipping de linhas

Cálculo do código de um vértice

outcode CompOutCode(double x, double y, double xmin, double xmax, double ymin, double ymax){ outcode code; code.top = 0, code.bottom = 0, code.right = 0, code.left = 0, code.all = 0; if (y > ymax) { code.top = 1; code.all += 8; } else if(y < ymin) { code.bottom = 1; code.all += 4; } if (x > xmax) { code.right = 1; code.all += 2; } else if(x < xmin) { code.left = 1; code.all += 1; } return code;}

1001 1000 1010

0001 0000 0010

0101 0100 0110

Page 5: Clipping de linhas e polígonos. Casos de clipping de linhas

void CohenSutherlandLineClipAndDraw(double x0, double y0, double x1, double y1, double xmin, double xmax, double ymin, double ymax, int value){ outcode outcode0, outcode1, outcodeOut, CompOutCode(); double x, y; boolean accept = FALSE, done = FALSE;

outcode0 = CompOutCode(x0, y0, xmin, xmax, ymin, ymax); outcode1 = CompOutCode(x1, y1, xmin, xmax, ymin, ymax);

do { if (outcode0.all == 0 && outcode1.all == 0) { accept = TRUE; done = TRUE; /* trivial draw and exit */ } else if((outcode0.all & outcode1.all) != 0) { done = TRUE; /* trivial reject and exit */ } else { if (outcode0.all != 0) outcodeOut = outcode0; else outcodeOut = outcode1;

if (outcodeOut.top) { x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0); y = ymax; } else if(outcodeOut.bottom) { x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0); y = ymin; } else if(outcodeOut.right) { y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0); x = xmax; } else if(outcodeOut.left) { y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0); x = xmin; } if (outcodeOut.all == outcode0.all) { x0 = x; y0 = y; outcode0 = CompOutCode(x0, y0, xmin, xmax, ymin, ymax); } else { x1 = x; y1 = y; outcode1 = CompOutCode(x1, y1, xmin, xmax, ymin, ymax); }

} /* Subdivide */ } while (!done);

if (accept) DrawLineReal(x0, y0, x1, y1, value);}

Algoritmo de Cohen-Sutherland

Page 6: Clipping de linhas e polígonos. Casos de clipping de linhas

Algoritimo de Cyrus-Beck(Liang-Barsky)

PEi

N Ei

P0 P1

N P t PEi Ei 0 N P t PEi Ei 0

N P t PEi Ei 0

P t P P P t 0 1 0( )

N P t PEi Ei 0

tN P P

N P PEi Ei

Ei

0

1 0

Page 7: Clipping de linhas e polígonos. Casos de clipping de linhas

Entrando ou Saindo ?

P0P1

Ei

N Ei

N P P PEEi 1 0 0

P0

P1

Ei

N Ei

N P P PLEi 1 0 0

Page 8: Clipping de linhas e polígonos. Casos de clipping de linhas

Cálculo das interseções

PL

PEPL

PE

PEPE

PL

PL

Page 9: Clipping de linhas e polígonos. Casos de clipping de linhas

Cyrus-Beck - caso geral

{ precalculate Ni and select a PEi for each edge

for( each line segment to be clipped ){ if(P1 = P0) line is degenerate so clip as a point; else{ tE = 0; tL = 1; for( each candidate intersection with a clip edge ){ if( Ni . (P1-P0) !=0 ){ /* edges not parallel to line */ calculate t; use sign of Ni . (P1-P0) to categorize as PE or PL; if( PE )tE = max(tE, t); if( PL )tL = min(tL, t); } else if(Ni . (P0-PEi) > 0) return nil; } if(tE > tL) return nil; else return P(tE) and P(tL) as true clip intersections; } }}

Page 10: Clipping de linhas e polígonos. Casos de clipping de linhas

Liang e Barsky- caso particular -

Ei NEi PEi t

left: x = xmin (-1, 0) (xmin, y)-(x0-xmin)(x1-x0)

right: x = xmax (1, 0) (xmax, y)(x0-xmax)-(x1-x0)

bottom: y = ymin (0,-1) (x, ymin)-(y0-ymin)(y1-y0)

top: y = ymax (0, 1) (x, ymax)(y0-ymax)-(y1-y0)

xmin xmax

ymin

ymax

x

y

Page 11: Clipping de linhas e polígonos. Casos de clipping de linhas

Liang e Barsky- Cálculo da interseção em uma fronteira -

boolean Clipt(double den, double num, double *tE, double *tL){ double t; if (den > 0) /* intersecao PE */ { t = num/den; if (t > *tL) /* tE > tL */ return FALSE; else if (t > *tE) *tE = t; } else if (den < 0) /* intersecao PL */ { t=num/den; if (t < *tE) /* tL < tE */ return FALSE; else if (t < *tL) *tL = t; } else if (num > 0) /* linha esta fora */ return FALSE; } return TRUE;}

Page 12: Clipping de linhas e polígonos. Casos de clipping de linhas

Algoritimo de Liang e Barsky

boolean Clip2D(double *x0, double *y0, double *x1, double *y1, double xmin, double max, double ymin, double ymax){ double dx = *x1 - *x0; double dy = *y1 - *y0; boolean visible = FALSE; if (dx==0)&&(dy==0)&&ClipPoint(*x0,*y0,xmin,xmax,ymin,ymax) visible=TRUE; else { double tE=0.0, tL=1.0;

if (Clipt(dx,xmin-*x0,&tE,&tL) ) if (Clipt(-dx,*x0-max,&tE,&tL) ) if (Clipt(dy,ymin-*y0,&tE,&tL) ) if (Clipt(-dy,*y0-ymax,&tE,&tL) ) { visible=TRUE; if (tL<1.0) { (*x1)=(*x0)+tL*dx; (*y1)=(*y0)+tE*dy; } if (tE>0.0) { (*x0)=(*x0)+tE*dx; (*y0)=(*y0)+tE*dy; } } } return visible;}

Page 13: Clipping de linhas e polígonos. Casos de clipping de linhas

Clipping de polígonos(Hodgman & Suterland)

• Clip contra uma aresta (plano) de cada vez

Page 14: Clipping de linhas e polígonos. Casos de clipping de linhas

Clipping de polígonos(Hodgman & Suterland)

• Para cada aresta (plano) teste um segmento de cada vez

S

P

store Pstore P

S

P

S

SP

store Istore I

I

P

store I, Pstore I, P

I

Page 15: Clipping de linhas e polígonos. Casos de clipping de linhas

Clipping de polígonos(Exemplo 1)

1

23

4

56

A

B

S P Ação

1 2 x

2 3 store A,3

3 4 store 4

4 5 store 5

5 6 store B

6 1 x

Page 16: Clipping de linhas e polígonos. Casos de clipping de linhas

Clipping de polígonos(Exemplo 2)

1

S P Ação1 2 store A2 3 x3 4 store B,44 5 store 55 6 store C6 1 store D,1

32

45

6A B

CDx x x x

1 45

B

CD

A

Page 17: Clipping de linhas e polígonos. Casos de clipping de linhas

Clipping de polígonos(Exemplo 2)

1

S P Ação

1 A store 1, A

A B store BB 4 store E4 5 store F,55 C store CC D store D

45

A B

CDx x x x

E

F

x

x

D 1 x

B, E, F, 5, C, D, 1, AB, E, F, 5, C, D, 1, A

Page 18: Clipping de linhas e polígonos. Casos de clipping de linhas

Clipping de polígonos(Concatenação de planos)

1

AB

45C

1 45

A B

CDx x x x

E

F

x

x

D

1, A, B, E, F, 5, C, D1, A, B, E, F, 5, C, D

12

3 4 5 6

1

32

45

6A B

CDx x x x

1 5

A B

CDx x x x

E

F

x

x

first[0]S[0]P[0]

first[1]S[1]P[1]

Page 19: Clipping de linhas e polígonos. Casos de clipping de linhas

APIs para definição de polígonos

int npoints;double x[MAXPOINTS], y[MAXPOINTS];

FillPoly(npoints, x, y);

int npoints;double x[MAXPOINTS], y[MAXPOINTS];

FillPoly(npoints, x, y);

gwPoint vertex[MAXPOINT]

FillPoly(npoints, vertex)

gwPoint vertex[MAXPOINT]

FillPoly(npoints, vertex)

Begin(FILL); Vertex(30.,20.); Vertex(15.,18.); …End( );

Begin(FILL); Vertex(30.,20.); Vertex(15.,18.); …End( );

Page 20: Clipping de linhas e polígonos. Casos de clipping de linhas

Cálculo de interseção pela distância

xmin xmax

ymin

ymax

x

y

(x0 , y0 )

(x1 , y1 )

x x t x x

y y t y y

0 1 0

0 1 0

( )

( )

d x x

d x x

td

d d

0 0

1 1

0

0 1

max

max

nd1

d0

Page 21: Clipping de linhas e polígonos. Casos de clipping de linhas

Distâncias as bordas das janelas

double Distance( double x, double y, int plane){ switch( plane ) { case 0: return( -x + xmin ); case 1: return( x - xmax ); case 2: return( -y + ymin ); case 3: return( y - ymax ); } return( 0.0 );}

xmin xmax

ymin

ymax

x

y

Page 22: Clipping de linhas e polígonos. Casos de clipping de linhas

Em coordenadas homogêneas

/* ===================== Distance ======================**** This function computes and returns the distance between a** point and a plane. Normal points toward out.*/ double Distance(double x, double y, double z, double w, int plane ){ switch( plane ) { case 0: return( -w - x ); case 1: return( -w + x ); case 2: return( -w - y ); case 3: return( -w + y ); case 4: return( -w - z ); case 5: return( -w + z ); } return( 0.0 );}

Page 23: Clipping de linhas e polígonos. Casos de clipping de linhas

Teste de interseção com uma fronteira

void Intersect(double x, double y, double z, double w, int plane, double d1, double d2){ double t = d1 / (d1 - d2);

double xi = sx[plane] + t * (x - sx[plane]); double yi = sy[plane] + t * (y - sy[plane]); double zi = sz[plane] + t * (z - sz[plane]); double wi = sw[plane] + t * (w - sw[plane]); if( plane == LAST_PLANE ) SaveVertex( xi, yi, zi, wi ); else ClipAtPlane( xi, yi,zi, wi, plane+1 );}

Page 24: Clipping de linhas e polígonos. Casos de clipping de linhas

Clipping de polígonos deSutherland-Hodgman

void ClipAtPlane( double x, double y, double z, double w, int plane )

{ double d = Distance(x, y, z, w, plane); /* Check whether it is the first point */ if( first[plane] ) { fx[plane] = x; fy[plane] = y; fz[plane] = z; fw[plane] = w; fd[plane] = d; first[plane] = 0; } else if ((sd[plane] < 0) ^ (d < 0)) Intersect( x, y, z, w, plane, sd[plane], d );

/* Save as previous */ sx[plane] = x; sz[plane] = z; sy[plane] = y; sw[plane] = w; /* Check whether it is a visible point */ if( d <= 0.0 ) { if( plane == LAST_PLANE ) SaveVertex( x, y, z, w ); else ClipAtPlane( x, y, z, w, plane+1 ); }}

Page 25: Clipping de linhas e polígonos. Casos de clipping de linhas

Ligando com a API

void ClipClose( int plane ){ if ((sd[plane] < 0) ^ (fd[plane] < 0)) Intersect( fx[plane], fy[plane], plane, sd[plane], fd[plane] );

first[plane] = 1; if( plane == LAST_PLANE ) FillSavedPolygon(); else ClipClose( plane+1 );}

void ClipClose( int plane ){ if ((sd[plane] < 0) ^ (fd[plane] < 0)) Intersect( fx[plane], fy[plane], plane, sd[plane], fd[plane] );

first[plane] = 1; if( plane == LAST_PLANE ) FillSavedPolygon(); else ClipClose( plane+1 );}

void Vertex( double x, double y, double z ){ if (clip_on_off) ClipAtPlane( x, y, z, 0 ); else SaveVertex(x,y,z);}

void Vertex( double x, double y, double z ){ if (clip_on_off) ClipAtPlane( x, y, z, 0 ); else SaveVertex(x,y,z);}