Advertisement
GopherAtl

Logo api v0.3.2 (computercraft lua)

Sep 12th, 2012
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.93 KB | None | 0 0
  1. --[[
  2.  
  3. LOGO Turtle graphics API v0.3.2
  4. code by GopherAtl.
  5. Do anything you want with this code except claim credit for it.
  6. If you distribute a program that uses it, please link users to the
  7. official thread on the cc forums here:
  8. http://www.computercraft.info/forums2/index.php?/topic/4006-logo-interpreter/
  9. If you distribute a modified version with fixes or enhancements, please link to
  10. it in the official thread as well.
  11.  
  12. --]]
  13.    
  14. --character aspect ratio - constant
  15. local charAspect=6.0/9.0
  16.  
  17. --current turtle location info
  18. local curX,curY=0,0
  19. local curAngle=0
  20.  
  21. --the view scale - how many units from center to the nearest edge (usually top/bottom)
  22. local curScale=100
  23.  
  24. --pen state
  25. local isPenDown=true
  26. local curPenChar="X"
  27.  
  28. --list of display objects being used
  29. local displays={}
  30.  
  31. --unused at present, will remember line data so it can be redrawn
  32. local lineData={
  33.     { pos={0, 0, 0}, angle=0 }
  34. }
  35.  
  36.  
  37. --Bresenham's line algo, adapted to lua by me
  38. function line(device,x1,y1,x2,y2,ch)  
  39.   local steep = math.abs(y2-y1)>math.abs(x2-x1)
  40.   local setPos
  41.   if steep then    
  42.     y1,x1=x1,y1
  43.     y2,x2=x2,y2
  44.     setPos=function(y,x) device.setCursorPos(x,y) end
  45.   else
  46.     setPos=function(x,y) device.setCursorPos(x,y) end
  47.   end
  48.   if x1>x2 then
  49.     x1,x2=x2,x1
  50.     y1,y2=y2,y1
  51.   end
  52.   local dx=x2-x1
  53.   local dy=math.abs(y2-y1)
  54.   local err=dx/2
  55.   local ys= y1<y2 and 1 or -1
  56.   local y=y1
  57.  
  58.   for x=x1,x2 do
  59.     setPos(x,y)
  60.     device.write(ch)
  61.     err=err-dy
  62.     if err<0 then
  63.       y=y+ys
  64.       err=err+dx
  65.     end
  66.   end  
  67. end
  68.  
  69.  
  70.  
  71. --reset the state of all api variables.
  72. function reset()
  73.   home()
  74.   curPenChar="x"
  75.   isPenDown=true
  76.   curScale=100
  77.   displays={}
  78.   lineData={
  79.       { pos={0, 0, 0}, angle=0 }
  80.     }
  81. end
  82.  
  83. function penUp()
  84.   isPenDown=false
  85. end
  86.  
  87. function penDown()
  88.   isPenDown=true
  89. end
  90.  
  91. function penChar(ch)
  92.   curPenChar=string.sub(ch,1,1)
  93. end
  94.  
  95. function moveTo(x,y)
  96.   if isPenDown then
  97.     for k,v in pairs(displays) do
  98.       local x1,y1=posToScreen(curX,curY,k)
  99.       local x2,y2=posToScreen(x,y,k)
  100.       line(displays[k].wrapper,x1,y1,x2,y2,curPenChar)
  101.     end
  102.   end
  103.   curX=x
  104.   curY=y
  105. end
  106.  
  107. function turn(angle)
  108.   curAngle=(curAngle+angle)%360
  109. end
  110.  
  111. function turnTo(angle)
  112.   curAngle=angle%360
  113. end
  114.  
  115. function forward(dist)
  116.   local angleRad=curAngle*math.pi/180.0
  117.   local newX=curX+dist*math.sin(angleRad)
  118.   local newY=curY+dist*math.cos(angleRad)
  119.   moveTo(newX,newY)
  120. end
  121.  
  122.  
  123. --[[
  124. generates values needed for saling lines to a given display
  125. device based on it's dimensions and defined bounds and the
  126. current scale.
  127. --]]
  128. local function scaleDisplay(name)
  129.   if displays[name].width*6>displays[name].height*9 then
  130.     --height is smaller
  131.     displays[name].scaleY=displays[name].centerY/curScale
  132.     displays[name].scaleX=displays[name].scaleY/charAspect
  133.  
  134.   else
  135.     displays[name].scaleX=displays[name].centerX/curScale
  136.     displays[name].scaleY=displays[name].scaleX*charAspect
  137.   end
  138. end
  139.  
  140. --[[
  141. set the scale for all devices to render; the smaller of the
  142. two axes, width or height, as determined by both the dimensions
  143. in characters of the screen and the dimensions of a single
  144. character in the font, will range from -newScale to scale, the
  145. other axis will be larger proportional to trueAspect.
  146. --]]
  147. function scale(newScale)
  148.   curScale=newScale
  149.   --smaller dimension of monitor will be scale
  150.   for k,v in pairs(displays) do
  151.     scaleDisplay(k)
  152.   end
  153. end
  154.  
  155. --convert a coordinate to a position on a given display with
  156. --the current scale
  157. function posToScreen(x,y,display)
  158.   return x*displays[display].scaleX+displays[display].centerX+1, y*displays[display].scaleY+displays[display].centerY+1
  159. end
  160.  
  161.  
  162. --erases the draw area and clears the draw history
  163. function clean()
  164.   for k,v in pairs(displays) do
  165.     for y=v.minY, v.maxY do
  166.       v.wrapper.setCursorPos(v.minX,y)
  167.       v.wrapper.write(string.rep(" ",v.width))
  168.     end
  169.   end
  170.  
  171.   lineData={
  172.       { pos={0, 0, 0}, angle=0 }
  173.   }
  174. end
  175.  
  176. --restores the turtle to it's initial state
  177. function home()
  178.   curX=0
  179.   curY=0
  180.   curAngle=0
  181. end
  182.  
  183. --[[
  184. add a display to the devices it's drawing to.
  185. wrapper is the interface, term for terminal or result of
  186.   peripheral.wrap() for monitors.
  187. min/max values specify a region of the screen to draw in;
  188.   default to full screen
  189. --]]
  190. function addDisplay(name,wrapper,minX,minY,maxX,maxY)
  191.   --set default params
  192.   if minX==nil then
  193.     minX=1
  194.   end
  195.   if minY==nil then
  196.     minY=1
  197.   end
  198.   if maxX==nil then
  199.     local t
  200.     maxX, t=wrapper.getSize()
  201.   end
  202.   if maxY==nil then
  203.     local t
  204.     t, maxY=wrapper.getSize()
  205.   end
  206.   local width, height=maxX-minX+1, maxY-minY+1
  207.  
  208.   displays[name]={
  209.     minX=minX,
  210.     minY=minY,
  211.     maxX=maxX,
  212.     maxY=maxY,
  213.     wrapper=wrapper,
  214.     width=width,
  215.     height=height,
  216.     centerX=width/2,
  217.     centerY=height/2,
  218.     aspect=width/height,
  219.     trueAspect=charAspect*width/height,
  220.   }
  221.  
  222.   scaleDisplay(name)
  223. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement