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

## Presentation on theme: "Clipping de linhas e polígonos. Casos de clipping de linhas."— Presentation transcript:

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 100110001010 000100000010 010101000110

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; } 100110001010 000100000010 010101000110

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

Algoritimo de Cyrus-Beck (Liang-Barsky)

Entrando ou Saindo ?

Cálculo das interseções PLPL PEPE PLPL PEPE PEPE PEPE PLPL PLPL

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

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

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

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

Clipping de polígonos (Hodgman & Suterland) Clip contra uma aresta (plano) de cada vez

Clipping de polígonos (Hodgman & Suterland) Para cada aresta (plano) teste um segmento de cada vez S P store P S P S SP store I I P store I, P I

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

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

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

Clipping de polígonos (Concatenação de planos) 1 A B 4 5 C 1 4 5 AB C D xxxx E F x x D 1, A, B, E, F, 5, C, D 1 2 3 4 5 6 1 3 2 4 5 6 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]

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( );

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 00 11 0 01 max n d1d1 d0d0

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

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

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

Clipping de polígonos de Sutherland-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 ); }

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

Download ppt "Clipping de linhas e polígonos. Casos de clipping de linhas."

Similar presentations