CLipping.cpp
上传用户:whjcdz88
上传日期:2011-09-07
资源大小:121k
文件大小:4k
源码类别:

图形图象

开发平台:

WINDOWS

  1. #include "Clipping.h"
  2. int get_code( POINT p , RECT rect )
  3. {
  4. int code = 0 ;
  5. if( p.y < rect.top )
  6. code |= TOP ;
  7. else
  8. if( p.y  > rect.bottom )
  9. code |= BOTTOM ;
  10. if( p.x  > rect.right )
  11. code |= RIGHT ;
  12. else
  13. if( p.x < rect.left )
  14. code |= LEFT ;
  15. return code ;
  16. }
  17. int Cohen_Sutherland_Line_Clipping( POINT& p1 ,int Code1 ,POINT& p2  , int Code2 ,  RECT rect , HDC hdc )
  18. {
  19. int draw , done , code ;
  20. int x , y ;
  21. int code1 = Code1 , code2 = Code2 ;
  22. draw = 0 ; done = 0 ;
  23. while( !done )
  24. {
  25. if( code1 == 0 && code2 == 0 )
  26. {
  27. draw = 1 ; done = 1 ;
  28. }
  29. else
  30. if( (code1 & code2) != 0 )
  31. done = 1 ;
  32. else
  33. {
  34. draw = 1 ;
  35. if( code1 != 0 )
  36. code = code1 ;
  37. else
  38. code = code2 ;
  39. if( (code & TOP) != 0 )
  40. {
  41. y = rect.top ;
  42. x = (int)(p1.x + (float)( y - p1.y ) * ( p2.x - p1.x ) / ( p2.y - p1.y ));
  43. }
  44. else
  45. {
  46. if( (code & BOTTOM) != 0 )
  47. {
  48. y = rect.bottom ;
  49. x = (int)(p1.x + (float)( y - p1.y ) * ( p2.x - p1.x ) / ( p2.y - p1.y ));
  50. }
  51. else
  52. if( (code & RIGHT) != 0 )
  53. {
  54. x = rect.right ;
  55. y = (int)(p1.y + (float)( x - p1.x ) * ( p2.y - p1.y ) / ( p2.x - p1.x )) ;
  56. }
  57. else
  58. if( (code & LEFT) != 0 )
  59. {
  60. x = rect.left ;
  61. y = (int)(p1.y + (float)( x - p1.x ) * ( p2.y - p1.y ) / ( p2.x - p1.x ));
  62. }
  63. }
  64. if( code == code1 )
  65. {
  66. p1.x = x ; p1.y = y ;
  67. code1 = get_code( p1, rect );
  68. }
  69. else
  70. {
  71. p2.x = x  ; p2.y = y ;
  72. code2 = get_code( p2 , rect );
  73. }
  74. }
  75. }
  76. if( draw == 1 )
  77. {
  78. MoveToEx( hdc , p1.x , p1.y , NULL );
  79. LineTo( hdc , p2.x , p2.y ) ;
  80. }
  81. return draw ;
  82. }
  83. void Clipping( POINT points[] , int count , RECT rect ,HDC hdc )
  84. {
  85. POINT * In = new POINT[ count * 2 ] ;
  86. POINT * Out = new POINT[ count * 2 ];
  87. int * Code = new int[ count ] ;
  88. int i ;
  89. for( int k = 0 ; k < count ; k ++ )
  90. Code[k] = get_code( points[k] , rect ) ;
  91. int in = 0 , out = 0 , draw = 0 ;
  92. for( i = 0 ; i < count ; i ++ )
  93. {
  94. In[ in ] = points[ i ] ;
  95. Out[ out ] = points[ ( i + 1 )%count ];
  96. draw = Cohen_Sutherland_Line_Clipping( In[ in ] ,Code[i] , Out[ out ] , Code[ (i+1)%count ] ,rect , hdc );
  97. if( draw == 1 )
  98. {
  99. if( Code[i] != 0 ) // points[i] is out of the window
  100. in ++ ;
  101. if( Code[ (i+1)%count] != 0 )
  102. out ++ ;
  103. }
  104. }
  105. int position = 0  , finish = 0 ;
  106. POINT Corner[4] = {  {rect.left , rect.bottom } , { rect.right , rect.bottom } , {rect.right , rect.top },{rect.left , rect.top }  } ;
  107. POINT Position , start ;
  108. int done = 0 ;
  109. while( finish < out )
  110. {
  111. start = Out[ finish ] ;
  112. done = 0 ;
  113. if( Out[ finish ] .x == rect.left )
  114. position = 0 ;
  115. if( Out[ finish ].x == rect.right )
  116. position = 2 ;
  117. if( Out[ finish ].y == rect.top )
  118. position = 3 ;
  119. if( Out[ finish ] .y == rect.bottom )
  120. position = 1 ;
  121. while( !done )
  122. {
  123. Position = Corner[ position ] ;
  124. for( i = 0 ; i < in ; i ++ )
  125. {
  126. switch( position )
  127. {
  128. case 0 :
  129. if( In[i].y < Position.y && In[i].x == rect.left && In[i].y > start.y )
  130. {
  131. done = 1 ; Position = In[i] ;
  132. }
  133. break;
  134. case 1 :
  135. if( In[i].x > start.x && In[i].y == rect.bottom && In[i].x < Position.x )
  136. {
  137. done = 1 ; Position = In[i] ;
  138. }
  139. break;
  140. case 2 :
  141. if( In[i].x == rect.right && In[i].y < start.y && In[i].y > Position.y )
  142. {
  143. done = 1 ; Position = In[i] ;
  144. }
  145. break;
  146. case 3 :
  147. if( In[i].y == rect.top && In[i].x < start.x && In[i].x > Position.x )
  148. {
  149. done = 1 ; Position = In[i] ;
  150. }
  151. break;
  152. }
  153. }
  154. MoveToEx( hdc , start.x , start.y , NULL );
  155. LineTo( hdc , Position.x , Position.y );
  156. if( done == 1 )
  157. finish ++ ;
  158. else
  159. {
  160. position ++ ; start = Position ;
  161. }
  162. }
  163. }
  164. delete[] In;
  165. delete[] Out ;
  166. delete[] Code;
  167. }