This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
billysback's profile picture

Generating Polygons/finding Points On Circumfrence Of A Circle

Started by billysback, 30 July 2013 - 05:53 AM
billysback #1
Posted 30 July 2013 - 07:53 AM
Basically, it's fucking up and I have no idea why.
here's the important bit that's messing up:

--r = radius of circle, ang = angle, x,y = centre of circle
local function getPointOnCirc(r, ang, x, y)
	local x2 = x + r * math.cos(ang)
	local y2 = y + r * math.sin(ang)
	return {math.ceil(x2), math.ceil(y2)}
end

--ps = no. points, r =  radius of circle, x,y = centre of circle
local function genPoly(ps, r, x, y)
	local poly = {}
	local tot = 0
	for i=1,ps do
		local rot = 360-tot
		if rot <= 0 then rot = 1 end
		if i == 1 then rot = rot/2 end
		tot = tot + math.random(rot)
		if tot > 360 then tot = 360 end
		local np = getPointOnCirc(r, tot, x, y)
		print(tot..","..np[1]..","..np[2])
		--sleep(0.5)
		poly[#poly + 1] = np
	end
	return poly
end

here's the rest of the program in case you want to try it out:
Spoiler

local function getPointOnCirc(r, ang, x, y)
	local x2 = x + r * math.cos(ang)
	local y2 = y + r * math.sin(ang)
	return {math.ceil(x2), math.ceil(y2)}
end

local function genPoly(ps, r, x, y)
	local poly = {}
	local tot = 0
	for i=1,ps do
		local rot = 360-tot
		if rot <= 0 then rot = 1 end
		if i == 1 then rot = rot/2 end
		tot = tot + math.random(rot)
		if tot > 360 then tot = 360 end
		local np = getPointOnCirc(r, tot, x, y)
		print(tot..","..np[1]..","..np[2])
		--sleep(0.5)
		poly[#poly + 1] = np
	end
	return poly
end

local function drawLine(x1, y1, x2, y2)
		local pixs = {}
	  
		x1 = math.floor(x1)
		y1 = math.floor(y1)
		x2 = math.floor(x2)
		y2 = math.floor(y2)
	  
		if x1 == x2 and y1 == y2 then
			pixs[#pixs + 1] = {x1, y1}
			return pixs
		end
	  
		local minX = math.min( x1, x2 )
		if minX == x1 then
				minY = y1
				maxX = x2
				maxY = y2
		else
				minY = y2
				maxX = x1
				maxY = y1
		end
			  
		local xDiff = maxX - minX
		local yDiff = maxY - minY
					  
		if xDiff > math.abs(yDiff) then
				local y = minY
				local dy = yDiff / xDiff
				for x=minX,maxX do
						if #pixs > 0 then
							if pixs[#pixs][1] == x and pixs[#pixs][2] == math.floor(y + 0.5) then else
								pixs[#pixs + 1] = {x, math.floor(y + 0.5)}
							end
						else
							pixs[#pixs + 1] = {x, math.floor(y + 0.5)}
						end
						y = y + dy
				end
		else
				local x = minX
				local dx = xDiff / yDiff
				if maxY >= minY then
						for y=minY,maxY do
								if #pixs > 0 then
									if pixs[#pixs][1] == math.floor(x+0.5) and pixs[#pixs][2] == y then else
										pixs[#pixs + 1] = {math.floor(x+0.5), y}
									end
								else
									pixs[#pixs + 1] = {math.floor(x+0.5), y}
								end
								x = x + dx
						end
				else
						for y=minY,maxY,-1 do
								if #pixs > 0 then
									if pixs[#pixs][1] == math.floor(x+0.5) and pixs[#pixs][2] == y then else
										pixs[#pixs + 1] = {math.floor(x+0.5), y}
									end
								else
									pixs[#pixs + 1] = {math.floor(x+0.5), y}
								end
								x = x - dx
						end
				end
		end
		--if pixs[1][1] == x2 and pixs[1][2] == y2 then pixs = flipTable(pixs) end
		return pixs
end
local sw, sh = term.getSize()
local function createShape(poly)
	local shape = {}
	local l = ""
	for i=1,#poly do
		local p1 = poly[i]
		local p2 = poly[i+1]
		if i == #poly then p2 = poly[1] end
		local line = drawLine(p1[1], p1[2], p2[1], p2[2])
		for j=1,#line do
			shape[#shape + 1] = line[j]
		end
		l = l..p1[1]..","..p1[2].." "
	end
	shape.det = l
	shape.poly = poly
	shape.draw = function(self, back, text, char)
		for i=1,#self do
			local p = self[i]
			term.setCursorPos(p[1], p[2])
			term.setBackgroundColor(back)
			term.setTextColor(text)
			term.write(char)
		end
		for i=1,#self.poly do
			local p = self.poly[i]
			term.setCursorPos(p[1], p[2])
			term.setBackgroundColor(back)
			term.setTextColor(text)
			term.write(tostring(i))
		end
		term.setCursorPos(1, sh-1)
		term.write(self.det)
	end
	return shape
end

term.setBackgroundColor(colors.black)
term.clear()
term.setCursorPos(1,1)
local mid = {math.floor(sw/2), math.floor(sh/2)}
local shape = createShape(genPoly(math.random(5, 8), math.random(5, 8), mid[1], mid[2]))
shape:draw(colors.red, colors.white, " ")
--sleep(2)
term.setCursorPos(1, sh)

for some reason, despite the angle being constantly under 360, it is drawing the points at seemingly random positions around the circle, meaning weird looking shapes are being made.
I have no idea why.

EDIT:
also, here is an example output of that function:

154,20,9
288,29,4
302,31,12
349,20,8
353,28,15
356,22,4
where the first number is the angle and the next two are the x,y coords.

NOTE:
there aren't any errors, the program *works* fine, it just doesn't work as expected
Bubba #2
Posted 30 July 2013 - 09:41 AM
In Lua, sin/cos take radians, not degrees. I haven't looked at your math yet but I'm guessing that's the issue.


math.sin(90) --0.893
math.sin((90*math.pi)/180) --1
billysback #3
Posted 30 July 2013 - 09:51 AM
That fixed it, thanks
This exact equations has worked in previous programs though .-.