当我们用顶点记录多边形时,对于直线的绘制和前面的图形无异,但当填充颜色的时候,我们并不能直接获得要填充的区域的起点和终点,这时通常采用扫描线算法。
多边形区域填充的时候,每一行与多边形边的交点很容易获得,问题在于当在一行获得多个交点时,如果判断相邻点对是在多边形内还是多边形外。对于每一行,我们在多边形外引一条水平的射线,这条射线必然与多边形有偶数个交点,因为多边形的大小是有限的,射线进入多边形内部后必然还要再出多边形,进和出的次数一定相等,这样,对所有交点排序后,每两个相邻的点对都对应多边形内部要填充的一段区域。
接下来要考虑的是边界条件。我们引出的是水平的射线,当多边形的一条边水平时,我们要考虑它两侧不水平的边的位置。如果两侧的不水平边分居水平边的两侧,则射线有进或出的过程,随便记录水平边的一个端点即可;如果两侧的不水平边在水平边的同侧,则射线不会进出多边形,无需记录端点。
当射线的交点是多边形的顶点时,同样考虑顶点两侧的边是否在同一侧,如果不在同一侧则记录,在同一侧则不记录。由于顶点和水平线可能重复,要注意考虑判断条件,不能重复记录。
基本代码:
draw_polygon.h
#ifndef DRAW_POLYGON_H_INCLUDED
#define DRAW_POLYGON_H_INCLUDED
#include "define.h"
#include "draw_point.h"
#include "draw_line.h"
#define POLYGON_MAX_POINT 100
typedef struct Polygon_xi
{
int32 x[POLYGON_MAX_POINT];
int32 y[POLYGON_MAX_POINT];
int32 pointNumber;
int32 isFinished;
}Polygon_xi;
void draw_polygon_T_xi(Polygon_xi polygon);
#endif // DRAW_POLYGON_H_INCLUDED
draw_polygon.c
#include "draw_polygon.h"
void draw_polygon_T_xi(Polygon_xi polygon)
{
int32 i, j, k, a, b;
int32 max_x, min_x;
int32 max_y, min_y;
int32 temp;
int32 set[1024];
int32 setNumber;
int16 isHorizon[POLYGON_MAX_POINT];
if(polygon.isFinished)
{
max_x = max_y = - (1 << 30);
min_x = min_y = 1 << 30;
for(i=0;i<polygon.pointNumber;++i)
{
max_x = max(max_x, polygon.x[i]);
min_x = min(min_x, polygon.x[i]);
max_y = max(max_y, polygon.y[i]);
min_y = min(min_y, polygon.y[i]);
}
polygon.x[polygon.pointNumber] = polygon.x[0];
polygon.y[polygon.pointNumber] = polygon.y[0];
polygon.x[polygon.pointNumber+1] = polygon.x[1];
polygon.y[polygon.pointNumber+1] = polygon.y[1];
for(i=1;i<=polygon.pointNumber+1;++i)
{
isHorizon[i] = (polygon.y[i] == polygon.y[i-1]);
}
isHorizon[0] = (polygon.y[0] == polygon.y[polygon.pointNumber - 1]);
for(i=min_y;i<max_y;++i)
{
setNumber = 0;
for(j=1;j<=polygon.pointNumber;++j)
{
if(i == polygon.y[j] && isHorizon[j])
{
temp = 1;
k = j + 1;
while(polygon.y[k] == polygon.y[j])
{
if(++k == j)
{
temp = 0;
break;
}
if(k >= polygon.pointNumber)
{
k -= polygon.pointNumber;
}
}
a = k;
b = j - 2;
if(b <= 0)
{
b += polygon.pointNumber;
}
if(((polygon.y[a] > polygon.y[j] && polygon.y[b] < polygon.y[j]) ||
(polygon.y[a] < polygon.y[j] && polygon.y[b] > polygon.y[j])) && temp)
{
set[setNumber++] = polygon.x[j];
}
}
}
for(j=1;j<=polygon.pointNumber;++j)
{
if(i == polygon.y[j])
{
if(isHorizon[j] || isHorizon[j+1])
{
continue;
}
if((polygon.y[j-1] > polygon.y[j] && polygon.y[j+1] < polygon.y[j]) ||
(polygon.y[j-1] < polygon.y[j] && polygon.y[j+1] > polygon.y[j]))
{
set[setNumber++] = polygon.x[j];
}
}
}
for(j=1;j<=polygon.pointNumber;++j)
{
if(i > min(polygon.y[j], polygon.y[j-1]) &&
i < max(polygon.y[j], polygon.y[j-1]))
{
temp = 1.0 * (i - polygon.y[j-1]) / (polygon.y[j] - polygon.y[j-1]) *
(polygon.x[j] - polygon.x[j-1]) + polygon.x[j-1];
if(temp >= min(polygon.x[j], polygon.x[j-1]) &&
temp <= max(polygon.x[j], polygon.x[j-1]))
{
set[setNumber++] = temp;
}
}
}
for(j=0;j<setNumber;++j)
{
for(k=j+1;k<setNumber;++k)
{
if(set[j] > set[k])
{
swap(set[j], set[k]);
}
}
}
for(j=0;j<setNumber-1;j+=2)
{
for(k=set[j];k<=set[j+1];++k)
{
draw_point_brush_2i(k, i);
}
}
}
for(i=1;i<=polygon.pointNumber;++i)
{
draw_line_4i(polygon.x[i-1], polygon.y[i-1], polygon.x[i], polygon.y[i]);
}
}
else
{
for(i=1;i<polygon.pointNumber;++i)
{
draw_line_4i(polygon.x[i-1], polygon.y[i-1], polygon.x[i], polygon.y[i]);
}
draw_line_4i(polygon.x[polygon.pointNumber],
polygon.y[polygon.pointNumber],
polygon.x[polygon.pointNumber - 1],
polygon.y[polygon.pointNumber - 1]);
}
}
分享到:
相关推荐
记录计图上机-图形填充
2020--SDUWH--计算机图形学实验 共20个实验 实验1 直线的绘制 实验2 直线的DDA生成算法 实验3 直线中点生成算法 实验4 直线Bresenham生成算法 实验5 中点画圆算法 实验6 中点画椭圆算法 实验7 多边形有序边表算法 ...
资源内容:透过鼠标获取多边形顶点绘制多边形,通过预先设定好的个顶点颜色,实现过度填充 语言:C++ 运行环境:Visual Studio 2013/更高版本
这是计算机图形学课程中的一个练习题,鼠标点击绘制多边形,绘制完成后用算法对多边形进行填充。这是我自己实现的源代码。
1.1计算机图形学及其相关概念 1.2计算机图形学的发展 1.2.1计算机图形学学科的发展 1.2.2图形硬件设备的发展 1.2.3图形软件的发展 1.3计算机图形学的应用 1.3.1计算机辅助设计与制造 1.3.2计算机辅助...
计算机图形学作业-基于C++实现MFC程序源码+项目说明.zip 【资源介绍】 MFC程序实现: 1.基本图形绘制: Bresenham、DDA、改进的Bresenham、系统库函数四种方法画直线, Bresenham画圆,Bresenham画椭圆,绘制矩形,...
图形学大作业----内容 一、主菜单的菜单项 基本图形绘制、图形变换、自由曲线绘制、图形裁剪、图形填充 二、二级子菜单(基本图形绘制) 1.直线绘制: 1)Bresenham绘制直线 2)DDA绘制直线 3)改进的Bresenham绘制...
计算机图形学多边形边缘填充算法 设计 包含源程序 和实验报告
计算机图形学作业:用采用活性边表的有序边表算法法填充多边形区域 多边形节点:P1(20,15)P2(30,17)P3(40,16)P4(45,14) 四节点依次连接J2EE实验:多线程并发顺序查找定义并创建1个100000个元素的整型数组...
计算机图形学大作业: 一、主菜单的菜单项 基本图形绘制、图形变换、自由曲线绘制、图形裁剪或图形填充 二、二级子菜单基本图形绘制 1.直线绘制: 1)Bresenham绘制直线 2)DDA绘制直线 3)改进的Bresenham...
基于种子的区域填充采用4连通区域的递归种子填充算法,或扫描线种子填充算法,要求种子点(x,y)可交互输入)。三、线段裁剪和多边形裁剪算法的动画演示实现。(两种线段裁剪算法和H-S多边形逐边裁剪算法)多边形裁剪...
用鼠标在屏幕上绘制任意顶点数的封闭多边形并填充,填充效果如下图所示。编程要求:⑴多边形的顶点数不受限制; ⑵按下鼠标左键,拖动鼠标绘制多边形,同时按下Shift键可以绘制水平边或垂直边; ⑶单击鼠标右键闭合...
1. 用DDA算法实现点绘制直线。 2. 用直线扫描法填充绘制所画多边形,并实现交互(鼠标左键点击绘制多边形,右键填充)。
计算机图形学教学大纲---实验教程《计算机图形学》实验教学大纲 1 实验一 C程序绘图基础 3 实验二 直线、圆弧及曲线的生成算法 15 实验三 Bezier曲线和样条曲线的生成算法 24 实验四 二维图形的几何变换 33 实验五 ...
计算机图形学基础程序,绘制多边形扫描线填充
代码是基于OpenGL的控制台程序,用C++编写,下载后直接复制到工程项目中即可运行,适合初学者学习。
利用QT实现多边形的填充算法,在网格下坐标系下,双击两下鼠标显示起点,之后点击依次连线,一共七条线,首尾要在同一个坐标才能实现功能。
自己写的大作业,包含多边形的绘制、填充、几何变换(移动、旋转、缩放、反射),可供参考
2. 采用VC++提供的绘图函数实现多义线、矩形、多边形的绘制; 3. 了解区域填充的实现过程。 实验环境 1.硬件环境:PC机 2.软件环境: Windows 环境、VC++编程 实验内容 1.实现Bresenham直线生成算法和DDA方法绘制...
几何图形扫描线算法, 通过用鼠标依次点击获取顶点来绘制多边形 点击绘制按钮即可绘制 代码有充分的注释说明 区域填充, (类似系统自带画图软件) 用油漆桶工具可以任意填充一个区域 使用扫描线算法