图形学扫描线填充算法

本文记录了学习图形学时关于扫描线填充算法的理解和实践过程。算法通过与图形相交的边进行填充,利用链表结构节省存储空间,并详细描述了初始化活动边表和绘制填充的步骤,包括删除与扫描线平行的边,以及按顺序划线的逻辑。文章还提及使用EasyX库来实现代码。
摘要由CSDN通过智能技术生成

  在上图形学课的时候,学习了扫描线填充算法。不过在完成实验的时候在真正理解了该算法,在此记录一下,如果有表达上的错误,欢迎指正!

扫描线填充算法通过在与图形相交的第(1,2)、(3,4)... 边之间划线不断不断填充图形。因此,在扫描时就需要确定什么时候与图形的某条边相交、划线的时候x的范围是多少以及划线时是从哪个交点画至另一个交点。

结构体如下所示:


为了节省存储的空间,边表项也使用链表结构,将图形中ymin值相同的边链接在同一个边表项后,这样在扫描的时候方便添加。

具体的流程如下:

一、初始化活动边表

         1. 统计并初始化表项

         2. 将每条边分别链接在表项后

二、 绘制与填充

          1. 取出当前与扫描线相交的边

               ① 取出ymin 大于当前扫描线的y值的边

               ② 删除ymax 小于等于当前扫描线的边(①②过程可以排除掉与扫描线平行的边)

          2. 将取出的边按照左右顺序排序(根据边的最低点的坐标与直线的斜率判断)

          3. 划线并直接在原结构上修改边的x值(因为是在一个函数内,修改保存的值仅限于函数内,并不影响main函数中的值)

具体的代码如下所示,使用的库是EasyX(可以在http://www.easyx.cn/下载):

#include "graphics.h"
#include "stdio.h"
#include "conio.h"
#include <stdlib.h>
#include <math.h>
#include <cmath>
#include <iostream>

using namespace std;
#define MAX_VOL 20
//多边形的边的数据结构
typedef struct Edge
{
	int y_max, y_min;	//该有向边的y坐标的最大值与最小值
	double x, deltax;	//该有向边的x的最小值以及x的变化的量(1/斜率)
	struct Edge* next;	//指向下一条边的指针

}Edge;
//活动边表表项
typedef struct TableItem
{
	int curr_y;			//该表项的y坐标值 ymin
	Edge *firstNode;	//该表项的首个节点,如果没有,NULL
	struct TableItem *next;	//指向下一个活动边表表项的指针
}TableItem;
//活动边表结构体
typedef struct Table
{
	TableItem *itemHeader;	//活动边表的表项header
	int item_count;		//活动边表表项的个数
}ET;

class Point
{
private:
	int x1, x2, y1, y2;
public:
	Point(int x1, int y1, int x2, int y2)
	{
		this->x1 = x1;
		this->x2 = x2;
		this->y1 = y1;
		this->y2 = y2;
	}
	//返回两个点之中的ymax
	int YMax()
	{
		return (y1 > y2 ? y1 : y2);
	}
	//返回ymin
	int YMin()
	{
		return (y1 < y2 ? y1 : y2);
	}
	//返回ymin 端点的x 值
	int x()
	{
		return (y1 < y2 ? x1 : x2);
	}
	//返回直线的斜率,按照传入的参数的顺序
	double KOfLine()
	{
		return ((y2 - y1)*1.0 / (x2 - x1));
	}

};

class Solution
{
public:
	//根据多边形初始化活动表
	//参数 T 活动边表
	//参数edges 用于初始化的边数组
	//参数 edge_num  用于初始化的边的个数
	void Init(ET &T, Edge *edges, int edge_num)
	{
		//初始化活动边表结构体
		T.item_count = 0;
		T.itemHeader = NULL;
		int ymins[20];		//存储ymin ,决定活动边表的个数以
  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值