"铲斗填充”;Javascript或coffeescript中的算法
"Bucket Fill" algorithm in Javascript or coffeescript
我正在写一个小的coffeescript/js应用程序,它允许用户设计图标(16x16像素或32X32像素)。图标实际上是一个带有颜色单元格的二维数组。单元格可以有颜色,也可以为空。
我希望用户能够用"桶式绘制"工具填充空白单元格。
这意味着
-
如果用户单击一个空白单元格,则单击的单元格旁边的所有空白单元格都将填充所选的颜色,直到达到彩色单元格
-
如果用户单击彩色单元格,则会填充单击单元格旁边的所有共享相同颜色的单元格,但不会填充空白单元格或彩色单元格(使用其他颜色)。
该应用程序已经允许用户用选定的颜色逐个填充单元格,或者用钢笔工具删除彩色单元格。
有什么建议吗?
(ps:我不使用html画布绘制)
由于这只是16x16或32x32,因此可以使用递归解决方案:
假设您的起点是将像素x/y从颜色A更改为颜色B(A或B可以为空)。
在伪代码中:
function floodfill(x,y,A,B) {
if ((x<0) || (x>15) || (y<0) || (y>15)) return;
if (get_color(x,y)!=A) return;
set_color(x,y,B);
floodfill(x-1,y-1,A,B);
floodfill(x-1,y,A,B);
floodfill(x-1,y+1,A,B);
floodfill(x,y-1,A,B);
floodfill(x,y+1,A,B);
floodfill(x+1,y-1,A,B);
floodfill(x+1,y,A,B);
floodfill(x+1,y+1,A,B);
}
我不完全确定你在寻找什么类型的建议,但你应该看看洪泛填充算法。
它在维基百科上:http://en.wikipedia.org/wiki/Flood_fill
好吧,下面是我在coffeescript中解决问题的方法。这是一个使用画布的例子。脚本应该在任何有一个id为canvas的canvas元素的页面上运行,因为stackerflow问题,我不得不创建自己的堆栈。
log = ->
console.log arguments
class Point
constructor:(@x,@y)->
class BucketFiller
MAXITERATION:100000
factor:1
fill : (ctx,pixel, colCible, colRep)->
P = []
max = @MAXITERATION
if @getColorAtPixel(ctx,pixel)!=colCible then return null
P.push(pixel)
while P.length > 0 and max >=0
--max
currentpixel = P.pop()
@fillRect(ctx,currentpixel.x,currentpixel.y,@factor,@factor,colRep)
if @isInCanvas(ctx,currentpixel)
if @getColorAtPixel(ctx,@up(currentpixel)) == colCible then P.push(@up(currentpixel))
if @getColorAtPixel(ctx,@down(currentpixel)) == colCible then P.push(@down(currentpixel))
if @getColorAtPixel(ctx,@right(currentpixel)) == colCible then P.push(@right(currentpixel))
if @getColorAtPixel(ctx,@left(currentpixel)) == colCible then P.push(@left(currentpixel))
return
fillRect:(ctx,x,y,width,height,color)->
ctx.fillStyle = color
ctx.fillRect(x,y,width,height)
return
down :(pixel)->
return {x:pixel.x,y:pixel.y-@factor}
up:(pixel)->
return {x:pixel.x,y:pixel.y+@factor}
right :(pixel)->
return {x:pixel.x+@factor,y:pixel.y}
left :(pixel)->
return {x:pixel.x-@factor,y:pixel.y}
getColorAtPixel:(ctx,pixel)->
try
imageData = ctx.getImageData(pixel.x,pixel.y,1,1)
catch e
return null
return @rgbArrayToCssColorString(imageData.data)
rgbArrayToCssColorString:(array)->
result = "rgb(#{array[0]},#{array[1]},#{array[2]})"
return result
isInCanvas : (ctx,pixel)->
result = ((0 <= pixel.x <= ctx.canvas.width) and (0 <= pixel.y <= ctx.canvas.height))
return result
main=->
buckfiller = new BucketFiller()
log("start")
canvas = document.getElementById("canvas")
ctx = canvas.getContext("2d")
penPosition = new Point(2,10)
fillColor = "rgb(255,0,0)"
colCible = buckfiller.getColorAtPixel(ctx,penPosition)
try
buckfiller.fill(ctx,penPosition,colCible,fillColor)
catch e
log e
window.onload=->
main()
相关文章:
- 循环比赛位置算法
- javascript扫雷器floodfill算法不能正常工作
- Node JS中的排名系统算法
- 查找仅适用于原始图像的图像放大算法的名称
- 在数组的 2/3 上调用自身的排序算法
- Luhn算法的实现
- 算法:从数组(javascript/angular)中按当前日期获取上一个和下一个事件
- 加速单纯形算法
- 最短路径算法js错误
- CoffeeScript将对象添加到数组中
- gets.chomp for coffeescript?
- CoffeeScript绑定多个参数
- 尝试将js函数更改为coffeescript时发生Uncaught ReferenceError
- 代码战争中的算法混乱
- 用于自动放置流程图形状的算法
- Jquery Validate with Coffeescript
- PHP或JavaScript的基本遗传算法开源代码
- 设置AngularJS控制器属性不能是使用Coffeescript的最后一行
- 用Javascript实现算法
- "铲斗填充”;Javascript或coffeescript中的算法