基于coocs2d-x quick 的图形填充

来源:互联网 发布:制作蹭饭地图软件 编辑:程序博客网 时间:2024/05/17 02:19

参考:http://blog.csdn.net/orbit/article/details/7323090


先上图一发:


如图效果实现,用了两种算法:

1.递归种子填充算法

分为4联通算法和8联通算法,这里使用4联通算法

开始时先从c++底层调用图片解析出png图片每个像素的alpha值,然后用"_"连接起来,变成一个string,传递到Lua,然后做逻辑处理即可


--图片相对于屏幕原点左下角的偏移量
local off_x,off_y
--从每个点开始延伸的四个方向
ColorLayer.direction4 = {
{x=-1,y=0},
{x=0,y=1},
{x=1,y=0},
{x=0,y=-1}
}


--核心算法

--种子填充算法
function ColorLayer:FloodSeedFill(x,y)
--检查触摸点是否是图片的图形区域
if not self:isBorder(x-off_x, y-off_y) then 

--检查当前点的透明度
if self:getPixelAlpha(x-off_x,y-off_y) == 0 then
--修改当前点的像素信息,避免进入死循环
self:setPixelAlpha(x- off_x, y-off_y,-1)

--在当前点画点
self:drawPoint(x, y)

--朝四个方向进行递归
for i=1,table.nums(ColorLayer.direction4) do
self:FloodSeedFill(x+ColorLayer.direction4[i].x,y+ColorLayer.direction4[i].y)
end
end
end

end


2.扫描线种子填充算法

递归种子填充算法虽然简单,但是使用了大量递归算法,需要大量的栈空间来存储相连的点,效率特别低,会有明显的卡顿现象,所以不得已只好换另一种算法。

--存储种子
local curSeed = 0
local seedT = {}
--直线扫描算法
function ColorLayer:LineSeedFill(x,y)

--检查边界
if not self:isBorder(x-off_x, y-off_y) then 

--检查种子
while seedT[curSeed+1] do

--扫描种子左边
self:seekLineLeft(seedT[curSeed+1][1], seedT[curSeed+1][2],0,-1,true) 

--扫描种子右边
self:seekLineRight(seedT[curSeed+1][1]+1, seedT[curSeed+1][2],0,-1,true) 

--在种子的上下两行寻找新的种子
self:seekLineNewSeed(left,right,seedT[curSeed+1][2]-1,0)
self:seekLineNewSeed(left,right,seedT[curSeed+1][2]+1,0)

--下一个种子
curSeed = curSeed + 1
end
end
end


--寻找新的种子点
function ColorLayer:seekLineNewSeed(left,right,y,value)
local temp_x = left
local isFindNewSeed = false
while temp_x <= right do
isFindNewSeed = false
while  self:getPixelAlpha(temp_x-off_x,y-off_y) == value and temp_x < right do
isFindNewSeed = true
temp_x = temp_x + 1
end
if isFindNewSeed then
if self:getPixelAlpha(temp_x-off_x,y-off_y) == value and temp_x == right then
table.insert(seedT, {temp_x,y})
else
table.insert(seedT, {temp_x-1,y})
end
end

temp_x = temp_x + 1
end
end

0 0
原创粉丝点击