高分求矢量图形的扫描线区域填充源程序!

allenhai1980 2003-10-21 11:41:54
谢谢各位大虾。
我在论坛中没有搜索到相关的合适源程序,又没时间自己写,
所以想要现成的,呵呵。
C++语言的。
allenhai@sina.com
...全文
153 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
tuxw 2003-12-25
  • 打赏
  • 举报
回复
void LineFill( CDC *pDC, const CRect& rc, int nFillMode, int nDis )
{
CPen pen( PS_SOLID, 0, RGB(255,0,0) ); // 测试用的填充颜色
CPen *pOldPen = pDC->SelectObject( &pen );

const COLORREF crText = RGB(0,0,0); // 已画好的字体颜色
COLORREF cr1, cr2;

if( nFillMode == 0 ) { // 水平填充
for( int row = rc.top; row < rc.bottom; row += nDis ) {
cr1 = pDC->GetPixel( rc.left+1, row );
for( int col = rc.left+2; col < rc.right; ++col ) {
cr2 = pDC->GetPixel( col, row );

if( cr1 != cr2 ) {
if( cr2 == crText )
pDC->MoveTo( col, row );
else if( cr1 == crText )
pDC->LineTo( col, row );
cr1 = cr2;
}
}
}
}
……

pDC->SelectObject( pOldPen );
}
allenhai1980 2003-10-27
  • 打赏
  • 举报
回复
Thanks zzuw very much.
我自己写吧,虽然耗时间!呵呵。
zzwu 2003-10-25
  • 打赏
  • 举报
回复
详细的算法描述见:
http://www.cs.uct.ac.za/courses/CS300W/IG/2003/handouts/scanlineHandout.pdf
zzwu 2003-10-25
  • 打赏
  • 举报
回复
allenhai1980(心蓝世界) :
程序写起来确实很麻烦,要自己从头开始编确实需要许多时间和精力。我估计这里参与讨论的人中做过这样工作的人不一定有,除了我之外,我以前也是因LSI设计工作的需要才做的。
不过,到网上再搜索一下看,说不定会有。
allenhai1980 2003-10-24
  • 打赏
  • 举报
回复
呵呵,想不到,我所要的算法就是zzwu(未名)所说的“桶算法”!
zzwu(未名)给出的四步很粗糙。
算法思想不难,当同时对很多多边形填充时,程序写起来很麻烦。
所以我想请各位提供一些类似的程序,不情之请啊!
allenhai1980 2003-10-24
  • 打赏
  • 举报
回复
大家帮忙啦!
zzwu 2003-10-24
  • 打赏
  • 举报
回复
“桶算法”就是老老实实地对封闭多边形进行由上到下的水平线填充,为此要做的工作大体为:

1.先对多边形的边,按y投影的大小重新排序,设y范围为[ymin,ymax]
2.求水平线hl[y]和多边形的边的交,p[y,1],p[y,2],p[y,3]...,y属于[ymin,ymax]
3.对交点按x大小排序,q[y,1]<q[y,2]<q[y,3]<q[y,4]<....
4.则要填的扫描线就是,q[y,1]-q[y,2],q[y,3]-q[y,4],....

由于桶算法是从上到下依次填充的,所以用不到进出堆栈的操作;同时,因相邻水平线一般都是和多边形的同一些边求交,所以多边形边与y高度水平线的交点可利用与y-1的交点算出(类似bresenham算法),从而速度是快的。

麻烦的是:从上到下求水平线交点时,要控制多边形的边的改变,另外要考察各种特例交点。



zzwu 2003-10-22
  • 打赏
  • 举报
回复
以上算法从速度来看并不高,要考虑速度,应使用“桶算法”,但编写程序较繁了。
alphapaopao 2003-10-22
  • 打赏
  • 举报
回复
不错不错
Freshyy 2003-10-22
  • 打赏
  • 举报
回复
To zzwu(未名) :
“桶算法”的原理能大致介绍一下吗?谢谢!
Freshyy 2003-10-22
  • 打赏
  • 举报
回复
不是一个版块!
积分不一样的!
allenhai1980 2003-10-22
  • 打赏
  • 举报
回复
To alphapaopao(炮炮):
你不是有很多星的么,咋整的?
allenhai1980 2003-10-22
  • 打赏
  • 举报
回复
谢谢zzwu(未名)提供的程序。

我没有说清意图:我并不是想对任意区域填充,我的操作对象是多个多边形,填充也只是一种理解,我本想拿水平直线与所有的封闭多边形求交从而依次得到水平交点,从而将由边描述的矢量多边形转化成由很多水平直线构成的一个多边形区域,水平直线的密度当然不可能很大,种子填充是一种方式,但不好用水平直线的端点来表述。

另外,如果图形太大且很多,会不会发生递归的堆栈溢出?所以我想直接运算。效率很差,呵呵。如果能提供一些较好的直接拿水平直线填充多边形的算法程序,就太好了。

To yalinliu(亚林) :我知道有,谢谢提示。
zzwu 2003-10-21
  • 打赏
  • 举报
回复
我用pascal编过扫描线算法区域填充程序,但未用C++编过这样的程序。

以下是从网上找到的C++区域填充程序,注意,扫描线算法可以有多种类型,这里只是一种,是否适合你的,要检查:

 
区域填充的扫描线算法:

区域填充的递归算法原理和程序都很简单,但由于多次递归,费时、费内存,效率不高。为了减少递归次数,提高效率可以采用扫描线算法。算法的基本过程如下:当给定种子点(x,y)时,首先填充种子点所在扫描线上的位于给定区域的一个区段,然后确定与这一区段相连通的上、下两条扫描线上位于给定区域内的区段,并依次保存下来。反复这个过程,直到填充结束。

区域填充的扫描线算法可由下列四个步骤实现:

(1)初始化:堆栈置空。将种子点(x,y)入栈。

(2)出栈:若栈空则结束。否则取栈顶元素(x,y),以y作为当前扫描线。

(3)填充并确定种子点所在区段:从种子点(x,y)出发,沿当前扫描线向左、右两个方向填充,直到边界。分别标记区段的左、右端点坐标为xl和xr。

(4)并确定新的种子点:在区间[xl,xr]中检查与当前扫描线y上、下相邻的两条扫描线上的象素。若存在非边界、未填充的象素,则把每一区间的最右象素作为种子点压入堆栈,返回第(2)步。

区域填充的扫描线算法:

typedef struct{ //记录种子点

intx;

int y;

} Seed;

void ScanLineFill4(int x,int y,COLORREF oldcolor,COLORREF newcolor)

{ int xl,xr,i;

bool spanNeedFill;

Seed pt;

setstackempty();

pt.x =x; pt.y=y;

stackpush(pt); //将前面生成的区段压入堆栈

while(!isstackempty())

{ pt = stackpop();

y=pt.y;

x=pt.x;

while(getpixel(x,y)==oldcolor) //向右填充

{ drawpixel(x,y,newcolor);

x++;

}

xr = x-1;

x = pt.x-1;

while(getpixel(x,y)==oldcolor) //向左填充

{ drawpixel(x,y,newcolor);

x--;

}

xl = x+1;

//处理上面一条扫描线

x = xl;

y = y+1;

while(x<xr)

{ spanNeedFill=FALSE;

while(getpixel(x,y)==oldcolor)

{ spanNeedFill=TRUE;

x++;

}

if(spanNeedFill)

{ pt.x=x-1;pt.y=y;

stackpush(pt);

spanNeedFill=FALSE;

}

while(getpixel(x,y)!=oldcolor && x<xr) x++;

}//End of while(i<xr)

//处理下面一条扫描线,代码与处理上面一条扫描线类似

x = xl;

y = y-2;

while(x<xr)

{ ....

}//End of while(i<xr)

}//End of while(!isstackempty())

}
yalinliu 2003-10-21
  • 打赏
  • 举报
回复
计算机图形学上有类似的算法!
浅析GIS大数据 作者:尤文辰 徐跃通 高尚 来源:《电脑知识与技术》2013年第24期 摘要:随着地理信息数据的迅速增加,GIS数据呈现出数据量大、数据种类多和 数据结构复杂的特点。该文从大数据的角度对GIS数据呈现的三个特征进行了具体的分析 ,并在此基础上提出GIS大数据存储和处理的新的要。最后介绍了MongoDB这一NoSQL数 据库的特性,简要分析了利用MongoDB数据库的特性来解决GIS大数据问题的方法,并简 单地借助于python语言用mongoDB对ESRI Shapefiles进行了存储。 关键词:GIS;大数据;mongoDB;python;开源GIS 中图分类号:TP208;TP392 文献标识码:A 文章编号:1009- 3044(2013)24-5399-04 1 概述 随着人类对客观世界认知的提高与技术水平的不断进步,所获取的描述客观世 界的数据呈爆炸式增长,大数据已经成为了Google、亚马逊等大公司的竞争资本,通过 大数据的有效利用和深入分析,可以挖掘巨大的商业价值和社会价值。根据维基百科[1 ]的定义,大数据是由巨大且复杂的数据集组成的集合,且这些数据集因其巨大和复杂而 难以用现有的数据库管理工具和传统的数据处理程序来进行处理。近些年我国开展的土 地调查、数字城市建设等项目,取得了丰硕的成果,收集了大量的测绘数据和自然、人 文数据,在今后大力开展的测绘工作中,还将获得更加丰富的地理信息数据,与此同时 ,如何有效地存储、管理和利用这些地理信息数据成为需要解决的问题。 2 GIS的定义 GIS(Geographic Information System)是地理信息系统的简称。陈述彭认为地理信息系统是以定位数据库为基础,具 有多层次数据结构,多功能分析能力的空间型信息系统[2],李德仁从多级格网理论[3] 的角度出发,认为GIS数据存储的式为不同尺度的空间数据库[4]。综上所述,GIS是以 计算机软硬件为基础,结合地理学、测绘学、地图学、计算机科学、运筹学等多门学科 的,以获取、存储、管理、展示、分析地理空间数据为主的计算机系统,可以用于区域 规划、决策分析等。 3 GIS数据的特征 从定义可看出,数据是GIS的血液。从通过图件扫描、格式转换、实地测绘等方 法的数据获取,到采用各种先进数据库技术对数据进行存储、管理,再到利用计算机图 学、地图学等综合可视化技术对数据进行展示,以及最终以数据为基础的借助于计量 地理学、拓扑学、图论等学科的决策分析等,这些过程都是以数据为核心的。随着GIS的 发展,其数据呈现出数量大、种类多和结构复杂的特征。 3.1 数量大 GIS的数据量大具有两层含义,第一层含义是指数据占用的字节数多,这主要是 针对栅格数据及多媒体数据而言的。比如"天地图"在2011年正式上线的时候,集成了海 量的基础地理信息资源数据[5],总数据量约有30TB,处理后的瓦片数近30亿。资源三号 测绘卫星是中国第一颗民用高分辨率光学传输型测绘卫星[6],截止到2013年6月底,在 运行的不到一年半的时间中,总共存档卫星影像37万多景,数据量达到249TB。而GIS空 间数据产生的商业价值每年正以15.5%的速度增加,是GIS软件和服务的两倍[7]。GIS数 据量大的第二层含义是指数据单位个数多。比如"天地图"各类地名和POI(Point of Interest,兴趣点)有1100多万条, 2011年8月竣工的国家西部1 50000地图空白区测图工程和国家1 50000基础地理信息数 据库更新工程两个国家级重大测绘工程[8],成果有20多万航片和8000多景卫星遥感影像 ,地名近600万条,描绘了1.4亿个地理要素。另外,其他专业领域比如土壤数据、气象 数据在全数据模式下[9]数量也是非常可观的。 3.2 数据种类多 GIS的数据种类多样,从大的方面看,具有矢量数据、栅格数据、属性数据,以 及与地理位置相关的音频、视频等多媒体数据等;而从小的角度看,主要是因为数据来 源广泛和不同应用的需而体现为数据格式多样,这里我们主要从数据格式多样来看GI S数据种类多。比如测绘方式产生的dxf数据,经常需要导入到GIS系统中,其他的还有扫 描得到的tiff或jpeg图像,具有空间坐标信息的GeoTIFF文件,数字制图中数字化后的E SRI shapefiles数据或MapInfo的TAB数据,格式转换后用于web的png、SVG或GeoJson数据等 。资源三号卫星TLC(三线阵相机)标准产品中的1A级产品(预处理级辐射校正影像产品 )包括的文件格式就有tiff、rpb、xml、jpeg等四种格式的15个文件。GDAL/OGR是地理 空间数据转换的类库,多用来读取地理空间数据,根据GDAL官方网站的资料

4,445

社区成员

发帖
与我相关
我的任务
社区描述
图形图像/机器视觉
社区管理员
  • 机器视觉
  • 迪菲赫尔曼
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧