Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Drawing edge line of a group of tiles — Gideros Forum

Drawing edge line of a group of tiles

piepie Member
edited May 2016 in General questions
Hi, I am trying to draw an outline from some tiles but I can't think of a "smart" way to do it.
I suppose that I could use a complex set of if..then..else, checking neighbours for every tile, but if someone has a better suggestion I am willing to listen.. :)

I have example A, and I'd like to get to example B (see attachment)

Thanks in advance

Comments

  • antixantix Member
    edited May 2016
    Check this article out @pie - http://www.saltgames.com/article/awareTiles/ The article only has a 4-bit algorithm but can be expanded to 31-bit if required.

    And there's this one that I just found again after losing the bookmark ages ago... http://www.angryfishstudios.com/2011/04/adventures-in-bitmasking/

    Likes: pie

    +1 -1 (+1 / -0 )Share on Facebook
  • n1cken1cke Maintainer
    edited May 2016
    This is my Tracer library. It's old and I used it with LuaJit only so I modified it for 'normal' Lua just now and don't know if it will work for you. Anyway you can check the algorythm.
    require "media"
    require "clipper"
     
    -- usage:
    -- local media = Media.new(path)
    -- local polygon = media:getTracedPolygon()
     
    local pixel = Media.new("pixel.png") -- "pixel.png" is 1x1 pixel image
     
    function Media:getTracedPolygon(isPixelTransparent)
    	isPixelTransparent = isPixelTransparent or function(x,y)
    		local _,_,_,a = self:getPixel(x,y)
    		return (a < 0.5)
    	end
     
    	self:drawImage(0,0,pixel,0) -- turbo
    	local w,h = self:getWidth(), self:getHeight()
    	for x = 1, w   do self:setPixel(x,1,0,0,0,0) end -- верх
    	for x = 1, w   do self:setPixel(x,h,0,0,0,0) end -- низ
    	for y = 2, h-1 do self:setPixel(1,y,0,0,0,0) end -- лево
    	for y = 2, h-1 do self:setPixel(w,y,0,0,0,0) end -- право
    	self:drawImage(0,0,pixel,0) -- turbo
     
    	local poly = Polygon.new()
    	local x0, y0
     
    	local function findOrigin()
    		for x = 2, w do
    			for y = 2, h do
    			  if not isPixelTransparent(x,y) then
    				x0,y0 = x-1,y
    				poly:addPoint(x0,y0)
    				return true
    			  end
    			end
    		end
    		return false
    	end
     
    	if not findOrigin() then
    		poly:addPoint(1,1)
    		poly:addPoint(self:getWidth(),1)
    		poly:addPoint(self:getWidth(),self:getHeight())
    		poly:addPoint(1,self:getHeight())	
    		return poly
    	end
     
    	local x, y, dir = x0+1, y0-1, 2
     
    	-- 8 1 2
    	-- 7 x 3
    	-- 6 5 4
     
    	local function getXY(x,y,dir)
    		if     dir == 1 then return x,  y-1
    		elseif dir == 2 then return x+1,y-1
    		elseif dir == 3 then return x+1,y
    		elseif dir == 4 then return x+1,y+1
    		elseif dir == 5 then return x,  y+1
    		elseif dir == 6 then return x-1,y+1
    		elseif dir == 7 then return x-1,y
    					    else return x-1,y-1
    		end
    	end
     
    	local function getFirstDir()
    		if dir < 7 then return dir+2 else return dir-6 end
    	end
     
    	local function getNextDir()
    		if dir > 1 then return dir-1 else return 8 end
    	end
     
    	local function getPrevDir()
    		if dir < 8 then return dir+1 else return 1 end
    	end
     
    	local function getNextPixelXY()
    		return getXY(x,y,getNextDir())
    	end
     
    	local function getPrevPixelXY()
    		return getXY(x,y,getPrevDir())
    	end
     
    	while x ~= x0 or y ~= y0 do
    		dir = getFirstDir()
    		for i = 1,8 do
    			local nx,ny = getXY(x,y,dir)
    			if isPixelTransparent(nx,ny)
    				and (dir%2==1 or isPixelTransparent(getNextPixelXY())
    				or isPixelTransparent(getPrevPixelXY()))
    			then
    				poly:addPoint(x,y)
    				x,y = nx,ny
    				break
    			end
    			dir = getNextDir()
    		end
    	end
     
    	poly:clean(0.45)
    	poly:clean(0.45)
    	return poly
    end

    Likes: pie

    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.