drawing comparison algorithm

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
Jasoco
Inner party member
Posts: 3727
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: drawing comparison algorithm

Post by Jasoco »

Gonna need a lot more work. Looking into a "normalizing" algorithm that will take the overall length of the drawn shape, divide it by 30 then place new points along that path at the spacing interval of Total Length / 30.

Gonna take a break and work on my real project. My top-down 2D adventure game engine.
User avatar
Person
Prole
Posts: 39
Joined: Thu Jun 18, 2009 2:35 am

Re: drawing comparison algorithm

Post by Person »

Wow, just got back from weekend vacation and Jasoco has already done some great stuff! I will continue to work on my project for now and when (or if) Jasoco releases the game/code I would appreciate being able to take a look at it for guidelines.
"Here's another curse for you, may all your bacon burn."
User avatar
Jasoco
Inner party member
Posts: 3727
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: drawing comparison algorithm

Post by Jasoco »

Here's the code I have right now:

Code: Select all

function load()
	love.graphics.setLine(2) 
	
	beginAgain()

	shapePoints = {}
	table.insert(shapePoints, {x = 0, y = 0, shape = 1})
	table.insert(shapePoints, {x = 4, y = 0, shape = 1})
	table.insert(shapePoints, {x = 0, y = 4, shape = 1})
	table.insert(shapePoints, {x = 4, y = 4, shape = 1})
	
	gridX = {}
	gridY = {}
	
	checksOut = "No Match"
	numberOfPoints = 0
	dbg = ""
end

function update(dt)
	if love.mouse.isDown(love.mouse_left) then 
		if started == false then
			placePoint(love.mouse.getX(),love.mouse.getY())
		end
		newShapePlotted = false
		placePoint(love.mouse.getX(),love.mouse.getY())
	elseif started == true and newShapePlotted == false then
		endLine()
	end
end	

function draw()
	love.graphics.draw(dbg, 10, 440)
	if finished == true then
		love.graphics.setColor(love.graphics.newColor(0,255,255,100))
		for i, p in ipairs(newPoints) do
			if p.keep == true then
				love.graphics.rectangle(love.draw_fill, gridX[p.gX] + leftest, gridY[p.gY] + highest, (horizScale * 20), (vertScale * 20))
			end
		end

		love.graphics.setColor(love.graphics.newColor(0,0,255,255))
		love.graphics.line(leftest, highest, leftest, lowest)
		love.graphics.line(rightest, highest, rightest, lowest)
		love.graphics.line(leftest, highest, rightest, highest)
		love.graphics.line(leftest, lowest, rightest, lowest)

		for i=0,5 do
			love.graphics.line(gridX[i] + leftest, highest, gridX[i] + leftest, lowest)
			love.graphics.line(leftest, gridY[i] + highest, rightest, gridY[i] + highest)
			if i < 5 then
				love.graphics.drawf(i, gridX[i] + leftest, gridY[0]-26 + highest, (horizScale * 20), love.align_center)
				love.graphics.drawf(i, gridX[0]-50 + leftest, gridY[i]-5 + highest + ((vertScale * 20)/2), 40, love.align_right)
			end
		end

		--Draw Reference Shape
		love.graphics.setColor(love.graphics.newColor(0,255,255,255))
		for i, p in ipairs(shapePoints) do
			if i > 1 then
				px = shapePoints[i-1].x
				py = shapePoints[i-1].y
				love.graphics.line(math.floor(px * horizScale * 20 + leftest + (horizScale*20/2)), math.floor(py * vertScale * 20 + highest + (vertScale*20/2)), math.floor(p.x * horizScale * 20 + leftest + (horizScale*20/2)), math.floor(p.y * vertScale * 20 + highest + (vertScale*20/2)))
			end
		end
	end
	
	if newShapePlotted == true then
		love.graphics.setColor(love.graphics.newColor(255,255,255,255))
		love.graphics.draw("New: " .. table.getn(newPoints), 280, 460)
		love.graphics.draw("Scale: " .. horizScale .. "," .. vertScale, 380, 460)

		love.graphics.setColor(love.graphics.newColor(255,0,255,255))
		for j, p in ipairs(newPoints) do
			if j > 1 then
				px = newPoints[j-1].x
				py = newPoints[j-1].y
				love.graphics.line(px, py, p.x, p.y)
			end
			if p.keep == true then
				love.graphics.setColor(love.graphics.newColor(255,0,255,255))
			else
				love.graphics.setColor(love.graphics.newColor(255,0,0,255))
			end
			love.graphics.rectangle(love.draw_fill, p.x-7, p.y-7, 14, 14)
			love.graphics.drawf(math.floor(p.gX) .. "," .. math.floor(p.gY), p.x-20, p.y+4, 40, love.align_center)
		end
	end

	if started == true then
		love.graphics.setColor(love.graphics.newColor(255,255,255,255))
		for i, p in ipairs(mousePoints) do
			if i > 1 then
				px = mousePoints[i-1].x
				py = mousePoints[i-1].y
				love.graphics.line(px, py, p.x, p.y)
			end
			numPoints = i
		end
		
		love.graphics.draw("W: " .. width .. ", H: " .. height, 10, 460)
		love.graphics.draw("Points: " .. table.getn(mousePoints), 160, 460)
		love.graphics.drawf(checksOut, 430, 460, 200, love.align_right)

		if finished == true then
			for i, p in ipairs(mousePoints) do
				if p.keep == true then
					love.graphics.setColor(love.graphics.newColor(0,255,0,255))
				else
					love.graphics.setColor(love.graphics.newColor(255,0,0,255))
				end
				love.graphics.rectangle(love.draw_fill, p.x-3, p.y-3, 6, 6)
		
				love.graphics.setColor(love.graphics.newColor(255,255,255,255))
				if p.ang > -1 then
					--love.graphics.drawf(tostring(math.floor(p.ang)), p.x-20, p.y+4, 40, love.align_center)
				end
			end
		end
	end
end

function placePoint(x,y)
	if started == true and finished == true then 
		beginAgain()
	end
	if distanceFrom(lastX, lastY, x, y) > 50 or started == false or (love.timer.getTime() > lastT + .1 and distanceFrom(lastX, lastY, x, y) > 5) then
		lastX = x
		lastY = y
		lastT = love.timer.getTime()
		table.insert(mousePoints, {x = x, y = y, keep = true, keeplock = false, ang = -1})
	end
	started = true	
end

function endLine()
	finished = true
	--This is where it would do the processing

	for i, p in ipairs(mousePoints) do
		if p.x < leftest and p.keep == true then leftest = p.x end
		if p.x > rightest and p.keep == true then rightest = p.x end
		if p.y < highest and p.keep == true then highest = p.y end
		if p.y > lowest and p.keep == true then lowest = p.y end
		width = rightest - leftest
		height = lowest - highest
	end
	for i, p in ipairs(mousePoints) do
		if p.x == leftest or p.x == rightest or p.y == highest or p.y == lowest then
			p.keeplock = true
		end
	end
	
	for i, p in ipairs(mousePoints) do
		if i > 2 then
			x1 = mousePoints[i-2].x
			y1 = mousePoints[i-2].y
			x2 = mousePoints[i-1].x
			y2 = mousePoints[i-1].y
			x3 = mousePoints[i].x
			y3 = mousePoints[i].y
			
			ang1 = findAngle(x2,y2,x1,y1)
			ang2 = findAngle(x2,y2,x3,y3)
			ang3 = ang2 - ang1
			if ang3 < 0 then ang3 = -ang3 end
			mousePoints[i-1].ang = ang3
			
			if ang3 > 159 and ang3 < 211 and mousePoints[i-1].keeplock == false then
				mousePoints[i-1].keep = false
			end
		end	
	end
	
	horizScale = width / 100
	vertScale = height / 100
	
	for i=0,5 do
		gridX[i] = i * (horizScale * 20)
		gridY[i] = i * (vertScale * 20)
	end

	newPoints = {}
	for i, p in ipairs(mousePoints) do
		if p.keep == true then
			if i == table.getn(mousePoints) and distanceFrom(p.x, p.y, mousePoints[1].x, mousePoints[1].y) < 50 then
				ix = mousePoints[1].x
				iy = mousePoints[1].y
			else
				ix = p.x
				iy = p.y
			end
			gX, gY = -1, -1
			for i=0,4 do
				if ix >= gridX[i] + leftest - 1 and ix < gridX[i+1] + leftest + 1 then 
					gX = i
				end
				if iy >= gridY[i] + highest - 1 and iy < gridY[i+1] + highest + 1 then 
					gY = i
				end
			end
			
			table.insert(newPoints, {x = ix, y = iy, gX = gX, gY = gY, keep = true, removed = false})
		end
	end

	for i, p in ipairs(newPoints) do
		if i > 2 then
			x1 = newPoints[i-2].x
			y1 = newPoints[i-2].y
			x2 = newPoints[i-1].x
			y2 = newPoints[i-1].y
			x3 = newPoints[i].x
			y3 = newPoints[i].y
			
			ang1 = findAngle(x2,y2,x1,y1)
			ang2 = findAngle(x2,y2,x3,y3)
			ang3 = ang2 - ang1
			if ang3 < 0 then ang3 = -ang3 end
			
			if ang3 > 139 and ang3 < 231 then
				newPoints[i-1].keep = false
				newPoints[i-1].removed = true
			end
			
			if newPoints[i].gX == newPoints[i-1].gX and newPoints[i].gY == newPoints[i-1].gY and newPoints[i-1].removed == false then
				newPoints[i].keep = false
			end
		end	
	end
	
	newShapePlotted = true

	dbg = ""
	
	matchRef = {}
	curShape = 1
	numberOfPoints = 0
	for j, n in ipairs(newPoints) do
		if n.keep == true then
			table.insert(matchRef, {gX = newPoints[j].gX, gY = newPoints[j].gY})
		end
	end

	i = 1
	j = 1
	for a=1,table.getn(shapePoints) do
		if matchRef[j].gX == shapePoints[i].x and matchRef[j].gY == shapePoints[i].y then
			numberOfPoints = numberOfPoints + 1
		end
		i = i + 1
		j = j + 1
	end
	
	if numberOfPoints > 0 then checksOut = "Found " .. numberOfPoints .. " pts." end
end

function beginAgain()
	started = false
	finished = false
	newShapePlotted = false
	
	lastX = -1
	lastY = -1
	lastT = love.timer.getTime()

	highest = 1000
	lowest = -1000
	leftest = 1000
	rightest = -1000
	width = 0
	height = 0
	
	horizScale = 1
	vertScale = 1
	
	mousePoints = {}
end

function distanceFrom(x1,y1,x2,y2)
	return math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2)
end

function findAngle(x1, y1, x2, y2)
	t = radtodeg(math.atan2(y1 - y2, x2 - x1))
	if t < 0 then t = t + 360 end
	return t	
end

function degtorad(d) return d * math.pi / 180 end	
function radtodeg(r) return r * 180 / math.pi end

function keypressed(k)
	if k == love.key_q then love.system.exit() end
	if k == love.key_r then love.system.restart() end
end
Note that I have no checking in place and the checking I do have is buggy and doesn't work and can be discarded. In essence all I have is the drawing function. You draw a shape and it performs its magic on it.

I don't know when I'll get to working on it again, it's a lot of math and calcuating and I ran out of steam when I hit a wall. So do what you can with this and see if you can do something better. We'll get a working gesture system one day. :ultrahappy:
User avatar
Jasoco
Inner party member
Posts: 3727
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: drawing comparison algorithm

Post by Jasoco »

I thought since I haven't really been able to do much with this project, I'd post this. Maybe it might help a little:

http://www.arkitus.com/Play/?id=21
Post Reply

Who is online

Users browsing this forum: slime and 4 guests