(phixonline)-->
--
-- demo\rosetta\Simple_turtle_graphics.exw
-- =======================================
--
with javascript_semantics
include turtle.e -- (common code for 2D and 3D versions)
atom x = 0,
y = 0,
direction = 0
procedure walk(atom distance)
//
// Move forward by distance pixels.
//
atom start_x = x,
start_y = y,
angle = direction*PI/180
x += distance*sin(angle)
y += distance*cos(angle)
if pen_down then
cdCanvasLine(cdcanvas,start_x,start_y,x,y)
end if
end procedure
procedure right(atom angle)
direction = remainder(direction+angle,360)
end procedure
procedure left(atom angle)
right(360-angle)
end procedure
procedure move(sequence s)
-- s is a list of angles (odd elements)
-- and distances (even elements)
for i=1 to length(s) do
if odd(i) then
right(s[i])
else
walk(s[i])
end if
end for
end procedure
procedure rectangle(atom width, height)
move({0,height,90,width,90,height,90,width,90})
end procedure
procedure draw_house(atom width, height)
//
// Draw a house at the current x,y
// direction must be 0 for house to be upright
-- left(10) -- (deliberately wonky works fine too)
// -- (as long as you undo it at the end)
// house walls
rectangle(width, height)
// door (maybe some windows too would be nice...)
penup()
move({90,width/7,-90})
pendown(CD_BLUE)
rectangle(width/8,height/2.5)
penup()
move({-90,width/7,90})
// roof
walk(height)
pendown(CD_RED)
atom a = arctan(width/height)*CD_RAD2DEG,
d = sqrt(width*width+height*height)/2
move({a,d,180-a*2,d})
penup()
// return to origin({qw,qh}) and direction 0:
move({90+a,width,-90,height,180})
-- right(10)
end procedure
procedure draw_barchart(sequence nums, atom w, h)
// draw a barchart occupying the middle 60% of w,h
// nums can contain +ve and/or -ve values.
-- right(10) -- (ditto)
integer n = length(nums)
atom mx = max(max(nums),0),
mn = min(min(nums),0),
r = mx-mn, -- range
zl = abs(mn)/r*h*0.6+h/5, -- zero line
bw = w*0.6/n -- bar width
move({90,w/5,-90,zl})
pendown()
for i=1 to n do
atom ni = nums[i]/r*h*0.6
if ni>0 then
rectangle(bw,ni)
else
pendown(CD_RED)
right(90)
rectangle(-ni,bw)
left(90)
pendown(CD_BLACK)
end if
move({90,bw,-90})
end for
penup()
// return to origin({w/2,0}) and direction 0:
move({180,zl,90,w/5+bw*n,90})
-- left(10)
end procedure
function redraw_cb(Ihandle /*ih*/)
integer {width, height} = IupGetIntInt(canvas, "DRAWSIZE")
cdCanvasActivate(cdcanvas)
cdCanvasClear(cdcanvas)
atom w2 = width/2,
qw = width/4,
qh = height/4
penup()
move({0,qh,90,qw,-90})
pendown()
draw_house(qw,qh) -- house in the left half
penup()
move({180,qh,90,qw,90}) -- return to {0,0}
move({90,w2,-90}) -- barchart in the right half
draw_barchart({0.5, -4/3, 2, 1.3, 0.5},width/2,height)
move({-90,w2,90}) -- return to {0,0}
-- sanity checks
if round(x)!=0 then ?9/0 end if
if round(y)!=0 then ?9/0 end if
if round(direction)!=0 then ?9/0 end if
cdCanvasFlush(cdcanvas)
return IUP_DEFAULT
end function
IupOpen()
canvas = IupCanvas(Icallback("redraw_cb"),"RASTERSIZE=600x400")
dlg = IupDialog(canvas,`TITLE="Simple turtle graphics"`)
IupMap(dlg)
cdcanvas = cdCreateCanvas(CD_IUP, canvas)
IupShow(dlg)
IupSetAttribute(canvas, "RASTERSIZE", NULL) -- release the minimum limitation
if platform()!=JS then
IupMainLoop()
IupClose()
end if