Posted 06 September 2013 - 05:23 AM
Hello all,
My name is Resender & I'm currently running a FTB series called To the END,in which I'm attempting to live in the END.
Since tuesday I've been atempting to write a program that would allow a turtle to build the most common structure in my build.
The result should be something like this
(Semi manually build)
But this what I get
The top ring sits in the correct spot,the bowl however is 10 up & 7 to the right off.
The problem occurs when I increase the radius needed to make the bowl to twice the radius of that of the circle.
I've checked the numbers that are given to the turle while moving but I cant figure out why its doing what its doing.
For instance the numbers for the movement match 100% between giving in a ring radius of 10,bowl 20 (radius bowl = radius*2) and giving in a ring radius of 20,bowl 20 (where the radius remains the same)
If anyone can take a look & tell me why this is happening that would be most appreciated.
This code is based upon Sphere Maker 2 from Timothy Goddard
http://pastebin.com/zKN6AZHG
My name is Resender & I'm currently running a FTB series called To the END,in which I'm attempting to live in the END.
Since tuesday I've been atempting to write a program that would allow a turtle to build the most common structure in my build.
The result should be something like this
(Semi manually build)
But this what I get
The top ring sits in the correct spot,the bowl however is 10 up & 7 to the right off.
The problem occurs when I increase the radius needed to make the bowl to twice the radius of that of the circle.
I've checked the numbers that are given to the turle while moving but I cant figure out why its doing what its doing.
For instance the numbers for the movement match 100% between giving in a ring radius of 10,bowl 20 (radius bowl = radius*2) and giving in a ring radius of 20,bowl 20 (where the radius remains the same)
If anyone can take a look & tell me why this is happening that would be most appreciated.
This code is based upon Sphere Maker 2 from Timothy Goddard
http://pastebin.com/zKN6AZHG
Spoiler
local arg = { ... }
radius = tonumber(arg[1])
cslot = 1
function checkFuel()
success = false
while not success do
if turtle.getFuelLevel() < 2 then
turtle.select(16)
success = turtle.refuel(2)
turtle.select(cslot)
else
success = true
end
if not success then
print("No fuel in slot 16.")
print("Please add fuel and press enter to continue.")
io.read()
end
end
end
-- Navigation features
-- allow the turtle to move while tracking its position
-- this allows us to just give a destination point and have it go there
positionx = radius
positiony = radius
facing = 0
function turnRightTrack()
turtle.turnRight()
facing = facing + 1
if facing >= 4 then
facing = 0
end
end
function turnLeftTrack()
turtle.turnLeft()
facing = facing - 1
if facing < 0 then
facing = 3
end
end
function safeForward()
checkFuel()
success = false
while not success do
success = turtle.forward()
if not success then
print("Blocked attempting to move forward.")
print("Please clear and press enter to continue.")
io.read()
end
end
end
function safeBack()
checkFuel()
success = false
while not success do
success = turtle.back()
if not success then
print("Blocked attempting to move back.")
print("Please clear and press enter to continue.")
io.read()
end
end
end
function safeUp()
checkFuel()
success = false
while not success do
success = turtle.up()
if not success then
print("Blocked attempting to move up.")
print("Please clear and press enter to continue.")
io.read()
end
end
end
function safeDown()
checkFuel()
success = false
while not success do
success = turtle.down()
if not success then
print("Blocked attempting to down up.")
print("Please clear and press enter to continue.")
io.read()
end
end
end
function moveToStart()
for i =1,radius do
safeForward()
end
if radius <= 10 then
downward = 3
else
downward = 5
end
for i = 1,downward do
safeDown()
end
--print("RDS")
--print(radius,downward)
--print("RDE")
end
function moveY(targety)
if targety == positiony then
return
end
if (facing ~= 0 and facing ~= 2) then -- check axis
turnRightTrack()
end
while targety > positiony do
if facing == 0 then
safeForward()
else
safeBack()
end
positiony = positiony + 1
end
while targety < positiony do
if facing == 2 then
safeForward()
else
safeBack()
end
positiony = positiony - 1
end
end
function moveX(targetx)
if targetx == positionx then
return
end
if (facing ~= 1 and facing ~= 3) then -- check axis
turnRightTrack()
end
while targetx > positionx do
if facing == 1 then
safeForward()
else
safeBack()
end
positionx = positionx + 1
end
while targetx < positionx do
if facing == 3 then
safeForward()
else
safeBack()
end
positionx = positionx - 1
end
end
function navigateTo(targetx, targety)
-- Cost calculation mode - don't move
if cost_only then
return
end
print(facing)
if facing == 0 or facing == 2 then -- Y axis
moveY(targety)
moveX(targetx)
else
moveX(targetx)
moveY(targety)
end
end
function placeBlockLower()
if turtle.getItemCount(cslot) == 0 then
foundSlot = false
while not foundSlot do
for i = 1,15 do
if turtle.getItemCount(i) > 0 then
foundSlot = i
break
end
end
if not foundSlot then
-- No resources
print("Out of building materials. Please refill and press enter to continue.")
io.read()
end
end
cslot = foundSlot
turtle.select(foundSlot)
end
turtle.placeDown()
end
function placeBlockUpper()
if turtle.getItemCount(cslot) == 0 then
foundSlot = false
while not foundSlot do
for i = 5,15 do
if turtle.getItemCount(i) > 0 then
foundSlot = i
break
end
end
if not foundSlot then
-- No resources
print("Out of building materials. Please refill and press enter to continue.")
io.read()
end
end
cslot = foundSlot
turtle.select(foundSlot)
end
turtle.placeDown()
end
function buildLowerPart()
--Calculus
zstart = 0
zend = downward-1
radius = radius * 2
width = radius * 2 + 1
sqrt3 = 3 ^ 0.5
boundary_radius = radius + 1.0
boundary2 = boundary_radius ^ 2
--Calculus
for z = zstart,zend do
if not cost_only then
safeUp()
end
--print("Layer " .. z)
cz2 = (radius - z) ^ 2
limit_offset_y = (boundary2 - cz2) ^ 0.5
max_offset_y = math.ceil(limit_offset_y)
-- We do first the +x side, then the -x side to make movement efficient
for side = 0,1 do
-- On the right we go from small y to large y, on the left reversed
-- This makes us travel clockwise around each layer
if (side == 0) then
ystart = radius - max_offset_y
yend = radius + max_offset_y
ystep = 1
else
ystart = radius + max_offset_y
yend = radius - max_offset_y
ystep = -1
end
for y = ystart,yend,ystep do
cy2 = (radius - y) ^ 2
remainder2 = (boundary2 - cz2 - cy2)
if remainder2 >= 0 then
-- This is the maximum difference in x from the centre we can be without definitely being outside the radius
max_offset_x = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
-- Only do either the +x or -x side
if (side == 0) then
-- +x side
xstart = radius
xend = radius + max_offset_x
else
-- -x side
xstart = radius - max_offset_x
xend = radius - 1
end
-- Reverse direction we traverse xs when in -y side
if y > radius then
temp = xstart
xstart = xend
xend = temp
xstep = -1
else
xstep = 1
end
for x = xstart,xend,xstep do
--[[
print("LS XS:" .. xstart,"-" .. x)
print("LP YS:" .. ystart,"-" .. y)
print("LP ZS:" .. zstart,"-" .. z)
--]]
cx2 = (radius - x) ^ 2
distance_to_centre = (cx2 + cy2 + cz2) ^ 0.5
-- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
print(distance_to_centre)
print(boundary_radius)
print(sqrt3)
if distance_to_centre < boundary_radius and distance_to_centre + sqrt3 >= boundary_radius then
offsets = {{0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}
for i=1,6 do
offset = offsets[i]
dx = offset[1]
dy = offset[2]
dz = offset[3]
if ((radius - (x + dx)) ^ 2 + (radius - (y + dy)) ^ 2 + (radius - (z + dz)) ^ 2) ^ 0.5 >= boundary_radius then
-- This is a point to use
--print("X:" .. x,"Y:" .. y)
navigateTo(x, y)
placeBlockLower()
break
end
end
end
end
end
end
end
end
--end
--print(radius,"-",radius)
radius = radius
navigateTo(radius,radius)
end
function buildRing(matID)
--Calculus
radius = radius
width = radius * 2 + 1
sqrt3 = 3 ^ 0.5
boundary_radius = radius + 1.0
boundary2 = boundary_radius ^ 2
zstart = radius
zend = zstart
--Calculus
for z = zstart,zend do
if not cost_only then
safeUp()
end
--print("Layer " .. z)
cz2 = (radius - z) ^ 2
limit_offset_y = (boundary2 - cz2) ^ 0.5
max_offset_y = math.ceil(limit_offset_y)
-- We do first the +x side, then the -x side to make movement efficient
for side = 0,1 do
-- On the right we go from small y to large y, on the left reversed
-- This makes us travel clockwise around each layer
if (side == 0) then
ystart = radius - max_offset_y
yend = radius + max_offset_y
ystep = 1
else
ystart = radius + max_offset_y
yend = radius - max_offset_y
ystep = -1
end
--print("UP YS:" .. ystart)
for y = ystart,yend,ystep do
cy2 = (radius - y) ^ 2
remainder2 = (boundary2 - cz2 - cy2)
if remainder2 >= 0 then
-- This is the maximum difference in x from the centre we can be without definitely being outside the radius
max_offset_x = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
-- Only do either the +x or -x side
if (side == 0) then
-- +x side
xstart = radius
xend = radius + max_offset_x
else
-- -x side
xstart = radius - max_offset_x
xend = radius - 1
end
-- Reverse direction we traverse xs when in -y side
if y > radius then
temp = xstart
xstart = xend
xend = temp
xstep = -1
else
xstep = 1
end
for x = xstart,xend,xstep do
cx2 = (radius - x) ^ 2
distance_to_centre = (cx2 + cy2 + cz2) ^ 0.5
-- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
if distance_to_centre < boundary_radius and distance_to_centre + sqrt3 >= boundary_radius then
offsets = {{0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}
for i=1,6 do
offset = offsets[i]
dx = offset[1]
dy = offset[2]
dz = offset[3]
if ((radius - (x + dx)) ^ 2 + (radius - (y + dy)) ^ 2 + (radius - (z + dz)) ^ 2) ^ 0.5 >= boundary_radius then
-- This is a point to use
navigateTo(x, y)
if matID >= 1 then
placeBlockUpper()
else
placeBlockLower()
end
break
end
end
end
end
end
end
end
end
--print(radius,"-",radius)
navigateTo(radius,radius)
end
--Main Program run
cost_only = false
moveToStart()
r2 = radius
--print("R2:" .. r2)
buildLowerPart()
for i =1,3 do
buildRing(i)
end