计算机图形学:多边形的扫描转换算法(有详细代码)

前言:

书本上用的是链表的方法,由于感觉链表太乱了,担心代码不清晰,就用了结构体的方法。 我的方法和书上的不太一样,只能说是自己根据书本修改的代码,可能有些错误,希望老师能够提出。

我在算法中初始了一个结构体名为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

运行结果:计算机图形学:多边形的扫描转换算法(有详细代码)_第1张图片

测试数据 :N=6 顶点坐标

70,10,20,30,20,90,70,70,130,110,130,50

运行结果计算机图形学:多边形的扫描转换算法(有详细代码)_第2张图片

测试数据:

顶点数N=4定点坐标:100,100,200,100,250,180,50,180

运行结果

计算机图形学:多边形的扫描转换算法(有详细代码)_第3张图片

顶点数N=10顶点坐标 : 100 200 122 131 195 131 136 88 159 19 100 62 41 19 64 88 5 131 78 131

运行结果:计算机图形学:多边形的扫描转换算法(有详细代码)_第4张图片



你可能感兴趣的:(扫描线,多边形的扫描转换算法)