Jump to content


heimdall116's Content

There have been 4 items by heimdall116 (Search limited from 29-March 23)


By content type

See this member's

Sort by                Order  

#192392 The versatile Shape Builder (updated 05/08/14 - now with diagonal lines)

Posted by heimdall116 on 27 August 2014 - 06:45 PM in Turtle Programs

Very cool plug-in for turtles! I had been working on something similar (here's my patchy dome) with the intention of eventually getting to a castle builder...n-sided polygon ramparts with towers (cylinders and pyramids) on the corners, for example. You guys are way ahead of me though, and if there's any way I could hitch a ride on your train instead of lone wolfing it, I'd love to pitch in.

Looking through your code, I thought it was funny that I coincidentally picked some of the same variable names (like "facing") you did, and just implemented them slightly differently (like 1-4 instead of 0-3). By the way, in that particular case I might be able to help you out already: here's a script that ensures the turtles always move *forward* (never in reverse) with the same efficiency. xRel and yRel would by my "GPS" variables.

local function face(f)
-- Re-orient the turtle WRT original facing: 1=forward; 2=right; 3=back; 4=left
		if f-facing == 0 then return
		elseif math.abs(f-facing) == 2 or f-facing == 1 or f-facing == -3 then
				while f-facing ~= 0 do
						turtle.turnRight()
						facing = facing + 1
						if facing == 5 then facing = 1 end
				end
		else
				turtle.turnLeft()
				facing = facing - 1
				if facing == 0 then facing = 4 end
		end
end

local function getThereX(dist)
		if dist == 0 then
				return
		elseif dist > 0 then
				face(1)
		else
				face(3)
		end
		
		for n = 1,math.abs(dist) do
				tryDig()
				tryForward()
		end
		
		xRel = xRel + dist
		return 0
end

local function getThereY(dist)
		if dist == 0 then
				return
		elseif dist > 0 then
				face(4)
		else
				face(2)
		end
		
		for n = 1,math.abs(dist) do
				tryDig()
				tryForward()
		end
		
		yRel = yRel + dist
		return 0
end

local function goTo(x2,y2)
		local dx = round(x2-xRel)
		local dy = round(y2-yRel)
		
		-- Check for low-hanging fruit first
		if facing == 1 and dx > 0 then
				dx = getThereX(dx)
		elseif facing == 2 and dy < 0 then
				dy = getThereY(dy)
		elseif facing == 3 and dx < 0 then
				dx = getThereX(dx)
		elseif facing == 4 and dy > 0 then
				dy = getThereY(dy)
		end
		
		-- do the shorter angle next
		if facing % 2 == 1 then
				dy = getThereY(dy)
				dx = getThereX(dx)
		else
				dx = getThereX(dx)
				dy = getThereY(dy)
		end
end

Here are some other suggestions, which I would love to (and think I am able to) help implement if you're interested. I realize that a few of these (like the n-prism) are more challenging, but I have some ideas on how to go about them all.

Optional command line entry interface
- type "versatileShape dome 7 -d -e -f" to make a dome with diameter 7, "dig down" flag, "use ender chest" flag, "fill in" flag
- Suggest writing a function to populate the "parameters table" right away, by looping through #argTable if inputs are provided
- Good for scripting larger projects (like a castle!!! :) )

Re-organize the (already brand new) input menu (sorry, CupricWolf! We could use the same layout?)
- Choose 2-D foundation first (line, circle, n-sided poly)
- Then choose solid form (solid, tube, pyramid, 2-D)
--- So Circle choices would be "sphere, cylinder, cone, flat circle"
--- But Square choices would be "cuboid, square tower, pyramid, flat square"
--- And n-sided poly choices would be "n-prism, n-tower, n-pyramid, polygon"
- Seems like the only hard one would be the n-prism, which would require a new "angled surface" algorithm

Write a builder for imperfect n-sided polygons (aka, not all angles equal)
--- Construct by angle/side length
--- Possibly develop a GUI, or see what's already out there
--- Probably skip the "prism" option on this one ;)

New external scripts to help showcase the code
--- Castle/fort!!!

If any of these seems like a priority and you're not already working on it, I'd be happy to get started myself. Thanks for your consideration. :)



#192213 Sorting Lua Tables: Multiple Columns

Posted by heimdall116 on 26 August 2014 - 01:58 AM in Ask a Pro

Brilliant - thanks!!! For future Googlers:

x1= x+x0; y1= y+y0; points[#points+1]={['x']=x1,['y']=y1,['theta']=math.atan2(x1,y1)}
x1= y+x0; y1= x+y0; points[#points+1]={['x']=x1,['y']=y1,['theta']=math.atan2(x1,y1)}
x1=-x+x0; y1= y+y0; points[#points+1]={['x']=x1,['y']=y1,['theta']=math.atan2(x1,y1)}
x1=-y+x0; y1= x+y0; points[#points+1]={['x']=x1,['y']=y1,['theta']=math.atan2(x1,y1)}
x1=-x+x0; y1=-y+y0; points[#points+1]={['x']=x1,['y']=y1,['theta']=math.atan2(x1,y1)}
x1=-y+x0; y1=-x+y0; points[#points+1]={['x']=x1,['y']=y1,['theta']=math.atan2(x1,y1)}
x1= x+x0; y1=-y+y0; points[#points+1]={['x']=x1,['y']=y1,['theta']=math.atan2(x1,y1)}
x1= y+x0; y1=-x+y0; points[#points+1]={['x']=x1,['y']=y1,['theta']=math.atan2(x1,y1)}

(...extra midpoint code...)

table.sort(points, function(p1,p2) return p1.theta<p2.theta end)

for i=1,#points do
	print('x=',points[i].x,', y=',points[i].y,', theta=',points[i].theta)	   	
end

Update: This method fails at x=0 and y=0. I was trying to avoid copying demonpants' tower code here, but I'm out of alternative ideas. To future Googlers, I would go with his method instead.



#192199 Sorting Lua Tables: Multiple Columns

Posted by heimdall116 on 25 August 2014 - 10:51 PM in Ask a Pro

Hi there,

I'm using the midpoint algorithm for circles to generate ordered pairs for my turtle. This has been done in many other codes, but I'd like to try a new optimization method: I want to sort the ordered pairs by their polar angle.

ri = math.sqrt(xi2 + yi2)
thetai = math.asin(yi / ri)

I think I know that table.sort requires the "key" column to be continuous integers. So, I thought maybe I could put x in one table and y in another, and write a new sort function that iterates over table.x and table.y to solve for table.theta, sort that, and then apply table.theta's "sorting code" to table.x and table.y.

But I'm pretty new to Lua. Before I go any farther, may I ask if this has been done before? Is there a more obvious solution?

Thanks!

Not sure it will be helpful in this particular case, but my code is at: http://pastebin.com/safRUyjh . This is around line 350...



#174499 Trouble Loading Monitor on Startup

Posted by heimdall116 on 20 April 2014 - 07:29 AM in Ask a Pro

Hi there,

I've got an elusive bug in my code, and could use some advice from a pro. :) This program connects to an ME storage unit and displays its capacity on a monitor.

Problem:
My monitor doesn't work on the first run of the code after initially placing the computer, but does on all subsequent runs. The code doesn't return any errors. Curiously, if I add print(text) inside the while loop, the correct display is repeatedly printed in the terminal until I break - so the ME is wrapped correctly and the code is iterating properly, but the monitor just isn't communicating??

Code
-- Simple LUA script to watch the ME Storage unit
-- Heimdall116, 4/6/14

--Load adjacent peripherals
local ME = peripheral.wrap("left")
local monitor = peripheral.wrap("top")

--Prep the monitor
monitor.clear()
local mX, mY = monitor.getSize()
monitor.setTextScale(3)

--Start periodic updates
while true do
  free = ME.getFreeBytes()
  total = ME.getTotalBytes()
  local text = (total-free..' / '..total)
 
  --Display it on the monitor
  monitor.clear()
  local x = math.floor(mX/2 - 4)
  local y = mY/2-1
  monitor.setTextColor(colors.white)
  monitor.setCursorPos(x,y)
  monitor.write("ME Usage:")
 
  if free/total < 0.25 or total == 0 then
    cCode = colors.red
  elseif free/total < 0.5 then
    cCode = colors.yellow
  else
    cCode = colors.green
  end
 
  local x = math.floor(mX/2 - string.len(text)/2)
  monitor.setCursorPos(x,y+1)
  monitor.setTextColor(cCode)
  monitor.write(text)
 
  monitor.setTextColor(colors.yellow)
  monitor.setCursorPos(1,mY)
  monitor.write(' - H116 ')
  monitor.setTextColor(colors.blue)
  monitor.write(' (Go Blue!)')
 
  os.sleep(3)
end

Thanks very much in advance!