RetroBASIC
Retrogamecoding(.org) => Examples => Topic started by: Bereb on November 13, 2012, 09:24:29 AM
-
An example of Mandelbrot (and speed test) :
Try to comment all lines beginning with 'local' to see the difference
#!/usr/bin/egsl
------------------------------------------------------------
-- MandelBrot (nov 2012) - EGSL 1.5.3 (B.Carette)
------------------------------------------------------------
openwindow(400,300,0,"Mandelbrot (EGSL)")
backcolor(255,255,255)
clearscreen()
--setframetimer(1000)
-- constants
local width, height, minre, maxre, mini, maxi, refactor, imfactor
width, height = screenwidth(), screenheight()
minre, maxre = -2.0, 1
mini = -1.2
maxi = mini+(maxre-minre)*height/width
refactor = (maxre-minre)/(width-1)
imfactor = (maxi-mini)/(height-1)
-- variables
local st, et
local cim, cre, zre, zim, zre2, zim2
local t
--MAIN PROGRAM
st = timerticks()
for y = 0, height+16 do
cim = maxi-y*imfactor
for x = 0, width do
cre = minre+x*refactor
zre = cre
zim = cim
for i = 0, 50 do
zre2 = zre*zre
zim2 = zim*zim
if zre2 + zim2 > 4 then
color(255-(i+5), i*5, i)
dot(x,y)
break
end
zim = 2*zre*zim+cim
zre = zre2-zim2+cre
end
end
end
et = timerticks()
t = tostring(et-st).." ms"
color(255,255,255)
drawtext(1, 10, t)
sync()
inkey()
closewindow()
--[[--
*** COMPARISONS ***
Interpreted Basic-like scripting languages :
* EGSL : +ou- 3000 ms / 600 to 800 ms (with variables as 'local')
* SDLBasic : 3400 ms
* FBSL : +ou- 10000 ms (freestyle Basic on win32)
Compiled Basics :
* PureBasic : 1438 ms / 422 ms compiled (win32)
1109 ms / 78 ms compiled (win32), with 'SetGadgetState()' after 2nd 'Next'
* GFA-BAsic : 315 ms / 198 ms compiled (win32)
* FreeBASIC : 220 to 400 ms
Lua + FLTK :
* murgaLua : 1900 to 2500 ms / 450 to 600 ms (with variables as 'local')
--]]--
-
As for speed issues one should use redraw() instead of sync() because sync() is implemented as
wait (timeleft())
redraw()
So even if timeleft=0 there is a second function call.
-
There is something similar on basicprogramming.org forum (http://forum.basicprogramming.org/index.php?topic=2450.0). You will find speed comparison and examples of Mandelbrot Set real time animation there.
-
As for speed issues one should use redraw() instead of sync()
Effectively. After several tests with both redraw() and sync(), I've got an average of 587ms for redraw() and 652ms for sync().
There is something similar on basicprogramming.org forum (http://forum.basicprogramming.org/index.php?topic=2450.0).
Thanks for the link. I didn't know that forum, it seems to be interesting
Your Mandelbrot Set example in that forum should run faster with 'local' variables, at least 2 times faster and then EGSL should sit after BaCon and before NaaLaa :)
I'v not tested it but I've a similar script adapted from X11-Basic. I don't know if i can post it here because of this comment at the head : Mandelbrotfraktale (c) Markus Hoffmann (copyright ?)
-
Hm, Markus is also registered at bp.org. (Are there any interpreter creators whose name is not Markus or Marcus? ;D) But I think if you leave the copyright message and do not change the code you might post it here.
-
So then ... :)
I have just changed the size of the screen and of course I have adapted the code so that it can work with EGSL
#!/usr/bin/egsl
--[[
°
° Mandelbrotfraktale (c) Markus Hoffmann
° Simple and direct drawing algorithm.
° X11-Basic, adapted for EGSL
°
--]]
local bx,by,bw,bh
local sx,sy,sw,sh
local t0, t1
local gx,gy,zx,zy,nzx
local col,r,v,b
bx=0
by=0
bw=800
bh=800
sx=-2.2
sy=-1.7
sw=3.4
sh=3.4
openwindow(bw,bh,0,"Mandel simple - EGSL (adapted from X11-Basic) -")
clearscreen()
t0=timerticks()
for x=bx,bx+bw do
for y=by,by+bh do
gx=(x-bx)/bw*sw+sx
gy=(y-by)/bh*sh+sy
zx=gx
zy=gy
for c=0,255 do
col = c
nzx=zx*zx - zy*zy + gx
zy=2*zx*zy+gy
zx=nzx
if zx*zx + zy*zy > 4 then
col = c
break
end
end
r = col*256+col
v = col*256+col*32
b = col*256+col*64
colour(r,v,b)
dot(x,y)
end
redraw()
end
t1=timerticks()
temps = tostring((t1-t0)/1000)
color(255,255,0)
drawtext(1,1,temps.." secondes.")
redraw()
inkey()
closewindow()
about 20 sec. this way (about 48 sec. without 'local' variables)
-
Wow. By the way (another annoying tipp of me), this is enough for drawtext:
temps = (t1-t0)/1000
because it automatically converts numbers to strings. ;)
My computer needs about 4 sec. with local definitions and about 15 sec. without. So, hey, thanks for your performance tipps!
-
I've written a real time Mandelbrot Set animation and I'm really impressed! Not as fast as compiled languages, but much faster than other scripting languages (including JavaScript)! :o
function mandelbrot()
local przelx, przely, powiekszenie, przesx, przesy, x, y, x2, y2, x3, a, b, c, z, a2, b2
przelx = 3 / 240
przely = 2 / 160
powiekszenie = 1
przesx = 14.17799995
przesy = 79.999904
repeat
przelx = 3 / (240 * powiekszenie);
przely = 2 / (160 * powiekszenie);
for x = 0, 240 do
x3 = x - 120
for y = 0, 160 do
y3 = y - 80
c, a, b, z = 0, 0, 0, 0
x2 = (przelx * (x3 + (przesx * powiekszenie))) - 2
y2 = (przely * (y3 + (przesy * powiekszenie))) - 1
while c < 255 and z < 4 do
a2 = a * a - b * b
b2 = 2 * a * b
a = a2 + x2
b = b2 + y2
z = a * a + b * b
c = c + 1
end
if c == 255 then
colour(0, 0, 0)
else
colour(255 - c, (c % 50)* 5, c)
end
dot(x, y)
end
end
if powiekszenie < 15625500000 then
powiekszenie = powiekszenie + powiekszenie * 0.05
end
redraw()
klawisz = getkey()
until klawisz == 27
end
openwindow(240, 160, 32, "Mandelbrot animation")
mandelbrot()
-
It's really amazing (for an interpreted language) :)
-
I have been working on a script that I have adapted from a murgaLua script of mine, inspired by a script found in BaCon samples ???
It's again about fractal but with a simplistic GUI.
I deliver it to you here as it is, with its possible errors and bugs :
#!/usr/bin/env egsl
-----------------------------------------------------------
-- Fractale avec GUI - EGSL 1.5.3
-- novembre 2012
-- B.Carette
-----------------------------------------------------------
--------------------------------------------------
-- Class 'Button'
--------------------------------------------------
Button = {}
button_id = 0 -- I'm not sure it is insdispensable here
function Button:new(x, y, text)
-- crée un objet si l'utilisateur n'en fournit pas / object if not provided
local obj = {}
setmetatable(obj, self)
self.__index = self
-- initialiser l'objet / inializing object
button_id = button_id + 1
obj.id = button_id
obj.x = x or 1
obj.y = y or 1
obj.text = text or ""
obj.width = #obj.text*8 + 8
obj.height = 24
obj.color = {r = 100, g = 100, b = 100}
obj.hlight = {r = 200, g = 200, b = 200}
obj.tcol = {r = 255, g = 255, b = 255}
obj.over = false
obj.callback = function() end
-- retourner l'objet
return obj
end
function Button:draw()
local col, txt
-- update
if mousezone(self.x, self.y, self.x + self.width, self.y + self.height) then
self.over = true
else
self.over = false
end
-- mouse pressed
if self.over then
col = self.hlight
if mouseb() == 1 then
color(255,0,0)
self.callback()
end
else
col = self.color
end
-- draw
color(col.r, col.g, col.b)
fillbox(self.x, self.y, self.width + self.x, self.height + self.y)
col = self.color
color(col.r+10,col.g+10,col.b+10)
box(self.x, self.y, self.width + self.x, self.height + self.y)
col = self.tcol
color(col.r,col.g,col.b)
drawtext(self.x + 4 , self.height/2 + self.y-4 , self.text)
--
redraw()
end
--------------------------------------------------
-- Constantes, variables, tableaux
--------------------------------------------------
local MaxIters = 100
local xSize = 300
local ySize = 240
local Black = -1
local Left = -2.0
local Right = 1.0
local Top = 1.1
local Bottom = -1.0
local layout = "Fractal with EGSL"
local start = "Please wait..."
local ready = "Ready!"
local picol = {{127,0,0},{127,0,128},{127,0,255},{127,127,0},
{127,127,127},{127,127,255},{127,255,0},{127,255,127},
{127,255,255},{255,0,0},{255,0,127},{255,0,255},
{255,127,0},{255,127,127},{255,127,255},{255,255,0}}
--------------------------------------------------
-- Interface graphique / GUI
--------------------------------------------------
openwindow(300,300, 0, "Fractale - EGSL 1.5.3")
backcolor(150, 150, 150)
clearscreen()
color(0, 0, 0)
drawtext(110, 280, layout)
-- canevas / canvas
color(255, 255, 255)
fillbox(1, 1, 298, 264)
-- boutons de commande / buttons
btn_draw = Button:new(2, 270, "Draw")
btn_clear = Button:new(50, 270, "Clear")
btn_exit = Button:new(255, 270, "Exit")
--------------------------------------------------
-- Gestion des évènements / managing events
--------------------------------------------------
function quit()
os.exit()
end
function clear()
-- retracer le canevas / redrawing canvas
color(255, 255, 255)
fillbox(1, 1, 299, 250)
redraw()
end
function draw()
-- effacer le texte d'attente / clearing info text
color(255, 255, 255)
fillbox(1, 240, 122, 264)
-- signaler le début du tracé / info to user
color(255, 0, 0)
drawtext(1, 255, start)
redraw()
-- calcul / computing
for y = 0, ySize do
for x = 0, xSize do
local zr, zi = 0, 0
local cr = Left + x * (Right - Left) / xSize
local ci = Top + y * (Bottom - Top) / ySize
local rsquared = zr * zr
local isquared = zi * zi
local count = 0
while (rsquared + isquared) < 2.0 and count < MaxIters do
zi = zr * zi * 2
zi = zi + ci
zr = rsquared - isquared
zr = zr + cr
rsquared = zr * zr
isquared = zi * zi
count = count+1
end
local sum = rsquared + isquared
if sum < 1 then
if sum < 2 then
ind = math.ceil(sum * 16)
else
ind = 16
end
color(picol[ind][1],picol[ind][2],picol[ind][3])
dot(x, y)
end --if
end --for x
end --for y
-- effacer le texte d'attente / clear info text
color(255, 255, 255)
fillbox(1, 240, 122, 264)
-- signaler que l'on est prêt à tracer / tell drawing is ready
color(0, 0, 255)
drawtext(1, 255, ready)
end
--------------------------------------------------
-- Evènements / events
--------------------------------------------------
btn_draw.callback = draw
btn_clear.callback = clear
btn_exit.callback = quit
--------------------------------------------------
-- Boucle principale / main loop
--------------------------------------------------
repeat
key = getkey()
btn_draw:draw()
btn_clear:draw()
btn_exit:draw()
until key == 27
closewindow()
8)
-
I've started many topics about fractals and written many examples in different languages (Yabasic, FreeBASIC, NaaLaa, BaCon, Blassic, AurelBasic), because I simply love fractals. But I think that folks here are bored of this stuff. Don't get me wrong. I have nothing against your examples. Just don't be surprised and disappointed if no one ever replies. Remember that EGSL is meant for games. ;)
Regards! :)
-
Very nice. But please don't forget the closewindow in your function quit:
function quit()
closewindow()
os.exit()
end
-
@Tomaaz
Yes, I remarked that EGSL was above all meant for games. That's why I was hesitating to join this forum recently, although I use EGSL since several months. I hesitate to post my scripts every time for the same reason. Moreover I'm not really a game fan. The kind of games that I appreciate is, for instance, Bubble Chain or similar. :-\
IMHO I don't think EGSL should be limited only for games. I think it can be a good language to become initiated into programing and other stuffs, thanks to its simplicity, its performances (probably due to Lua and Pascal) and thanks to the fact it develops mainly graphics. What allows to get a quick feedback of what we put on our scripts, as Logo and Basic did in the past. I come from there (Logo, Basic, etc. on a Commodore 64 in the '80s), sorry, but I'm not at all nostalgic. World moves forward ... :)
I don't post my scripts with the only intention of receiving congratulations or some gratefulness. In the other hand, I appreciate if one corrects my errors. I just wanted to share my modest experiments, which could be usefull, well I hope so. ???
I have an indigestion of fractals too. I use them for testing and I tested many languages this way (May be I'm an obsessive test man) ;)
In my last script, fractal was just pretext to test my extremely naive and simplistic attempt to create command buttons with EGSL, without calling complex external libraries. However, about that, I did not feel like doing another topic, for fear that I appear to be coming to the fore :-[
@Cybermonkey
When I put only closewindow() in my function quit(), I get this message (if a console is opened, e.g. in Geany editor) : Error: No graphics window initialized. and nothing with os.exit().
But I did not test with both : closewindow() and os.exit(). That works fine and it's more satisfying.
Thanks
-
Moreover I'm not really a game fan.
Me, too. ;) All I can play is "Boulder Dash" and space shooters. :)
IMHO I don't think EGSL should be limited only for games.
I couldn't agree more! :) Do you know that first name of the interpreter was Easy Graphic Scripting with Lua? Later Markus has changed it to Game, probably for marketing reasons.
I don't post my scripts with the only intention of receiving congratulations or some gratefulness. In the other hand, I appreciate if one corrects my errors.
I even like when people say that my work is really bad. But sometimes they just don't reply and that's what I meant. What I wanted to say was: Keep posting and don't care if there is no reply. ;)
I have an indigestion of fractals too. I use them for testing and I tested many languages this way...
Me, too. :) Here (http://fractals.ct8.pl/) you can find my Mandelbrot Set explorer in JavaScript.
BTW Do you like coding demos? What do you thing about this one (http://tomaaz.ct8.pl/simple_demo.zip)?
Regards! :)
-
I couldn't agree more! :) Do you know that first name of the interpreter was Easy Graphic Scripting with Lua? Later Markus has changed it to Game, probably for marketing reasons.
Then my subconscious have replaced 'game' by 'graphic' ;D
Yes, "game" seems less austere than "graphic" or "graphic arts". But after all, games depends a lot on graphics, so we can be content with that :)
BTW Do you like coding demos? What do you thing about this one (http://tomaaz.ct8.pl/simple_demo.zip)?
Well, I had already downloaded it and I find it's a good (and amazing) presentation, which places EGSL precisely between 'game' and 'graphics' ::)
I even like when people say that my work is really bad. But sometimes they just don't reply and that's what I meant. What I wanted to say was: Keep posting and don't care if there is no reply. ;)
While posting my sketchy scripts, my first intention was to return what I had taken from the experience of the other members. I learnt a lot from the former forum (which was impossible to join). The least I could do as thanks was this modest return. Afterwards everyone can do as he wants with that :)
Thanks for the link to your Javascript demos. I don't know very well Java and Javascript, although I gave Processing a little try. But the latter seems to me rather 'heavy' and I'm looking for lighter solutions (with good performances nevertheless) like SDLBasic or EGSL preferably (because of Lua and its better maintenance)
-
Well, I had already downloaded it and I find it's a good (and amazing) presentation, which places EGSL precisely between 'game' and 'graphics' ::)
I don't think it's particularly good, but it's amazing how easy is creating something like that with EGSL. It has 117 lines of code and it took me maybe half an hour to write it. Adding new effects is extremely easy. I don't think it would be as easy and fun to make it in Python or even BASIC.
-
And here is the same Mandelbrot animation written in FreePascal + egslengine. This is really fast!
program Mandelbrot;
uses egslengine;
var
x, y, c : integer;
przelx, przely, powiekszenie, przesx, przesy, x2, y2, x3, y3, a, b, z, a2, b2 : double;
begin
openwindow(240, 160, 32 ,'Mandelbrot Set');
przelx := 3 / 240;
przely := 2 / 160;
powiekszenie := 1;
przesx := 14.1779999496342;
przesy := 79.999903999999999;
repeat
begin
przelx := 3 / (240 * powiekszenie);
przely := 2 / (160 * powiekszenie);
for x := 0 to 240 do
begin
x3 := x - 120;
for y := 0 to 160 do
begin
y3 := y - 80;
c := 0;
a := 0;
b := 0;
z := 0;
x2 := (przelx * (x3 + (przesx * powiekszenie))) - 2;
y2 := (przely * (y3 + (przesy * powiekszenie))) - 1;
while (c < 255) and (z < 4) do
begin
a2 := a * a - b * b;
b2 := 2 * a * b;
a := a2 + x2;
b := b2 + y2;
z := a * a + b * b;
c := c + 1;
end;
if (c = 255) then
colour(0, 0, 0)
else
colour(255 - c, (c mod 50)* 5, c);
dot(x, y);
end;
end;
if (powiekszenie < 50 * 50 * 50 * 50 * 50 * 50 * 50 * 50) then
powiekszenie := powiekszenie + powiekszenie * 0.04;
redraw();
wait(20);
end;
until (getkey() = 27);
end.
Source code and an executable created on Linux Mint 9 32-bit are attached.
-
I was asking you about pseudo fractal snow flake drawing like is on
screenshot...
-
require "turtle"
openwindow (640, 550, 32, "Snowflake")
goxy (100, 150)
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
for x = 1, 3 do
koch(150, 5)
turnright(120)
end
inkey()
You need my turtle library for this. Is this what you want (if you want anything)?
-
Thanks Tomaaz...
You need my turtle library for this. Is this what you want (if you want anything)?
of course that i need and what this means ' if you want anything? '... ???
I need this because i build wifi 2.4GHz antennas based on fractals(pseudo fractals).
And like you may see on my picture,it is small fractal antenna.
red and blue lines are copper wires.
Do you understand now?
Where is this turtle lib?
I am interested in this antenna design because are simple to build and have good gain.
On screenshot you can see my last design based on 'curtain quad' antenna.
-
need and what this means ' if you want anything? '... ???
I wasn't sure because you were talking about the past ("I was asking..."). The library is attached to this post. Keep it in the same folder where the Snowflake source code.
You can experiment with bolded values to get different effect:
...
forward(3*x)
...
for x = 1, 3 do
koch(120, 5)
turnright(120)
end
-
Yes 'was'.... ;D
Ok thanks.. ;)