ine 5341

Programa

OpenGL

Trabalhos 2001

Trabalhos 2002

Links

Bibliografia

Plano de Ensino

Capítulo 4: Sistema de Coordenadas Normalizado e suas Alternativas, Navegação Estendida com a Window e Clipping (Recorte

4.1. Introdução

4.2. Sistemas de Coordenadas Intermediários e Navegação Extendida em 2D.

4.3. Clipping

4.4. Código-Exemplo de Clipping



4.1. Introdução


Figura 4.1. Relacionamento entre Window e Viewport visto até agora.
 
 


Figura 4.2. Resultado esperado na geração da visualização de um objeto geométrico complexo 
 


Figura 4.3. Duas visões de uma cena. Em (a) a Window encontra-se distante e em (b) próxima.


Figura 4.4. Navegação com a Window através de rotação e resultado na Viewport.



4.4. Código-Exemplo de Clipping

/*  Algoritmo de Cohen-Sutherland adaptado para "C" */ 
/*  Fonte: Foley & van Dam
    Versão em português: 
       Instituto de Ciências Matemáticas e de Computação - USP */

typedef  enum {LEFT= Q, RIGHT = 1 , BOTTOM = 2, TOP = 3} aresta; 
typedef  enum {TRUE = 1 ,FALSE = 0} boolean; 
typedef  boolean outcode; 
float xmax, ymax, xmin, ymin; /* variaveis globais */

boolean Vazio(outcode codigo[])
/* retorna TRUE se todos os outcodes em codigo sao FALSE, 
   e FALSE caso contrario */ 

   /* ... procedimento auxiliar */ 

boolean InterseccaoVazia(outcode codigo0[], outcode codigo1 []) 
/* retorna TRUE se a interseccao logica entre codigo1 e codigo 2 e vazia, e FALSE c.c. */

   /* ... procedimento auxiliar */

boolean igual(outcode codigo0[], outcode codigo1[]) 
/* retorna TRUE se codigo0 e codigo 1 sao iguais, e FALSE c.c. */ 

   /* ... procedimento auxiliar */

void CalculaOutCode(float x,float y,outcode codigo[]) 
/* calcula outcode para ponto (x,y) */ 

int i; 
for (i - LEFT; i < = TOP; i + + ) codigo[i] = FALSE; 
    if y > ymax) codigo[TOP] = TRUE; 
    else if (y < ymin) codigo[BOTTOM] = TRUE; 
       else; 
    if (x > xmax) codigo[RIGHT] = TRUE; 
    else if (x < xmax) codigo[BOTTOM] = TRUE; 
       else; 

void RecorteLinhaCohenSutherland(float x0,float y0,float x1,float y1,int valor) 
/* algoritmo de recorte de Cohen-Sutherland para linha P0(x0,y0) a P1(x1,y1), e retangulo de recorte com diagonal de (xmin,ymin) a (xmax,ymax). */ 
{
boolean aceito, pronto; 
outcode outcode0[4], outcode1 [4], *outcode0ut; 
/* outcodes para P0, P1 e quaisquer outros pontos que estao fora do retangulo de recorte */
float x, y; 

aceito = FALSE; 
pronto = FALSE; 
CalculaOutCode(x0,y0,outcode0); 
CalcuiaOutCode(xl ,y1 ,outcode1); 
do
    if (vazio(outcode0) && vazio(outcode1))
    { /* aceitacao trivial e sai */ 
      aceito = TRUE; pronto = TRUE; 
    } 
    elseif (interseccao_vazia(outcode0,outcode1)) 
          /* rejeicao trivial e sai */
            pronto = TRUE; 
      else
            { 
          /* ambos os testes falharam, entao calcula o segmento de reta a recortar: 
            a partir de um ponto externo a uma interseccao com a aresta de recorte */
          /* pelo menos um ponto esta fora do retangulo de recorte; seleciona-o */
            outcode0ut= vazio(outcode0) ? outcode1 : outcode0; 
          / * acha agora o ponto de interseccao, usando as formulas: 
            y = y0 + inclinacao * (x-x0), x = x0 + ( 1 /inclinacao) * (y-y0) */
          if (outcodeOut(TOP)) 
                { / * divide a linha no topo do retangulo de recorte */
                x= x0 + (x1-x0) * (ymax-y0)/(y1-y0); y= ymax;
                } 
            else if (outcode0ut[BOTTOM]) 
                    { /* divide a linha na base do retangulo de recorte */
                    x = x0 + (x1-x0) + (ymin-y0)/(y1-y0); y = ymin; 
                    } 
                    else if (outcode0ut[RIGHT]) 
                        { /* divide na aresta direita do retangulo de recorte */
                        y = y0 + (y1 -y0) + (xmax-x0)/(x1-x01; x = xmax; 
                        } 
                        else if (outcode0ut[LEFT]) 
                            { /* divide  na aresta esquerda do retangulo de recorte */
                            y = y0 + (y 1 -y0) + (xmin-x0)/(x1-x0); 
                            x = xmin; 
                            } 
                            else; 
          /* agora move o ponto externo para o ponto de interseccao, 
               para recortar e preparar para o proximo passo */
          if (igual(outcode0ut,outcode0)) 
            { 
             x0 = x; 
             y0 = y; 
             CalculaOutCode(x0,y0,outcode0); 
            } 
            else { 
             x1 = x; 
             y1 = y; 
             CalculaOutCode(x1,y1,outcode1); 
            } 
        } /* fim do else da subdivisao * /
    } while (pronto);
if (aceito) 
    /* AGORA me deixam calcular a intersecção.... */
    MeioPontoLinhaReal(x0,y0,x1,y1),valor); 

/* OBS: versao do algoritmo para coordenadas reais */

} /* fim do algoritmo de recorte e tracado */



/* Algoritmo de Sutherland-Hodgman para recorte do polígonos */
/*  Fonte: Foley & van Dam
    Versão em português: 
        Instituto de Ciências Matemáticas e de Computação - USP */

#define MAX 20 

typedef struct {float x,y;} ponto; 
typedef ponto vertice; 
typedef vertice aresta[2]; 
typedef vertice VetorVertices[MAX]; 
typedef enum {TRUE = 1, FALSE = 0} boolean; 

void saida(vertice novoVertice, int *tamSaida, VetorVertices vetorSaida) 
/* acrescenta um novo vertice a vetorSaida, e atualiza tamSaida */ 

   /* ... procedimento auxiliar */ 
}

boolean dentro(vertice testeVertice, aresta arestaRecorte) 
/* checa se o vertice esta dentro ou fora da aresta de recorte */ 

   /* ... procedimento auxiliar */ 
}

vertice intercepta(vertice prim, vertice seg, aresta arestaRecorte) 
/* recorta a aresta (prim,seg) do poligono contra arestaRecorte, retorna o novo ponto */

    /* ... procedimento auxiliar */ 

void RecortePoligonosSutherlandHodgman( 
     VetorVertices vetorEntrada, /* vetor de vertices de entrada */ 
     VetorVertices vetorSaida,   /* vetor de vertices de saida */ 
     int tamEntrada,            /* numero de entradas em vetorEntrada */
     int tamSaida,              /* numero de vertices em vetorSaida */ 
     aresta arestaRecorte)

   vertice s, p; /* pontos inicial e final da aresta de recorte corrente */ 
   vertice i; /* ponto de interseccao com uma aresta de recorte */ 
   int j; /* contador para o loop de vertices */ 

   *tamSaida = 0; 
   s = vetorEntrada[tamEntrada]; / * comeca com o ultimo vertice em vetorEntrada */ 

   for (j = 1 ;j < = tamEntrada;j + + ) 
      { 
       p= vetorEntrada[j]; /* agora s e p correspondem aos vertices na Fig. */ 
      if (dentro(s,arestaRecorte)) 
          { /* casos 1 e 4 */ 
          if (dentro(s,arestaRecorte)) saida(p,tamSaida,vetorSaida); 
          else
              i = intercepta(s,p,arestaRecorte); 
              saida(i,tamSaida,vetorSaida); 
              saida(p,tamSaida,vetorSaida); 
              } 
           } 
       else
           { /* casos 2 e 3 */ 
           if (dentro(s,arestaRecorte)) 
              { 
               i = intercepta(s,p,arestaRecorte); 
               saida(i,tamSaida,vetorSaida); 
              } 
           } 
        s = p; 
      } /* fim do for */ 
} /* fim do algoritmo de recorte */ 



Pseudocódigo para Algoritmo de Weiler-Atherton, versão de James C. Miller, Bradley University.

const int MAXVERT = 500;
const int MAXPOLYV = 50;
const int MAXH = 10;

struct Point2D
{float x,y;
};
typedef Point2D Vertices[MAXVERT];

enum VerType = {Polygon, Intersection};

typedef struct ClipListRec * ClipPtr;
struct ClipListRec
{ int Vindex;
  ClipPtr next;
  VerType Kind;
  float t;
  ClipPtr otherList;
}

struct Polygon
{ int nVertex;
  int vert[MAXPOLYV];
  ClipPtr list;
}
struct GenPolygon
{ Polygon exterior;
  int numHoles;
  Polygon Holes[MAXH];
}

GenPolygon Sub,Clip;
int entering[MAXVERT],exiting[MAXVERT];
Vertices V;
int numVertex = 0;    // size of the array of verticies
int clipPoly[MAXVERT];  // a clip polygon

int readPoint();
{ cin >> inX;  cin >> inY;
  if (numVertex < MAXVERT)
  {  V[numVertex].x = inX;
     V[numVertex].y = inY;
      idNo = numVertex;
     numVertex++;
  }
  else
     idNo = -1;
  return idNo;
}

void readPolygon (GenPolygon p)
{ cin >> p.exterior.nVertex;
  for (i = 0; i < p.exterior.nVertex; i++)
  { newId = readPoint();
    if (newId < 0)
      error
    else
    { insertAtRear (p.exterior.list,newId);
      p.exterior.vert[i] = newId;
    }
  }
  // now do the holes basically the same way
. . . 
}
// the "main" program loop would then be (pseudocode)
while (!EMPTY(entering))
{ nextInter = delete (entering);
  SEARCH (SubjectPolygon,nextInter,ptr1);
  AddToOutputList (ptr1->. . .)
  StartPoint = ptr1->. . .
  ptr1 = prt1->next;
  while (ptr1->. . . != StartPoint)
  { AddToOutputList (ptr1->. . .);
    if (ptr1-> . .   ==  INTERSECTION)
      ptr1 = prt1->otherList->next;
    else
       ptr1 = ptr1->next;
  }
  FixListForOutput();
  DrawPolygon();
  EmptyOutputList();
}



Links Interessantes:

Apostila em Português (incompleta)

Poly clipping

Polygon clipping

Parametric line clipping

Code for various poly and line clipping methods among other things

Frustrum clipping doc with source code

On-Line Geometric Modeling Notes - Clipping - uses rigorous linear algebra
 
 
 
The Cyclops Project
German-Brazilian Cooperation Programme on IT
CNPq GMD DLR