Author Topic: Simple turtle library for EGSL  (Read 11387 times)

Tomaaz

  • Guest
Simple turtle library for EGSL
« on: November 11, 2012, 08:45:05 PM »
I've ported my simple turtle library for Yabasic to EGSL. Not really meant for games, but who knows. ;)

forward(x) - moves the turtle x pixels forward and draws the line when pen is down
backward(x) - moves the turtle x pixels backward and draws the line when pen is down
turnright(x) - turns the turtle x degrees to the right
turnleft(x) - turns the turtle x degrees to the left
pendown() - puts the pen down
penup() - lifts the pen up
goxy(x, y) - moves the turtle to (x, y) position
gox(x) - moves the turtle vertically by x pixels
goy(x) - moves the turtle horizontally by x pixels
resetangle() - set the angle to 0

No matter if the pen is down or up, goxy, gox and goy don't draw anything on the canvas. Value of angle (in degrees) is stored in katzolwia global variable. Position of the turtle is stored in pozycjax and pozycjay global variables.

The source, two examples and updated configuration file for Geany (syntax highlighting) are attached.

Library:
Code: [Select]
pi = 3.14159
katzolwia = 0
pozycjax = 300
pozycjay = 300
rysowanie = 1

function forward(dlugosc)
    local a, b, x, y
    a = (math.sin(katzolwia * pi / 180) * dlugosc)
    b = (math.cos(katzolwia * pi / 180) * dlugosc)
    x = pozycjax + a
    y = pozycjay - b
    if rysowanie == 1 then
        line (pozycjax, pozycjay, x, y)
    end
    pozycjax = x
    pozycjay = y
    redraw()
end

function backward(dlugosc)
    local a, b, x, y
    a = (math.sin(katzolwia * pi / 180) * dlugosc)
    b = (math.cos(katzolwia * pi / 180) * dlugosc)
    x = pozycjax - a
    y = pozycjay + b
    if rysowanie == 1 then
line (pozycjax, pozycjay, x, y)
    end
    pozycjax = x
    pozycjay = y
    redraw ()
end

function turnright(zmiana)
    katzolwia = katzolwia + zmiana
    if katzolwia > 360 then
        katzolwia = katzolwia - 360
    end
    if katzolwia < 0 then
        katzolwia = katzolwia + 360
    end
end

function turnleft (zmiana)
    katzolwia = katzolwia - zmiana
    if katzolwia > 360 then
        katzolwia = katzolwia - 360
    end
    if katzolwia < 0 then
        katzolwia = katzolwia + 360
    end
end

function penup()
    rysowanie = 0
end

function pendown()
    rysowanie = 1
end

function goxy(zmianax, zmianay)
    pozycjax = zmianax
    pozycjay = zmianay
end

function gox(zmianax)
    pozycjax = pozycjax + zmianax
end

function goy(zmianay)
    pozycjay = pozycjay + zmianay
end

function resetangle()
    katzolwia = 0
end

Koch Curve:
Code: [Select]
require "turtle"
openwindow (640, 480, 32, "Test")
goxy (10, 300)
turnright(90)
function koch(x, t)
if t > 0 then
t = t - 1
x = x / 3
koch(x, t)
turnleft(60)
koch(x, t)
turnright(120)
koch(x, t)
turnleft(60)
koch(x, t)
else
forward(3 * x)
end
end

koch(200, 6)
inkey()



Example 2:
Code: [Select]
require "turtle"
openwindow(900, 650, 32, "Test")
resetangle()
goxy(110, 300)   

for x = 1, 20 do
colour(255, 255 - x * 10, x * 5)
forward(250)   
turnleft(198)   
end   

resetangle()   
goxy(230, 440)   
for k = 1, 20   do 
colour(0, 0, 256 - k * 10)
gox(2)   
goy(2)   
for x = 1, 36 do   
if x % 2 == 0 then   
penup()   
end   
backward(20)   
pendown()   
turnright(10)   
end   
end   

resetangle()   
goxy(350, 550)   
k = 2   
while (k < 496) do
colour (k / 2, k / 2, k / 2)
forward(500 - k)   
turnright(91)   
k = k + 2   
end

inkey()

« Last Edit: February 03, 2013, 10:40:27 AM by Cybermonkey »

cvirus

  • Guest
Re: Simple turtle library for EGSL
« Reply #1 on: November 12, 2012, 01:02:15 PM »
Very nice, thanks.  8)

Tomaaz

  • Guest
Re: Simple turtle library for EGSL
« Reply #2 on: November 12, 2012, 06:20:28 PM »
There is no need to use a special pi variable as Lua has build in math.sin() function. For some reason I was trying to call sin() instead of math.sin(). Of course it didn't work, so I added the pi variable.

I've also made another improvement. By default the library call EGSL redraw() function after any drawing takes place. Now it's possible to disable it by using a new setredraw(0) function and call redraw() manually when needed. It makes execution significantly faster. Just compare old Koch Curve example with this one:
Code: [Select]
require "turtle"
openwindow (640, 480, 32, "Test")
goxy (10, 300)
turnright(90)
setredraw(0)
function koch(x, t)
if t > 0 then
t=t-1
x=x/3
koch(x, t)
turnleft(60)
koch(x, t)
turnright(120)
koch(x, t)
turnleft(60)
koch(x, t)
else
forward(3*x)
end
end

koch(200, 6)
redraw()
inkey()

To enable automatic redrawing just use setredraw(1).

New version of the library and an updated file for Geany are attached.
« Last Edit: November 12, 2012, 08:07:55 PM by Tomaaz »

Bereb

  • Guest
Re: Simple turtle library for EGSL
« Reply #3 on: November 12, 2012, 11:12:12 PM »
Here's a very very minimal "turtle", which could be written as a library too :

Code: [Select]
#!/usr/bin/egsl
--================================================--
-- Turtle Graphics  (EGSL) - RECURSIVE TREE (3)
--
-- EGSL 1.5.3 -  Bertrand Carette - nov. 2012
--================================================--

openwindow(400, 400, 0, "EGSL Turtle Graphics")
backcolor(255,255,255)
color(0,0,0)
clearscreen()

-------------------------------------------------
-- constants & variables
-------------------------------------------------
center = {x = screenwidth()/2, y =  screenheight()/2}
coor= {x = 0, y = 0} -- coordinates of the turtle
heading = 0 -- orientation of the turtle
pendown = true -- pen is down
pensize = 0 -- drawing width

-------------------------------------------------
-- basic procedures for polar/turtle graphics
-------------------------------------------------
local sin, cos, rad = math.sin, math.cos, math.rad -- (faster if declared as local)

function setpos(px, py)
-- draw if pen is down
if pendown then
for i = 0, pensize/2, 0.25 do
aaline(center.x+(coor.x+i), center.y-(coor.y+i),center.x+(px+i), center.y-(py+i))
end
end
-- set new position
coor.x, coor.y = px, py
end

function home()
-- move to screen center without drawing or clearing
pen 'up'   -- pendown = false
setpos(0,0)
heading = 0
pen 'down' -- pendown = true
end

function turn(degree)
-- set orientation in degree : right = +degree / left = -degree
heading = heading + degree % 360
end

function go(distance)
-- move : forward = +distance / backward = -distance
local direction = rad(heading)
setpos(coor.x+(distance*sin(direction)), coor.y+(distance*cos(direction)))
end

function pen(p)
local p = p or 'down'
if p == 'down' then
pendown = true
elseif p == 'up' then
pendown = false
else
pendown = false
end
end

--------------------------------------------------
-- MAIN PROGRAM : recursive tree (3)
--------------------------------------------------
setcaption("Recursive tree (3)")

red   = {255,0,0}
green = {0,255,0}
blue  = {0,0,255}
col   = {red, green, blue}

function tree(size)
pensize = size/8
pencolor = col[math.random(1,3)]
colour(pencolor[1], pencolor[2], pencolor[3])
go(size)
if size > 5 then
turn(30)
tree(size/2)
turn(30)
tree(size/2)
turn(-90)
tree(size/2)
turn(-30)
tree(size/2)
turn(60)
end
pen 'up'
go(-size)
pen 'down'
pensize = 0
end

pen 'up'
go(-150)
pen 'down'
tree(150)
redraw()

inkey()
closewindow()

-- fin du programme
« Last Edit: November 13, 2012, 08:51:13 AM by Bereb »

Tomaaz

  • Guest
Re: Simple turtle library for EGSL
« Reply #4 on: November 13, 2012, 02:09:36 AM »
Nice. :) But I needed to fix line 25 to make it work: local sin, cos, rad = math.sin, math.cos, math.rad --(faster if declared as local)

Regards. :)

Bereb

  • Guest
Re: Simple turtle library for EGSL
« Reply #5 on: November 13, 2012, 08:50:40 AM »
But I needed to fix line 25 to make it work: local sin, cos, rad = math.sin, math.cos, math.rad --(faster if declared as local)
Oh, sorry   :-[
This comment was not in the original script. I added it afterwards to point the trick : when variables are declared as 'local', programs run faster. It's obvious especially with fractals (I've got some samples and have tested them with other prog. languages, see there). Thus these sorts of program run up to 5 or 6 times faster and then EGSL (and consequently Lua) has no cause to be envious of some other compiled programing languages  ;)
« Last Edit: November 13, 2012, 09:28:02 AM by Bereb »

Cybermonkey

  • Administrator
  • *****
  • Posts: 0
Re: Simple turtle library for EGSL
« Reply #6 on: November 13, 2012, 09:27:19 AM »
Good to know (with that local declaration). Although the EGSL implemented sin, cos etc. are implemented in Pascal and are compiled ...  ;)
EDIT: Hm, forget that I was talking rubbish ... The math.sin etc. are implemented in C, right? So Pascal can't be faster.
« Last Edit: November 13, 2012, 09:35:14 AM by Cybermonkey »

Bereb

  • Guest
Re: Simple turtle library for EGSL
« Reply #7 on: November 13, 2012, 09:33:58 AM »
Although the EGSL implemented sin, cos etc. are implemented in Pascal and are compiled ...  ;)
Yes. I go on  declaring them out of a bad habit, that I'v got before  I notice the EGSL helper functions, sorry !

lelldorin

  • Guest
Re: Simple turtle library for EGSL
« Reply #8 on: February 02, 2013, 08:24:10 PM »
Hello All,

can i add this example as part of my EGSL IDE?

http://haikuware.com/directory/view-details/development/ides/egsl-ide

Tomaaz

  • Guest
Re: Simple turtle library for EGSL
« Reply #9 on: February 02, 2013, 11:27:52 PM »
I'm not sure if you're asking about my simple library or Bereb's work, but if it's my library, feel free to use it and all my examples.

Regards!
« Last Edit: February 02, 2013, 11:37:45 PM by Tomaaz »

Cybermonkey

  • Administrator
  • *****
  • Posts: 0
Re: Simple turtle library for EGSL
« Reply #10 on: February 03, 2013, 10:41:36 AM »
Sorry, but due to security reasons I removed the links to the images. As Mopz said, maybe you'll find another hoster for images (flickr?)

Tomaaz

  • Guest
Re: Simple turtle library for EGSL
« Reply #11 on: February 03, 2013, 11:40:05 AM »
Yes, I need to find something or... maybe you could change the limit of attachments from 2 to 3? :) One archive with all files needed to run an example and two screenshots would be enough. ;)

Tomaaz

  • Guest
Re: Simple turtle library for EGSL
« Reply #12 on: May 16, 2013, 09:35:26 PM »
I've added some features to make the library more kids-friendly (after all, I've written it for my son). There are two new functions for colour. They accept 17 colour names (white, black, green, red, blue, yellow, grey, purple, aqua, teal, olive, maroon, navy, magenta, lightblue, lightgrey, darkgrey).

setcolour("[colour name]") - set the colour for drawing to "colour name"
setbgcolour("[colour name]") - clears the screen and set the background colour to"colour name"

For more colours you can still use EGSL functions.

There is also a new fill() function that fills the area with a currently set colour.

Here is a small example (see the screenshot):
Code: [Select]
require "turtle"
openwindow (640, 550, 0, "Example of turtle graphics")

function koch(x, t)
if t > 0 then
t=t-1
x=x/3
koch(x, t)
turnleft(60)
koch(x, t)
turnright(120)
koch(x, t)
turnleft(60)
koch(x, t)
else
forward(3*x)
end
end

setredraw(0)
setbgcolor("red")
setcolor("yellow")
goxy (100, 150)
turnright(90)
for x = 1, 3 do
koch(150, 5)
turnright(120)
end
goxy (250, 237)
for x = 1, 3 do
koch(50, 4)
turnright(120)
end
setcolor("white")
circle (325, 275, 200)
redraw()
setredraw(1)
goxy (200, 200)
setcolor("purple")
fill()
goxy (320, 275)
setcolor("olive")
fill()
goxy (10, 10)
setcolor("teal")
fill()
inkey()

Source codes and an updated configuration file for Geany are attached.
« Last Edit: May 16, 2013, 10:10:14 PM by Tomaaz »

Aurel

  • Guest
Re: Simple turtle library for EGSL
« Reply #13 on: September 25, 2014, 05:55:27 PM »
Hi Tomek
I am playing with this Turtle functions in my interpreter and i looking into
your koch curve example ...
how big is variable t
because inside if / end if you have
t=t-1  but i don't see where is t set to value
any help maybe ?

Cybermonkey

  • Administrator
  • *****
  • Posts: 0
Re: Simple turtle library for EGSL
« Reply #14 on: September 25, 2014, 08:26:24 PM »
t is part of the function call. So if it's
Code: [Select]
koch(150, 5)then t=5.