前言:
书本上用的是链表的方法,由于感觉链表太乱了,担心代码不清晰,就用了结构体的方法。 我的方法和书上的不太一样,只能说是自己根据书本修改的代码,可能有些错误,希望老师能够提出。
我在算法中初始了一个结构体名为pNET[1024]的数组用来存贮书上的ET边表,其中结构体中有xmin(线段下端点的x坐标),ymax(线段上端点的y坐标),ymin(线段下端点的y坐标),dx(斜率的倒数)ps:(至于我这里为什么相对于书本上多加了一个ymin,是为了在扫描线扫描的时候直接判断扫描线是否在ymax和ymin之间).
我在为pNET[1024]数组赋初值的时候就判断某顶点是否为局部最大或最小来使是否ymin+1.
然后用for循环从所有y坐标的最小值开始扫描至最大y坐标。
因为在上面已经判断了某顶点是否为局部最大值,所以某条扫描线下的x坐标个数一定是偶数,
只要对坐标排序,相邻的两个为一组进行填充像素就好了。
至于画图,同样是安装了easyx的vc6.0,使用graphics.h头文件下的putpixel(x,y,color)函数画像素点,其中(x,y)是像素坐标,color是需要画的颜色。通过画像素点实现画出这个图形。由于initgraph(x,y)只能初始一个左上角坐标为(0,0)x轴向右,y轴向下的绘图屏幕,所以请确保所有的坐标都>=0.具体请看源代码
源代码:
源代码: #include <graphics.h> #include <conio.h> #include <stdio.h> #include <string.h> #include <queue> #include <windows.h> using namespace std; struct XET { float xmin,ymax,ymin,dx; }pNET[1024]; //N个顶点的坐标 struct node { float x,y; }point[1024]; //画图 drawColor(float a,float b,int y) { int x; for(x=a+0.5;x<=b+0.5;x++) putpixel(x,y,RED); //可以把下面这句取消注释,按回车看画线过程。 // system("pause"); } //优先队列保存某条扫描线上的x值 priority_queue<float,vector<float>,greater<float> >s; int main() { //i,j为for循环用到的,t为pNET[]数组的下标 int i,j,t=0,N; //min_y为所有顶点y坐标的最小值,max_y为所有顶点y坐标的最大值 int min_y=0x3fffffff,max_y=-1; printf("请输入顶点数N=:"); scanf("%d",&N); printf("请按逆时针输入N个顶点的坐标(用空格分开)\n"); for(i=0;i<N;i++) { scanf("%f %f",&point[i].x,&point[i].y); //查找所有顶点y坐标的最值 if(point[i].y>max_y) max_y=point[i].y; if(point[i].y<min_y) min_y=point[i].y; } for(i=min_y;i<=max_y;i++) { for(j=0;j<N;j++) { if(point[j].y==i) { //按逆时针,某顶点的前一个顶点 if(point[(j-1+N)%N].y>point[j].y) { struct XET p; p.xmin=point[j].x; p.ymax=point[(j-1+N)%N].y; p.ymin=point[j].y; p.dx=(point[(j-1+N)%N].x-point[j].x)/(point[(j-1+N)%N].y-point[j].y); //判断是否为局部最值 if(point[(j+1+N)%N].y<=point[j].y) p.ymin++; pNET[t++]=p; } //按逆时针,某顶点的后一个顶点 if(point[(j+1+N)%N].y>point[j].y) { struct XET p; p.xmin=point[j].x; p.ymax=point[(j+1+N)%N].y; p.ymin=point[j].y; p.dx=(point[(j+1+N)%N].x-point[j].x)/(point[(j+1+N)%N].y-point[j].y); //判断是否为局部最值 if(point[(j-1+N)%N].y<=point[j].y) p.ymin++; pNET[t++]=p; } } } } initgraph(480,480); //所有扫描线进行扫描 for(i=min_y;i<=max_y;i++) { for(j=0;j<t;j++) { //当前扫描线在某条边之间 if(pNET[j].ymin<=i&&pNET[j].ymax>=i) { s.push(pNET[j].xmin); //更新xmin坐标 pNET[j].xmin+=pNET[j].dx; } } while(!s.empty()) { //每两个一对,a,b均为扫描线上的x坐标 float a=s.top();s.pop(); float b=s.top();s.pop(); drawColor(a,b,i); } } getch(); closegraph(); return 0; }
测试数据:N=4顶点坐标
0,0,0,100,100,100,100,0
测试数据 :N=6 顶点坐标
70,10,20,30,20,90,70,70,130,110,130,50
测试数据:
顶点数N=4定点坐标:100,100,200,100,250,180,50,180
运行结果
顶点数N=10顶点坐标 : 100 200 122 131 195 131 136 88 159 19 100 62 41 19 64 88 5 131 78 131