c实现的扫描线算法

今天突然发现自己csdn的草稿箱中有几篇以前写过的文章,发出来与大家分享!


/*

* =====================================================================================

*

* Filename: FillPolygon.c

*

* Description: comments

*

* Version: 1.0

* Created: 08/17/2010 08:43:12 PM

* Revision: none

* Compiler: gcc

*

* Author: dylan (comments), [email protected]

* Company: University of Technology and Science of China

*

* =====================================================================================

*/

#include <stdio.h>

typedef struct _Edge

{

int x;

float dx;

int ymax;

struct _Edge *next;

}Edge;

typedef struct _Point

{

int x;

int y;

}Point;

static Edge *edges[480], *active;

void InsertEdge(Edge *list, Edge *edge)

{

Edge *p, *q = list;

p = q->next;

while(p != NULL)

{

if(edge->x < p->x)

p = NULL;

else

{

q = p;

p = p->next;

}

}

edge->next = q->next;

q->next = edge;

}

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 = lower.x;

if(upper.y < yComp)

edge->ymax = upper.y - 1;

else

edge->ymax = upper.y;

InsertEdge(edges[lower.y],edge);

}

int yNext(int k, int num, Point *pts)

{

int j;

if((k + 1) > (num - 1))

j = 0;

else

j = k + 1;

while(pts[k].y == pts[j].y)

if((j + 1) > (num - 1))

j = 0;

else

++j;

return (pts[j].y);

}

void BuildEdgeList(Point *pts, int num, Edge *edges[])

{

Edge *edge;

Point v1,v2;

int i, yPrev = pts[num-2].y;

v1.x = pts[num-1].x;

v1.y = pts[num-1].y;

for( i = 0; i < num; ++i)

{

v2 = pts[i];

if(v1.y != v2.y)

{

edge = (Edge *)malloc(sizeof(Edge));

edge = (Edge *)malloc(sizeof(Edge));

if(v1.y < v2.y)

MakeEdgeRec(v1,v2,yNext(i,num,pts),edge,edges);

else

MakeEdgeRec(v2,v1,yPrev,edge,edges);

}

yPrev = v1.y;

v1 = v2;

}

}

void BuildActiveList(int scan, Edge *active, Edge *edge[])

{

Edge *p, *q;

p = edges[scan]->next;

while(p)

{

q = p->next;

InsertEdge(active, p);

p = q;

}

}

void FillScan(int scan, Edge *active)

{

Edge *p1, *p2;

int i;

p1 = active->next;

while(p1)

{

p2 = p1->next;

for( i = p1->x; i < p2->x; ++i)

printf(".");

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 ScanLineFillPolygon(Point *pts, int num)

{

int i,scan,scanmax=0,scanmin = 480;

/* 扫描线的边界*/

for( i = 0; i < num -1; ++i)

{

if(pts[i].y > scanmax)

scanmax = pts[i].y;

if(pts[i].y < scanmin)

scanmin = pts[i].y;

}

/* 初始化边表*/

for( scan = scanmin; scan < scanmax; ++scan )

{

edges[scan] = (Edge *) malloc(sizeof(Edge));

edges[scan]->next = NULL;

}

BuildEdgeList(pts,num,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);

UpdateActiveList(scan,active);

ResortActiveList(active);

}

}

}

int main()

{

Point pts[] = {{100,40},{220,140},{280,80},{350,300},

{200,380},{50,280},{100,40},};

int num = sizeof(pts)/sizeof(Point);

//initgraph(&gdriver, &gmode, "");

ScanLineFillPolygon(pts,num);

return 0;

}

你可能感兴趣的:(算法)