多边形填充算法

多边形填充算法

//+++++++++++++++++++++++++++++++++++
//+-----------------定义基本数据-------------------+
//+++++++++++++++++++++++++++++++++++
//----------------------struct_def.h------------------------------

const int MAX_Y=1028; 
const int MAX_X=1024;
const int MAX_ARC=100;  //假定边的总数最多为 100

typedef struct ArcNode  //定义边
{
 int x1,y1; 
 int x2,y2;
}ArcNode;
typedef struct Node //定义EOT,AET 表中的链表结点
{
   int Ymin;
   float Xs;
   float xx;
   Node * next;
}ElemNode, * ElemLink;
typedef struct NodeY // Y 桶表
{
 ElemLink link;
 int Y;
}NodeY;
typedef struct Table  //表EOT和表AET同样结构
{
   NodeY nodeY[MAX_Y];
}* TableList;


TableList createEOTList(ArcNode arrayARC[MAX_ARC], int n);
void ShowTable(const Table * table);
void InsertArcNode(TableList table,Node *const node,int Y);
TableList EOT_to_AET(const TableList table);

//---------------------------------具体算法实现-----------------------------------

TableList createEOTList(ArcNode arrayARC[MAX_ARC], int n)
{
     TableList eotList=new Table;
 int i;
  for(i=0;i<MAX_Y;i++) //初始化 Y 表
  {  
   eotList->nodeY[i].link=NULL;
   eotList->nodeY[i].Y=i;
  }


  int Y;
  for(i=0;i<n;i++)
  {  if(arrayARC[i].y1 != arrayARC[i].y2) 
  {
   Node * node=new Node;
   if(arrayARC[i].y1 < arrayARC[i].y2)  // y1 < y2
   {
     node->Ymin=arrayARC[i].y1;
     node->Xs=(float)arrayARC[i].x2;
     Y=arrayARC[i].y2;   //!!!!!!!
   }
   if(arrayARC[i].y1 > arrayARC[i].y2)  // y1 > y2  ,y1==y2 的情况不要
   {
     node->Ymin=arrayARC[i].y2;
     node->Xs=(float)arrayARC[i].x1;
     Y=arrayARC[i].y1;
   }
         node->xx=(float) -(arrayARC[i].x2-arrayARC[i].x1) / (arrayARC[i].y2-arrayARC[i].y1);
   node->next=NULL;
   InsertArcNode(eotList,node,Y);
        }
  }
  return eotList;

}

void InsertArcNode(TableList table, Node *const node,int Y)
{
        if(table->nodeY[Y].link==NULL)  
   {  //表头为空
    table->nodeY[Y].link=node;
    node->next=NULL;
    return ;
   }
         else
   {  
    ElemLink head_node=table->nodeY[Y].link;
    ElemNode *temp_node=head_node;
             if((node->Xs < head_node->Xs) || (head_node->Xs == node->Xs && node->xx < head_node->xx))
             {  //插在表头
       table->nodeY[Y].link=node;
       node->next=head_node;
       return;
    }
    else
    {
     while(temp_node->next != NULL)
     {
                 if((node->Xs < temp_node->next->Xs) || (temp_node->next->Xs == node->Xs && node->xx < temp_node->next->xx))
                 {    node->next=temp_node->next;
         temp_node->next=node;
      return;
     }
     else
       temp_node=temp_node->next;
     }  //end while
     if(temp_node->next==NULL)
     {
      temp_node->next=node;
      node->next=NULL;
      return;
     }
    }
  }//end else
}

TableList EOT_to_AET(const TableList table)
{
 int i,j,Y;
 float sum;
 ElemLink head=new Node; 
 TableList tableAET=new Table;

 for(i=0;i<MAX_Y;i++) //初始化 Y 表 且将 EOT copy 到 AET
  {  
   tableAET->nodeY[i].link=NULL;
   tableAET->nodeY[i].Y=i;
  }
    
 for(i=MAX_Y-1;i>0;i--)   //i=MAX_Y-1
 {  
  head=table->nodeY[i].link;
  Y=table->nodeY[i].Y;
  while(head)  
  {  
   Node * temp=new Node;
   temp->Xs =head->Xs;
   temp->Ymin=head->Ymin;
   temp->xx=head->xx;
      temp->next=NULL;
   InsertArcNode(tableAET,temp,Y);
  
   sum=head->Xs;       
   for(j=Y-1;j > head->Ymin;j--)
   {   sum = sum + head->xx;
    Node * addNode=new Node;
    addNode->Ymin=head->Ymin;
    addNode->xx=head->xx;
    addNode->Xs=sum;
    addNode->next=NULL;
       InsertArcNode(tableAET,addNode,j); 
   }
   head=head->next;
  }//END WHILE  
 }
 return tableAET;
}

//在DOC 中定义一数组,在VIEW通过pDoc->arrayARC 获得数组并在显示,数组通过对话框输入,颜色可选!

void CTestHTView::OnDraw(CDC* pDC)
{
 CTestHTDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 int i,j;
   
 TableList tableEOT=new Table;
 tableEOT=createEOTList(pDoc->ArrayARC,pDoc->num); //
 TableList tableAET=new Table;
 tableAET=EOT_to_AET(tableEOT);

  Node * head=new Node;
  int X1,X2;
 for(i=MAX_Y-1;i>=0;i--)
  {
  head=tableAET->nodeY[i].link;
  while(head)
  {
   X1=head->Xs;
   head=head->next;
   X2=head->Xs;
   for(j=X1;j<X2;j++)
    pDC->SetPixel(j,i,RGB(m_R,m_G,m_B));
  
   head=head->next;
  }
 } 
    ReleaseDC(pDC);
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include #include #include #include #include //////////////////////////////////////////////////////////////functions///////////////////////////////////////////////// void swap(float &m,float &n) { float temp=n; n=m; m=temp; } int sign(float a,float b)//sign() { int t; if(a>b) { t=1;} else if(adx) { swap(dx,dy); Flag=1; } else Flag=0; float Nerror=2*dy-dx; for(int i=1;i=0) { if(Flag) { x=x+sx;} else y=y+sy; Nerror=Nerror-2*dx; } if(Flag) { y=y+sy;} else x=x+sx; Nerror=Nerror+2*dy; } } ///////////////////////////////////四连通种子填充/////////////////////////////////////////////////// void BoundaryFill4(HDC hdc,int x,int y,int FilledColor,int BoundaryColor) { int CurrentColor; CurrentColor=GetPixel(hdc,x,y); if(CurrentColor!=BoundaryColor&&CurrentColor!=FilledColor) { SetPixel(hdc,x,y,FilledColor); BoundaryFill4(hdc,x+1,y,FilledColor,BoundaryColor); BoundaryFill4(hdc,x-1,y,FilledColor,BoundaryColor); BoundaryFill4(hdc,x,y+1,FilledColor,BoundaryColor); BoundaryFill4(hdc,x,y-1,FilledColor,BoundaryColor); } } ////////////////////////////////////////扫描线填充/////////////////////////////////////////////////// //DrawLine()函数:在(x1,y)和(x2,y)两点之间画一条颜色为FilledColor的横线(用来扫描填充) void drawline(HDC hdc, int x1, int x2,int y0, int FilledColor) { for(int n=x1+1;n<x2;n++) { SetPixel(hdc,n,y0,FilledColor); } } //Scan()函数:扫描线函数,将扫描线与图形的交点坐标存在数组中 //数组中同行的点即为该行扫描线与图形的交点(一般为2个) //数组中的行代表扫描线的纵坐标 void scan(HDC hdc, int boundarycolor) { int currentcolor; int a[300][2]={0}; for (int j=0;j<300;j++) { for(int i=300;i<700;i++) { currentcolor=GetPixel(hdc,i,j); if((currentcolor==boundarycolor)&&(GetPixel(hdc,i+1,j)!=boundarycolor)&&(i500)) {a[j][1]=i;} } } //利用循环调用DrawLine函数逐行填充两交点之间的点 for(int k=0;k<300;k++) { if((a[k][0]!=0)&&(a[k][1]!=0)) drawline(hdc,a[k][0],a[k][1],k,RGB(255,0,0));} } ///////////////////////////////////////////////边界填充////////////////////////////////////// //Contrary()取反函数:如果点的颜色为白,则将点置为填充色;如果点的颜色为填充色,则将点置为白色 //忽略了边界色,即不对边界点作颜色处理 void contrary(HDC hdc, int x, int y,int FilledColor) { for(int h=x;h<280;h++) { if(GetPixel(hdc,h,y)==RGB(255,255,255)) { SetPixel(hdc,h,y,FilledColor); } else if(GetPixel(hdc,h,y)==FilledColor) { SetPixel(hdc,h,y,RGB(255,255,255)); } } } //borderline()边线函数: 先找出图形的边界 左边和右边,从右到左的顺序调用contrary()函数进行填充 void borderline(HDC hdc, int boundarycolor) { for(int j=280;j<499;j++) { for(int i=80;i100)) { contrary(hdc,i,j,RGB(0,0,255)); } } } for(int m=280;m<499;m++) { for(int n=80;n<280;n++) { int currentcolor=GetPixel(hdc,n,m); if((currentcolor==boundarycolor)&&(GetPixel(hdc,n+1,m)!=boundarycolor)&&(GetPixel(hdc,n-1,m)!=boundarycolor)&&(n<101)) { contrary(hdc,n,m,RGB(0,0,255)); } } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值