⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 图形学算法(伪代码).txt

📁 图形学算法(伪代码)
💻 TXT
字号:
//bresenham 圆
void MyCircle(CDC* pDC, int x0, int y0, int r)
{   int d, x, y ;

    d = 1-r;
    x = 0;  y = r;
    CirclePoint( pDC, x0, y0, x, y ) ;
    while( y>x )
    { if( d<=0 ) d += 2*x+3; 
        else { d += 2*(x-y);  y--; }
      x++;
      CirclePoint( pDC, x0, y0, x, y ) ;}
}

void CirclePoint( CDC* pDC, int x0, int y0, int x, int y)
{   
        pDC->SetPixel( pDC, x0+x, y0+y ) ;
        pDC->SetPixel( pDC, x0+y, y0+x ) ;
        pDC->SetPixel( pDC, x0-y, y0+x ) ;
        pDC->SetPixel( pDC, x0-x, y0+y ) ;
        pDC->SetPixel( pDC, x0+y, y0-x ) ;
        pDC->SetPixel( pDC, x0+x, y0-y ) ;
        pDC->SetPixel( pDC, x0-x, y0-y ) ;
        pDC->SetPixel( pDC, x0-y, y0-x ) ;
}
-----------------------------------------------------------------------
//bresenham 直线
void MyLine( CDC* pDC, int x1, int y1, int x2, int y2, COLORREF color )
{
  int x, y, e, a, b ;

  a = x2 - x1 ;
  b = y2 - y1 ;
  e = 2 * b - a ;
  x = x1 ; y = y1 ;
  MySetPixel( pDC, x, y, color ) ;
  while( (x != x2) || ( y != y2 ))
   { if ( e >= 0 ) 
        { y ++ ; e -= 2 * a ; }
         x ++ ;  
         e += 2 * b ; }
     pDC->SetPixel( x, y, color ) ; 
        }
}
-----------------------------------------------------------------------
//四连通点填充 (边界)
void MyFloodFill( CDC* pDC, int x, int y, COLORREF color, COLORREF BoundColor )
{
        pDC->SetPixel(x,y,color);
        if ( pDC->GetPixel(x-1,y) != BoundColor )
                MyFloodFill( pDC, x-1, y, color, BoundColor ) ;
        if ( pDC->GetPixel(x+1,y) != BoundColor )
                MyFloodFill( pDC, x+1, y, color, BoundColor ) ;
        if ( pDC->GetPixel(x,y+1) != BoundColor )
                MyFloodFill( pDC, x, y+1, color, BoundColor ) ;
        if ( pDC->GetPixel(x,y-1) != BoundColor )
                MyFloodFill( pDC, x, y-1, color, BoundColor ) ;
}
-----------------------------------------------------------------------
//四连通点填充 (内部)
void MyFloodFill( CDC* pDC, int x, int y, COLORREF color, COLORREF OldColor )
{
        pDC->SetPixel(x,y,color);
        if ( pDC->GetPixel(x-1,y) == OldColor )
                MyFloodFill( pDC, x-1, y, color, OldColor ) ;
        if ( pDC->GetPixel(x+1,y) == OldColor )
                MyFloodFill( pDC, x+1, y, color, OldColor ) ;
        if ( pDC->GetPixel(x,y+1) == OldColor )
                MyFloodFill( pDC, x, y+1, color, OldColor ) ;
        if ( pDC->GetPixel(x,y-1) == OldColor )
                MyFloodFill( pDC, x, y-1, color, OldColor ) ;
}
-----------------------------------------------------------------------
//bezier 分裂
void BezierSplit( CDC * pDC, double px[], double py[], int n, int k)
{
  double qx[MAX], qy[MAX] ;
  register i, j ;

  for( i = 0 ; i <= n ; i++ )
   { qx[i] = px[0] ;
     qy[i] = py[0] ;
     for( j = 0 ; j < n-i ; j++ )
      {         px[j] =(px[j] + px[j+1]) / 2. ;
                 py[j] =(py[j] + py[j+1]) / 2. ; } }
  if ( k > 1 )
   { BezierSplit( pDC, qx, qy, n, k-1) ;
         BezierSplit( pDC, px, py, n, k-1) ; }
  else
   { DrawLine( pDC, qx, qy, n ) ;
         DrawLine( pDC, px, py, n ) ; }
}

void DrawLine(CDC * pDC, double px[], double py[], int n)
{ register i ;

  pDC->MoveTo((int)px[0], (int)py[0]) ;
  for( i = 1 ; i <= n ; i++ )
    pDC->LineTo((int)px[i], (int)py[i]) ;
}
-----------------------------------------------------------------------
//逐点 Bezier
void BezierPoint( CDC * pDC,  double px[], double py[], int n, int count)
{
  double qx[MAX], qy[MAX], u ;
  register i, j, k ;

  pDC->MoveTo((int)px[0], (int)py[0]) ;
  for( k = 1 ; k < count ; k++ )
   { u = (double)k / (double)count ;
     for( i = 0 ; i <= n ; i++ )
      { qx[i] = px[i] ;
                qy[i] = py[i] ; }
     for( i = 0 ; i < n ; i++ )
       for( j = 0 ; j < n-i ; j++ )
                { qx[j] = (1.-u) * qx[j] + u * qx[j+1] ;
                  qy[j] =(1.-u) * qy[j] + u * qy[j+1];}
     pDC->LineTo((int)qx[0], (int)qy[0]) ; }
  pDC->LineTo((int)px[i], (int)py[i]) ;
}
-----------------------------------------------------------------------
//二次B样条
void Bspline2( CDC * pDC, double px[], double py[], int n, int count)
{ double mar2[4][4] = {{0.5, -1., 0.5, 0.}, {-1., 1., 0., 0.},
                      {0.5, 0.5, 0., 0.} , { 0., 0., 0., 0.}} ;
  register i ;

  pDC->MoveTo((int) ceil((px[0]+px[1])/2.), (int) ceil((py[0]+py[1])/2.)) ;
  for( i = 0 ; i <= n - 2 ; )
   { BsplinePoint( pDC, mar2, 2, px, py, i++, count ) ;
     pDC->LineTo((int) ceil((px[i]+px[i+1])/2.), (int) ceil((py[i]+py[i+1])/2.))
; }
     pDC->SelectObject(oldpen);
}

void BsplinePoint( CDC * pDC,  double mar[][4], int k, double px[], double py[],
                   int m, int count )
{ double t, u, x, y, sx, sy ;
  register i, j, l ;

  for( l = 1 ; l < count ; l++ )
   { t = (double)l / (double)count ;
     u = 1. ; x = y = 0. ;
     for( i = k ; i >= 0 ; i-- )
      { sx = sy = 0. ;
           for( j = 0 ; j <= k ; j++ )
           { sx += mar[i][j] * px[m+j] ;
             sy += mar[i][j] * py[m+j] ; }
           x += u * sx ; y += u * sy ;
           u *= t ; }
       pDC->LineTo((int)x, (int)y) ; }
}
-----------------------------------------------------------------------
//三次B样条
void Bspline3(CDC* pDC,double px[], double py[], int n, int count)
{  double mar3[4][4] = {
          {-0.166667, 0.5, -0.5, 0.166667},
          {0.5, -1., 0.5, 0.},
           {-0.5, 0., 0.5, 0.} , 
          { 0.166667, 0.666667, 0.166667, 0.}  } ;
  register i ;

  pDC->MoveTo((px[0]+4.*px[1]+px[2])/6., 
                (py[0]+4.*py[1]+py[2])/6.);
  for( i = 0 ; i <= n - 3 ; )
   { BsplinePoint(pDC, mar3, 3, px, py, i++, count ) ;
     pDC->LineTo((int)((px[i]+4.*px[i+1]+px[i+2])/6.),
                (int) (py[i]+4.*py[i+1]+py[i+2])/6.)) ; }
}

void BsplinePoint( CDC * pDC,  double mar[][4], int k, double px[], double py[],
                   int m, int count )
{
  double t, u, x, y, sx, sy ;
  register i, j, l ;

  for( l = 1 ; l < count ; l++ )
   { t = (double)l / (double)count ;
     u = 1. ; x = y = 0. ;
     for( i = k ; i >= 0 ; i-- )
      { sx = sy = 0. ;
                for( j = 0 ; j <= k ; j++ )
                { sx += mar[i][j] * px[m+j] ;
              sy += mar[i][j] * py[m+j] ; }
                x += u * sx ; y += u * sy ;
                u *= t ; }
     pDC->LineTo((int)x, (int)y) ; }
}

-----------------------------------------------------------------------
//线填充Etable
void SortXrank( PETable ETable[], int Xrank[], int k )
{//冒泡排序
  int i, j, tmp ;
  for( i=0; i<k; i++ )
     for( j = 0; j<k-i; j++ )
       if (ETable[Xrank[j]]->x > ETable[Xrank[j+1]]->x )
        { tmp = Xrank[j] ; Xrank[j] = Xrank[j+1] ;
           Xrank[j+1] = tmp ; }
}

void AddETable( PETable ETable[], int i, int n )
{
  if ( i == -1 ) i = n ;
  switch( ETable[i]->flag )
      { case 0 :
          ETable[i]->flag = 1 ;
          break ;
        case 1 :
          ETable[i]->flag = -1 ;
          break ;
      }
}

PETable RequestETable(int x0, int y0, int x, int y)
{//生成一个表
  PETable p ;

  p = new ETable ;
  if ( y >= y0 )
   { p->x = (float)x0 ;
         p->dx = (float)(x-x0)/(float)(y-y0) ; } 
  else
   { p->x = (float)x ;
         p->dx = (float)(x0-x)/(float)(y0-y) ; }
  p->flag = 0 ;
  return(p) ;
}

void MyFillPolygon( CDC* pDC, float p[][2], int n, int color)
{
//p为点数组,n条边,n个顶点
  PETable ETable[10] ;
  int Yrank[10], Xrank[10], flag[10] ;
  int i, j, k, tmp ;
  int x0, y0, x, y ;

  //画多变形
  DrawPolygon( pDC, p, n, color ) ;
  //排序顶点,Yrank[]为顶点下标
  for( i=0; i<=n; i++ )
    Yrank[i] = i ;
  for( i=0; i<n; i++ )
   for( j = 0; j<n-i; j++ )
     if ( p[Yrank[j]][1] > p[Yrank[j+1]][1] ) //按y值冒泡排序
          { tmp = Yrank[j] ; Yrank[j] = Yrank[j+1] ;
            Yrank[j+1] = tmp ; }
  //初始化ET表
  x0 = (int)p[0][0]; y0 = (int)p[0][1] ;
  for( i=1; i<=n; i++ )
   { x = (int)p[i][0] ; y = (int)p[i][1] ;
     ETable[i-1] = RequestETable(x0, y0, x, y) ;
     x0 = x ; y0 = y ;
   }
  x = (int)p[0][0]; y = (int)p[0][1] ;//最后一条边
  ETable[n] = RequestETable(x0, y0, x, y) ;


  //遍历填色
  i = 0 ;
  y = p[Yrank[0]][1] ;
  while( i < n )
   { //引进二边表
     do
      { AddETable( ETable, Yrank[i], n ) ;
        AddETable( ETable, Yrank[i]-1, n ) ;
        i++ ;
      } while( p[Yrank[i]][1] == p[Yrank[i-1]][1] ) ;
     //计算x新值
     k = 0 ;
     for( j=0; j<=n; j++ )
       if (ETable[j]->flag == 1)
                { ETable[j]->x += ETable[j]->dx ;
                  Xrank[k++] = j ; 
                }
     k-- ;
     SortXrank( ETable, Xrank, k ) ;  //排序新x值
         //重复画线填色
     for( ; y <= p[Yrank[i]][1]; y++ )
      { for( j = 0 ; j <= k ; j+=2 )
                { vline( pDC, (int)(ETable[Xrank[j]]->x+1.5),(int)(ETable[Xrank[j+1]]->x+0.5), y, color ) ;
                        ETable[Xrank[j]]->x += ETable[Xrank[j]]->dx ;
                        ETable[Xrank[j+1]]->x +=ETable[Xrank[j+1]]->dx;
       }}}
}
////////////////////////////////////////////////////////////////////////
(1)将顶点按y值升序排列 Ri
(2)置初值:y=y[R[0]]
(3)For(i=0;i<=N;i++)
        {引进p[R[i]]的两边,L,R
        如果边在AET表中删除,不在加入
        重新对AET排序,否则先比较x,x相等,比较dx
        for(;y<y[R[i+1]];y++)
        {
                遍历AET表(j=0;j<k;j++)
                do{
                        Lineto(x[i,j],y)
                        遍历AET表
                        x[i]=do[i]直到结束
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -