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

weird miscalculation on cylinder digging program

Started by taz4hvn, 08 July 2016 - 07:28 AM
taz4hvn #1
Posted 08 July 2016 - 09:28 AM
I'm in the early stage of writing a turtle program able to dig a cylinder.

My idea to minimize movement and fuel comsuption is to proceed as follow:
- dig four quarters of the cylinder sequentially, only returning to center between them
- dig the first line of the quarter (whose length is a radius), then go back until distance for the next row is within radius and dig the next row and so on.

It mainly works as intended but I have some weird miscalculations, for the last rows it will act inconsistently removing to much blocks or not enought, compared to worldedit //hcyl command.

I tried to use some continuity corrections, inserting some +-.5 in some parts of the code, no luck so far.
My guess was, as I'm moving to the last rows, the derivative gets bigger and bigger and some rounding problems may occur. If someone is willing to help, tell me if my maths or my code is broken.

Here is my code so far:

Spoiler
args = {...}
radius = tonumber( args[1] )
height = tonumber( args[2] )

function distance()
	return math.sqrt(dist^2+posz^2)
end

function forceForward(toGo)
	for i=1,toGo do
		while not turtle.forward() do turtle.dig() end
		turtle.digUp()
		turtle.digDown()
	end
end

function forceDown(toGo)
	for i=1,toGo do
		while not turtle.down() do turtle.digDown() end
	end
end

function placeForEvenRow()
	posz = posz + 1
	turtle.turnLeft()
	forceForward(1)
	turtle.turnLeft()
end

function placeForOddRow()
	posz = posz + 1
		while distance() > radius do
			turtle.back()
			dist = dist - 1
		end
		turtle.turnRight()
		forceForward(1)
		turtle.turnRight()
end

turtle.digUp()
turtle.digDown()

function backToCenter()
	if radius % 2 == 0 then
		turtle.turnRight()
		forceForward(radius-1)
	else
		turtle.turnLeft()
		forceForward(radius-1)
		turtle.turnLeft()
		forceForward(dist)
		turtle.turnRight()
	end
end

function Main()
	slices = math.floor(height/3)
	for slice = 1,slices do
		if slice == 1 then
			forceDown(2)
		else
			forceDown(3)
		end
		for quarter = 1, 4 do
			dist = radius - 1
			posz = 0
			for row = 0,radius-1 do
				forceForward(dist)
				if row ~= radius - 1 then
					if row%2 == 0 then
						placeForOddRow()
					else
						placeForEvenRow()
					end
				else
					backToCenter()
				end
			end
		end
	end
end

Main()
Edited by
The Crazy Phoenix #2
Posted 08 July 2016 - 01:32 PM
Have you tried approximating the circle formula (r2 = x2 + y2) by storing relative coordinates? It may be easier to do so.
Here's a neat function to round:


function round(value)
    --# +0.5 means that anything >= 0.5 will be +1 floored
    return math.floor(value + 0.5)
end

Since you allow the user to input a radius, you may want to find solutions for the equation starting from x = 0 or y = 0 and then checking each nearby block (x and y from -1 to 1) to see which is the closest approximation. Skip blocks you've already tested and you should be able to map out where to place blocks to obtain a circle.
taz4hvn #3
Posted 09 July 2016 - 07:07 AM
First, thanks for the answer.
I knew about this trick to get a missing 'round' in lua and tried it, it definitly changes the shape of the excavation but sadly is no better, and why in the first place should I round the calculus for the distance ?
You're suggestion would be nice if I wanted to build a circle, most of the progs building circles out there do so, but I want to excavate a disk, so the turtle must move only in already digged blocks that makes things trickier.
I'm still stuck.