A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Recorte e seleção de linhas e polígonos. Motivações.

Apresentações semelhantes


Apresentação em tema: "Recorte e seleção de linhas e polígonos. Motivações."— Transcrição da apresentação:

1 Recorte e seleção de linhas e polígonos

2 Motivações

3 Ambiguidade na seleção

4 Classes de Algoritmos Pontos Linhas Polígonos

5 Ponto em retângulo xmxm ymym x y xpxp ypyp 2.tol int pontInRect(int xm, int ym, float xp, float yp, float tol) { return ( (xp>=xm-tol) && (xp =ym-tol) && (yp<=ym+tol) ); }

6 Casos de clipping de linhas (x 1, y 1 ) (x 2, y 2 ) (x 1, y 1 ) (x 2, y 2 ) A B C E D

7 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

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

9 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

10 Algoritimo de Cyrus-Beck (Liang-Barsky)

11

12 Entrando ou Saindo ?

13 Cálculo das interseções PLPL PEPE PLPL PEPE PEPE PEPE PLPL PLPL C B A PEPE PEPE PLPL PLPL

14 Cyrus-Beck - caso geral { Calcule Ni e escolha um PEi para cada aresta if(P1 = = P0) o segmento é degenerado e deve ser recortado como um ponto; else { tE = 0; tL = 1; for( cada aresta ){ if (Ni.(P1-P0)!=0 ){ /* aresta não é paralela ao segmento */ calcule t; use sign of Ni.(P1-P0) para categorizar como PE ou PL; if( PE ) tE = max(tE, t); if( PL ) tL = min(tL, t); } else { /* aresta paralela ao segmento */ if (Ni.(P0-PEi) > 0) /* está fora */ return nil; } if(tE > tL) return nil; else return P(tE) and P(tL) as true clip intersections; }

15 Liang e Barsky - caso particular - Ei N Ei P Ei t left: x = x min (-1, 0)(x min, y) -(x 0 -x min ) (x 1 -x 0 ) right: x = x max (1, 0)(x max, y) (x 0 -x max ) -(x 1 -x 0 ) bottom: y = y min (0,-1)(x, y min ) -(y 0 -y min ) (y 1 -y 0 ) top: y = y max (0, 1)(x, y max ) (y 0 -y max ) -(y 1 -y 0 ) x min x max y min y max x y

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

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

18 Clipping de polígonos (Hodgman - Sutherland) Clip contra uma aresta (plano) de cada vez

19 Clipping de polígonos (Hodgman & Suterland) Para cada aresta (plano) teste um segmento de cada vez Existem quatro casos possiveis para um vértice e seu antessessor S P guarde P S P SP guarde I I S P guarde I, P I internosaindoexternoentrando (a)(b)(c)(d)

20 Cálculo de interseção pela distância x min x max y min y max x y (x 0, y 0 ) (x 1, y 1 ) dxx dxx t d dd max n d1d1 d0d0

21 Clipping de polígonos (Exemplo 1) A B SPAção 12x 23store A,3 34store 4 45store 5 56store B 61x

22 Clipping de polígonos (Exemplo 2) 1 SP Ação 12store A 23x 34store B,4 45store 5 56store C 61store D, AB C D xxxx B C D A

23 Clipping de polígonos (Exemplo 2) 1 SPAção 1Astore A ABstore B B4store E 45store F,5 5Cstore C CDstore D 4 5 AB C D xxxx E F x x D1store 1 B, E, F, 5, C, D, 1, A

24 Clipping de polígonos (Concatenação de planos) 1 A B 4 5 C AB C D xxxx E F x x D 1, A, B, E, F, 5, C, D AB C D xxxx 1 5 AB C D xxxx E F x x first[0] S[0] P[0] first[1] S[1] P[1]

25 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); Point vertex[MAXPOINT] FillPoly(npoints, vertex) Point vertex[MAXPOINT] FillPoly(npoints, vertex) Begin(FILL); Vertex(30.,20.); Vertex(15.,18.); … End( ); Begin(FILL); Vertex(30.,20.); Vertex(15.,18.); … End( );

26 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 ); } x min x max y min y max x y

27 Teste de interseção com uma fronteira void Intersect(double x, double y, 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]); if( plane == LAST_PLANE ) SaveVertex( xi, yi); else ClipAtPlane( xi, yi, plane+1 ); }

28 Clipping de polígonos de Sutherland-Hodgman void ClipAtPlane( double x, double y, int plane ) { double d = Distance(x, y, plane); /* Check whether it is the first point */ if( first[plane] ) { fx[plane] = x; fy[plane] = y; fd[plane] = d; first[plane] = 0; } else if ((sd[plane] < 0) ^ (d < 0)) Intersect( x, y, plane, sd[plane], d ); /* Save as previous */ sx[plane] = x; sy[plane] = y; /* Check whether it is a visible point */ if( d <= 0.0 ) { if( plane == LAST_PLANE ) SaveVertex( x, y); else ClipAtPlane( x, y, plane+1 ); }

29 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) { if (clip_on_off) ClipAtPlane( x, y, 0 ); else SaveVertex(x, y); } void Vertex( double x, double y) { if (clip_on_off) ClipAtPlane( x, y, 0 ); else SaveVertex(x, y); }

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


Carregar ppt "Recorte e seleção de linhas e polígonos. Motivações."

Apresentações semelhantes


Anúncios Google