Clipp2D.cpp
上传用户:lhwx1029
上传日期:2013-03-07
资源大小:1173k
文件大小:11k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /** 3DGPL *************************************************
  2.  * ()                                                     *
  3.  * 2D line and polygon clipping.                          *
  4.  *                                                        *
  5.  * Defines:                                               *
  6.  *  C_init_clipping          Setting bounds;              *
  7.  *  C_get_bounds             Clipping window;             *
  8.  *  C_set_bounds             Impose another condition;    *
  9.  *                                                        *
  10.  *  C_line_x_clipping        Clipping a line horizontally;*
  11.  *  C_line_y_clipping        Clipping a line vertically;  *
  12.  *                                                        *
  13.  *  C_polygon_x_clipping     Horizontal polygon cliping.  *
  14.  *                                                        *
  15.  * (c) 1995-98 Sergei Savchenko, (savs@cs.mcgill.ca)      *
  16. **********************************************************/
  17. #include "RayTracing.h"           /* hardware specific stuff */
  18. #include "Clipper.h"             /* 2D macros */
  19. int C_2D_clipping;                          /* type of performed clipping */
  20. int C_x_clipping_min=C_X_CLIPPING_MIN;      /* clipping bounds */
  21. int C_x_clipping_max=C_X_CLIPPING_MAX;      /* default values */
  22. int C_y_clipping_min=C_Y_CLIPPING_MIN;
  23. int C_y_clipping_max=C_Y_CLIPPING_MAX;
  24. /**********************************************************
  25.  * Setting bounds for 2D clipping.                        *
  26.  *                                                        *
  27.  * SETS: C_x_clipping_min,...,C_y_clipping_max            *
  28.  * -----                                                  *
  29. **********************************************************/
  30. void C_init_clipping(int minx,int miny,int maxx,int maxy)
  31. {
  32.  C_x_clipping_min=minx;                     /* no error checking... */
  33.  C_y_clipping_min=miny;
  34.  C_x_clipping_max=maxx;
  35.  C_y_clipping_max=maxy;
  36. }
  37. /**********************************************************
  38.  * Getting current state of bounds for 2D clipping.       *
  39. **********************************************************/
  40. void C_get_bounds(int *minx,int *miny,int *maxx,int *maxy)
  41. {
  42.  *minx=C_x_clipping_min;
  43.  *miny=C_y_clipping_min;
  44.  *maxx=C_x_clipping_max;
  45.  *maxy=C_y_clipping_max;
  46. }
  47. /**********************************************************
  48.  * Imposing extra set of bounds for 2D clipping.          *
  49.  *                                                        *
  50.  * RETURNS: 0 when no clipping window exist;              *
  51.  * -------- 1 when it does exist.                         *
  52.  *                                                        *
  53.  *   +--------+      merging two sets of conditions       *
  54.  *   |   +-------+   old and new. Getting an intersection *
  55.  *   |   |////|  |   where both old and new conditions    *
  56.  *   +---|----+  |   are valid.                           *
  57.  *       +-------+                                        *
  58.  *                                                        *
  59.  * SETS: C_x_clipping_min,...,C_y_clipping_max            * 
  60.  * -----                                                  *
  61. **********************************************************/
  62. int C_set_bounds(int minx,int miny,int maxx,int maxy)
  63. {
  64.  if(minx>C_x_clipping_min) C_x_clipping_min=minx;
  65.  if(maxx<C_x_clipping_max) C_x_clipping_max=maxx;
  66.  if(miny>C_y_clipping_min) C_y_clipping_min=miny;
  67.  if(maxy<C_y_clipping_max) C_y_clipping_max=maxy;
  68.  if((C_x_clipping_min>=C_x_clipping_max)||
  69.     (C_y_clipping_min>=C_y_clipping_max)
  70.    ) return(0);                             /* invalid bounds, can't clip */
  71.  else return(1);                            /* clipping is possible */
  72. }
  73. /**********************************************************
  74.  * Line clipping using binary search technique.           *
  75.  *                                                        *
  76.  * RETUNRNS: 0 when line is compleately outside;          *
  77.  * --------- 1 otherwise.                                 *
  78.  *                                                        *
  79.  * SETS:  C_2D_clipping to 1 when first or both points    *
  80.  * -----  were changed, 0 otherwise.                      *
  81. **********************************************************/
  82. int C_line_x_clipping(int **vertex1,int **vertex2,int dimension)
  83. {
  84.  register int i;
  85.  register int whereto;
  86.  register int *l,*r,*m,*t;                  /* left right midle and tmp */
  87.  static int g_store0[C_MAX_DIMENSIONS];     /* static stores for clipped vxes */
  88.  static int g_store1[C_MAX_DIMENSIONS];
  89.  static int g_store2[C_MAX_DIMENSIONS];
  90.  static int g_store3[C_MAX_DIMENSIONS];
  91.  static int g_store4[C_MAX_DIMENSIONS];
  92.  static int g_store5[C_MAX_DIMENSIONS];
  93.  int **vmn,**vmx;                           /* so that *vmn[0] < *vmx[0] */
  94.  int swap;                                  /* were coordinates swaped? */
  95.  C_2D_clipping=0;                           /* default no clipping yet */
  96.  if((*vertex1)[0]<(*vertex2)[0])
  97.  { swap=0; vmn=vertex1; vmx=vertex2; }      /* so that *vmn[0] < *vmx[0] */
  98.  else
  99.  { swap=1; vmn=vertex2; vmx=vertex1; }
  100.  if(((*vmn)[0]>=C_x_clipping_max)||((*vmx)[0]<=C_x_clipping_min)) return(0);
  101.  else
  102.  {
  103.   if((*vmn)[0]<=C_x_clipping_min)           /* clipping */
  104.   {
  105.    HW_copy_int(*vmn,m=g_store0,dimension);  /* copying old vertices */
  106.    HW_copy_int(*vmx,r=g_store1,dimension);
  107.    l=g_store2;
  108.    whereto=1;
  109.    while(m[0]!=C_x_clipping_min)
  110.    {
  111.     if(whereto==1) { t=l; l=m; m=t; }
  112.     else           { t=r; r=m; m=t; }
  113.     for(i=0;i<dimension;i++) m[i]=(l[i]+r[i])>>1;
  114.     whereto=m[0]<C_x_clipping_min;
  115.    }
  116.    *vmn=m;                                  /* that is why m[] is static */
  117.    C_2D_clipping=swap^1;
  118.   }
  119.   if((*vmx)[0]>=C_x_clipping_max)           /* clipping */
  120.   {
  121.    HW_copy_int(*vmn,l=g_store3,dimension);  /* copying old vertices */
  122.    HW_copy_int(*vmx,m=g_store4,dimension);
  123.    r=g_store5;
  124.    whereto=0;
  125.    while(m[0]!=C_x_clipping_max)
  126.    {
  127.     if(whereto==1) { t=l; l=m; m=t; }
  128.     else           { t=r; r=m; m=t; }
  129.     for(i=0;i<dimension;i++) m[i]=(l[i]+r[i])>>1;
  130.     whereto=m[0]<C_x_clipping_max;
  131.    }
  132.    *vmx=m;                                  /* that is why m[] is static */
  133.    C_2D_clipping|=swap&1;
  134.   }
  135.  }
  136.  return(1);                                 /* partialy or not clipped */
  137. }
  138. /**********************************************************
  139.  * Line clipping using binary search technique.           *
  140.  *                                                        *
  141.  * RETUNRNS: 0 when line is compleately outside;          *
  142.  * --------- 1 otherwise.                                 *
  143.  *                                                        *
  144.  * SETS:  C_2D_clipping to 1 when first or both points    *
  145.  * -----  were changed, 0 otherwise.                      *
  146. **********************************************************/
  147. int C_line_y_clipping(int **vertex1,int **vertex2,int dimension)
  148. {
  149.  register int i;
  150.  register int whereto;
  151.  register int *l,*r,*m,*t;                  /* left right midle and tmp */
  152.  static int g_store0[C_MAX_DIMENSIONS];     /* static stores for clipped vxes */
  153.  static int g_store1[C_MAX_DIMENSIONS];
  154.  static int g_store2[C_MAX_DIMENSIONS];
  155.  static int g_store3[C_MAX_DIMENSIONS];
  156.  static int g_store4[C_MAX_DIMENSIONS];
  157.  static int g_store5[C_MAX_DIMENSIONS];
  158.  int **vmn,**vmx;                           /* so that *vmn[1] < *vmx[1] */
  159.  int swap;                                  /* were coordinates swaped? */
  160.  C_2D_clipping=0;                           /* default no clipping yet */
  161.  if((*vertex1)[1]<(*vertex2)[1])
  162.  { swap=0; vmn=vertex1; vmx=vertex2; }      /* so that *vmn[1] < *vmx[1] */
  163.  else
  164.  { swap=1; vmn=vertex2; vmx=vertex1; }
  165.  if(((*vmn)[1]>=C_y_clipping_max)||((*vmx)[1]<=C_y_clipping_min)) return(0);
  166.  else
  167.  {
  168.   if((*vmn)[1]<=C_y_clipping_min)           /* clipping */
  169.   {
  170.    HW_copy_int(*vmn,m=g_store0,dimension);  /* copying old vertices */
  171.    HW_copy_int(*vmx,r=g_store1,dimension);
  172.    l=g_store2;
  173.    whereto=1;
  174.    while(m[1]!=C_y_clipping_min)
  175.    {
  176.     if(whereto==1) { t=l; l=m; m=t; }
  177.     else           { t=r; r=m; m=t; }
  178.     for(i=0;i<dimension;i++) m[i]=(l[i]+r[i])>>1;
  179.     whereto=m[1]<C_y_clipping_min;
  180.    }
  181.    *vmn=m;                                  /* that is why m[] is static */
  182.    C_2D_clipping=swap^1;
  183.   }
  184.   if((*vmx)[1]>=C_y_clipping_max)           /* clipping */
  185.   {
  186.    HW_copy_int(*vmn,l=g_store3,dimension);  /* copying old vertices */
  187.    HW_copy_int(*vmx,m=g_store4,dimension);
  188.    r=g_store5;
  189.    whereto=0;
  190.    while(m[1]!=C_y_clipping_max)
  191.    {
  192.     if(whereto==1) { t=l; l=m; m=t; }
  193.     else           { t=r; r=m; m=t; }
  194.     for(i=0;i<dimension;i++) m[i]=(l[i]+r[i])>>1;
  195.     whereto=m[1]<C_y_clipping_max;
  196.    }
  197.    *vmx=m;                                  /* that is why m[] is static */
  198.    C_2D_clipping|=swap&1;
  199.   }
  200.  }
  201.  return(1);                                 /* partialy or not clipped */
  202. }
  203. /**********************************************************
  204.  * Creating a x-clipped polygon.                          *
  205.  *                                                        *
  206.  * RETURNS: number of elements in the clipped polygon.    *
  207.  * -------- (0 when compleately behind view plane)        *
  208.  *                                                        *
  209.  *         |    |        1-2-3-4-5-6-1  -> 2'-3'-5'-6'    *
  210.  *         |5'  |6'                                       *
  211.  *      5*-*----*-*6     If first vertex in the line is   *
  212.  *      /  |    |       being clipped both vertices are  *
  213.  *    4*   |    |    *1  copyed.If no clipping or second  *
  214.  *        |    |   /    one is clipped then only second  *
  215.  *      3*-*----*-*2     one is copyed. If both vertices  *
  216.  *         |3'  |2'      are clipped, neither is copyed.  *
  217.  *                                                        *
  218. **********************************************************/
  219. int C_polygon_x_clipping(int *from,register int *to,int dimension,int length)
  220. {
  221.  register int i;
  222.  int *v1,*v2,new_lng=0;
  223.  int *first_vrtx=to;                        /* begining of the source */
  224.  for(i=0;i<length;i++)                      /* for all edges */
  225.  {
  226.   v1=(int*)from; from+=dimension; v2=(int*)from;
  227.   if(C_line_x_clipping(&v1,&v2,dimension))  /* clipping */
  228.   {
  229.    if(C_2D_clipping)                        /* depends which one was clipped */
  230.    {
  231.     HW_copy_int(v1,to,dimension); to+=dimension;
  232.     HW_copy_int(v2,to,dimension); to+=dimension;
  233.     new_lng+=2;                             /* first point clipped */
  234.    }
  235.    else
  236.    {
  237.     HW_copy_int(v2,to,dimension); to+=dimension;
  238.     new_lng++;                              /* second point clipped */
  239.    }
  240.   }
  241.  }
  242.  HW_copy_int(first_vrtx,to,dimension);      /* looping the polygon vertices */
  243.  return(new_lng);
  244. }
  245. /**********************************************************/