求多边形填充算法,分不够再加

jingqiang2008 2003-10-15 02:55:36
求多边形填充算法(扫描转换填充算法中的Y-X扫描线算法的具体实现)。急需求多边形填充算法的实现,效率越高越好,身边只有一本书讲到扫描转换填充算法中的Y-X扫描线算法效率较高,如能提供效率更高的算法更好。分不够可再加。请大家帮助。
...全文
158 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
jingqiang2008 2003-10-20
  • 打赏
  • 举报
回复
yndfcd(YNDFCD),POLYGON2D_PTR 定义是什么?请帖出完整的代码好么?我是新手,看起来比较费劲。谢谢。
jingqiang2008 2003-10-17
  • 打赏
  • 举报
回复
感谢回帖,不过看的头都大了:(
jingqiang2008 2003-10-16
  • 打赏
  • 举报
回复
这是我目前用的。
#include <stdlib.h>
#include <malloc.h>
#define WINDOW_HEIGHT 480
#define NULL 0
typedef struct tEdge
{
int ymax;
float x;
float dx;
struct tEdge *next;
}Edge;
typedef struct point
{
int x;
int y;
}POINT;
void InsertEdge(Edge *list,Edge *edge)
{
Edge *p,*q=list;
p=q->next;
while(p)
{
if(edge->x<p->x)
p=NULL;
else
{
q=p;
p=p->next;
}
}
edge->next=q->next;
q->next=edge;
}
int yNext(int k,int cnt,POINT *pts)
{
int j;
if((k+1)>(cnt-1))
j=0;
else
j=k+1;
while(pts[k].y==pts[j].y)
if((j+1)>(cnt-1))
j=0;
else
j++;
return(pts[j].y);
}
void MakeEdgeRec(POINT lower,POINT upper,int yComp,Edge *edge,Edge *edges[])
{
edge->dx=(float)(upper.x-lower.x)/(upper.y-lower.y);
edge->x=(float)lower.x;
if(upper.y<yComp)
edge->ymax=upper.y-1;
else
edge->ymax =upper.y;
InsertEdge(edges[lower.y],edge);
}
void BuildEdgeList(int cnt,POINT *pts,Edge *edges[])
{
Edge *edge;
POINT v1,v2;
int i,yPrev=pts[cnt-2].y;
v1.x=pts[cnt-1].x;
v1.y=pts[cnt-1].y;
for(i=0;i<cnt;i++)
{
v2=pts[i];
if(v1.y!=v2.y)
{
edge=(Edge*)malloc(sizeof(Edge));
if(v1.y<v2.y)
MakeEdgeRec(v1,v2,yNext(i,cnt,pts),edge,edges);
else
MakeEdgeRec(v2,v1,yPrev,edge,edges);
}
yPrev=v1.y;
v1=v2;
}
}
void BuildActiveList(int scan,Edge *active,Edge *edges[])
{
Edge *p,*q;
p=edges[scan]->next ;
while(p)
{
q=p->next ;
InsertEdge(active,p);
p=q;
}
}
void FillScan(int scan,Edge *active,int color)
{
Edge *p1,*p2;
int i;
p1=active->next;
while(p1)
{
p2=p1->next;
for(i=p1->x;i<p2->x;i++)
setpixel((int)i,scan,color);
p1=p2->next ;
}
}
void DeleteAfter(Edge *q)
{
Edge *p=q->next ;
q->next =p->next ;
free(p);
}
void UpdateActiveList(int scan,Edge *active)
{
Edge *q=active,*p=active->next ;
while(p)
if(scan>=p->ymax)
{
p=p->next ;
DeleteAfter(q);
}
else
{
p->x=p->x+p->dx;
q=p;p=p->next;
}
}
void ResortActiveList(Edge *active)
{
Edge *q,*p=active->next;
active->next =NULL;
while(p)
{
q=p->next ;
InsertEdge(active,p);
p=q;
}
}
void ScanFill(int cnt,POINT *pts,int color)
{
Edge *edges[WINDOW_HEIGHT],*active;
int i,scan,scanmax=0,scanmin=WINDOW_HEIGHT;
for(i=0;i<cnt-1;i++)
{
if(scanmax<pts[i].y) scanmax=pts[i].y;
if(scanmin>pts[i].y) scanmin=pts[i].y;
}
for(scan=scanmin;scan<=scanmax;scan++)
{
edges[scan]=(Edge *)malloc(sizeof(Edge));
edges[scan]->next=NULL;
}
BuildEdgeList(cnt,pts,edges);
active=(Edge *)malloc(sizeof(Edge));
active->next =NULL;
for(scan=scanmin;scan<=scanmax;scan++)
{
BuildActiveList(scan,active,edges);
if(active->next )
{
FillScan(scan,active,color);
UpdateActiveList(scan,active);
ResortActiveList(active);
}
}
}
jakeye 2003-10-16
  • 打赏
  • 举报
回复
我不知道,学习学习。
tonybaobao 2003-10-16
  • 打赏
  • 举报
回复
我也只知道种子算法了……
yndfcd 2003-10-16
  • 打赏
  • 举报
回复
// calculate edge 2:

while ((errorterm2 < xdiff2) && (count2 > 0))
{
// finished w/edge 2?
if (count2--)
{
// count down on edge 2
offset2+=xunit2; // increment pixel offset
xstart2+=xunit2;
} // end if

errorterm2+=ydiff2; // increment error term

if (errorterm2 < xdiff2)
{ // if not more than XDIFF
vbuffer[offset2]=(UCHAR)poly->color; // ...plot a pixel
} // end if

} // end while

errorterm2-=xdiff2; // if time to increment X, restore error term

// draw line from edge 1 to edge 2:

length=offset2-offset1; // determine length of horizontal line

if (length < 0)
{ // if negative...
length=-length; // make it positive
start=offset2; // and set START to edge 2
} // end if
else
start=offset1; // else set START to edge 1

for (int index=start; index < start+length+1; index++)
{ // From edge to edge...
vbuffer[index]=(UCHAR)poly->color; // ...draw the line
} // end for index

offset1+=mempitch; // advance edge 1 offset to next line
ystart1++;
offset2+=mempitch; // advance edge 2 offset to next line
ystart2++;

} // end if

} // end if
else
{
// increment edge 1 on X and edge 2 on Y:
count1=xdiff1; // count for X increment on edge 1
count2=ydiff2; // count for Y increment on edge 2

while (count1 && count2)
{ // continue drawing until one edge is done
// calculate edge 1:
while ((errorterm1 < xdiff1) && (count1 > 0))
{ // finished w/edge 1?
if (count1--)
{
// count down on edge 1
offset1+=xunit1; // increment pixel offset
xstart1+=xunit1;
} // end if

errorterm1+=ydiff1; // increment error term

if (errorterm1 < xdiff1)
{ // If not more than XDIFF
vbuffer[offset1]=(UCHAR)poly->color; // ...plot a pixel
} // end if

} // end while

errorterm1-=xdiff1; // If time to increment X, restore error term

// calculate edge 2:
errorterm2+=xdiff2; // increment error term

if (errorterm2 >= ydiff2)
{ // if time to increment Y...
errorterm2-=ydiff2; // ...restore error term
offset2+=xunit2; // ...and advance offset to next pixel
xstart2+=xunit2;
} // end if

count2--;

// draw line from edge 1 to edge 2:

length=offset2-offset1; // determine length of horizontal line

if (length < 0)
{ // if negative...
length=-length; // ...make it positive
start=offset2; // and set START to edge 2
} // end if
else
start=offset1; // else set START to edge 1

for (int index=start; index < start+length+1; index++) // from edge to edge
{
vbuffer[index]=(UCHAR)poly->color; // ...draw the line
} // end for index

offset1+=mempitch; // advance edge 1 offset to next line
ystart1++;
offset2+=mempitch; // advance edge 2 offset to next line
ystart2++;

} // end while
} // end if
} // end if
else
{
if (xdiff2 > ydiff2)
{
// increment edge 1 on Y and edge 2 on X:

count1=ydiff1; // count for Y increment on edge 1
count2=xdiff2; // count for X increment on edge 2

while(count1 && count2)
{ // continue drawing until one edge is done
// calculate edge 1:

errorterm1+=xdiff1; // Increment error term

if (errorterm1 >= ydiff1)
{ // if time to increment Y...
errorterm1-=ydiff1; // ...restore error term
offset1+=xunit1; // ...and advance offset to next pixel
xstart1+=xunit1;
} // end if

count1--;
yndfcd 2003-10-16
  • 打赏
  • 举报
回复
void Draw_Filled_Polygon2D(POLYGON2D_PTR poly, UCHAR *vbuffer, int mempitch)
{
// this function draws a general n sided polygon

int ydiff1, ydiff2, // difference between starting x and ending x
xdiff1, xdiff2, // difference between starting y and ending y
start, // starting offset of line between edges
length, // distance from edge 1 to edge 2
errorterm1, errorterm2, // error terms for edges 1 & 2
offset1, offset2, // offset of current pixel in edges 1 & 2
count1, count2, // increment count for edges 1 & 2
xunit1, xunit2; // unit to advance x offset for edges 1 & 2

// initialize count of number of edges drawn:
int edgecount = poly->num_verts-1;

// determine which vertex is at top of polygon:

int firstvert=0; // start by assuming vertex 0 is at top

int min_y=poly->vlist[0].y; // find y coordinate of vertex 0

for (int index=1; index < poly->num_verts; index++)
{
// Search thru vertices
if ((poly->vlist[index].y) < min_y)
{
// is another vertex higher?
firstvert=index;
min_y=poly->vlist[index].y;
} // end if

} // end for index

// finding starting and ending vertices of first two edges:
int startvert1=firstvert; // get starting vertex of edge 1
int startvert2=firstvert; // get starting vertex of edge 2
int xstart1=poly->vlist[startvert1].x+poly->x0;
int ystart1=poly->vlist[startvert1].y+poly->y0;
int xstart2=poly->vlist[startvert2].x+poly->x0;
int ystart2=poly->vlist[startvert2].y+poly->y0;
int endvert1=startvert1-1; // get ending vertex of edge 1

if (endvert1 < 0)
endvert1=poly->num_verts-1; // check for wrap

int xend1=poly->vlist[endvert1].x+poly->x0; // get x & y coordinates
int yend1=poly->vlist[endvert1].y+poly->y0; // of ending vertices
int endvert2=startvert2+1; // get ending vertex of edge 2

if (endvert2==(poly->num_verts))
endvert2=0; // Check for wrap

int xend2=poly->vlist[endvert2].x+poly->x0; // get x & y coordinates
int yend2=poly->vlist[endvert2].y+poly->y0; // of ending vertices

// draw the polygon:

while (edgecount>0)
{
// continue drawing until all edges drawn
offset1=mempitch*ystart1+xstart1; // offset of edge 1
offset2=mempitch*ystart2+xstart2; // offset of edge 2

// initialize error terms
// for edges 1 & 2
errorterm1=0;
errorterm2=0;

// get absolute value of
if ((ydiff1=yend1-ystart1) < 0)
ydiff1=-ydiff1;

// x & y lengths of edges
if ((ydiff2=yend2-ystart2) < 0)
ydiff2=-ydiff2;

if ((xdiff1=xend1-xstart1) < 0)
{
// get value of length
xunit1=-1; // calculate X increment
xdiff1=-xdiff1;
} // end if
else
{
xunit1=1;
} // end else

if ((xdiff2=xend2-xstart2) < 0)
{
// Get value of length
xunit2=-1; // calculate X increment
xdiff2=-xdiff2;
} // end else
else
{
xunit2=1;
} // end else

// choose which of four routines to use
if (xdiff1 > ydiff1)
{
// if x length of edge 1 is greater than y length
if (xdiff2 > ydiff2)
{
// if X length of edge 2 is greater than y length

// increment edge 1 on X and edge 2 on X:
count1=xdiff1; // count for x increment on edge 1
count2=xdiff2; // count for x increment on edge 2

while (count1 && count2)
{
// continue drawing until one edge is done
// calculate edge 1:
while ((errorterm1 < xdiff1) && (count1 > 0))
{
// finished w/edge 1?
if (count1--)
{
// count down on edge 1
offset1+=xunit1; // increment pixel offset
xstart1+=xunit1;
} // end if

errorterm1+=ydiff1; // increment error term

if (errorterm1 < xdiff1)
{ // if not more than XDIFF
vbuffer[offset1]=(UCHAR)poly->color; // ...plot a pixel
} // end if

} // end while

errorterm1-=xdiff1; // if time to increment X, restore error term
yndfcd 2003-10-16
  • 打赏
  • 举报
回复
二种方法:
1。将多边分成若干个三角形,将每个三角形再分成小的有一边水平的三角形。然后分别推填充这些小三角形。

2。将多边的形的顶点从上到下,从左到右的方法排列,然后计算很每条边的斜率,然后境减相应的值。
jingqiang2008 2003-10-16
  • 打赏
  • 举报
回复
是不是书上讲的算法都能看到填充的过程?库函数用的是么方法呢?大家讨论一下。做这个程序是因为上边安排下来,要在LINUX上画图用的。
jingqiang2008 2003-10-16
  • 打赏
  • 举报
回复
把上面的程序在VC下试了一下,比较慢啊:(,比FillRgn()速度慢了很多,FillRgn是怎么做的啊。哪位高手请帮帮忙啊。
simclock 2003-10-16
  • 打赏
  • 举报
回复
带种子的扫描线填充?
SCUM 2003-10-15
  • 打赏
  • 举报
回复
以前在DOS下写图形库的时候用的是Y桶法
速度一般
别的方法没有真正试过
愿闻道
TianGuangZao 2003-10-15
  • 打赏
  • 举报
回复
学过电视机的一点原理,跟你讲的有点类似。
先给出你的算法,然后才能比较谁的更好。
jingqiang2008 2003-10-15
  • 打赏
  • 举报
回复
在线等待!!!

69,368

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧