188 lines
3.8 KiB
Text
188 lines
3.8 KiB
Text
# -*- ObjectIcon -*-
|
|
|
|
import graphics
|
|
import ipl.graphics
|
|
import io
|
|
import util(Math)
|
|
|
|
procedure main ()
|
|
local w
|
|
local width, height
|
|
local xcenter, ycenter, pixels_per_unit, max_iter
|
|
local zoom_ratio
|
|
|
|
write ("q or Q : quit")
|
|
write ("left press : recenter")
|
|
write ("+ : zoom in")
|
|
write ("- : zoom in")
|
|
write ("2 .. 9 : set zoom ratio")
|
|
write ("o or O : restore original")
|
|
write ("p or P : dump to a PNG")
|
|
|
|
width := 400
|
|
height := 400
|
|
|
|
pixels_per_unit := 150
|
|
max_iter := 200
|
|
zoom_ratio := 2
|
|
xcenter := -0.75
|
|
ycenter := 0.0
|
|
|
|
w := Window().
|
|
set_size(width, height).
|
|
set_resize(&yes).
|
|
set_bg("white").
|
|
set_canvas("normal") | stop(&why)
|
|
|
|
event_loop (w, xcenter, ycenter, pixels_per_unit, max_iter,
|
|
zoom_ratio)
|
|
end
|
|
|
|
procedure event_loop (w, xcenter, ycenter, pixels_per_unit,
|
|
max_iter, zoom_ratio)
|
|
local event
|
|
local xy
|
|
local png_number, png_name
|
|
local redraw
|
|
local width, height
|
|
local xleft, ytop
|
|
local i, j
|
|
local cx, cy, step
|
|
local iter, color
|
|
|
|
png_number := 1
|
|
|
|
redraw := &yes
|
|
repeat
|
|
{
|
|
if \redraw then
|
|
{
|
|
w.erase_area()
|
|
|
|
step := 1.0 / pixels_per_unit
|
|
|
|
width := w.get_width()
|
|
height := w.get_height()
|
|
|
|
xleft := xcenter - (width / (2.0 * pixels_per_unit))
|
|
ytop := ycenter + (height / (2.0 * pixels_per_unit))
|
|
|
|
cx := xleft
|
|
cy := ytop
|
|
|
|
j := 0
|
|
i := 0
|
|
|
|
redraw := &no
|
|
}
|
|
|
|
if j ~= height then
|
|
{
|
|
iter := count_mandelbrot_iterations (cx, cy, max_iter)
|
|
color := map_iterations_to_color (max_iter, iter)
|
|
w.set_fg (color)
|
|
w.draw_point (i, j)
|
|
i +:= 1; cx +:= step
|
|
if i = width then
|
|
{
|
|
i := 0; cx := xleft
|
|
j +:= 1; cy -:= step
|
|
}
|
|
}
|
|
|
|
if *w.pending() ~= 0 then
|
|
{
|
|
event := w.event()
|
|
case event[1] of
|
|
{
|
|
QuitEvents():
|
|
exit()
|
|
|
|
Mouse.LEFT_PRESS:
|
|
{
|
|
xy := window_coords_to_point (w, event[2], event[3],
|
|
xcenter, ycenter,
|
|
pixels_per_unit)
|
|
xcenter := xy[1]
|
|
ycenter := xy[2]
|
|
redraw := &yes
|
|
}
|
|
|
|
"+":
|
|
{
|
|
pixels_per_unit := zoom_ratio * pixels_per_unit
|
|
redraw := &yes
|
|
}
|
|
|
|
"-":
|
|
{
|
|
pixels_per_unit :=
|
|
max (1, (1.0 / zoom_ratio) * pixels_per_unit)
|
|
redraw := &yes
|
|
}
|
|
|
|
!"23456789":
|
|
zoom_ratio := integer(event[1])
|
|
|
|
!"oO":
|
|
{
|
|
pixels_per_unit := 150
|
|
max_iter := 200
|
|
zoom_ratio := 2
|
|
xcenter := -0.75
|
|
ycenter := 0.0
|
|
redraw := &yes
|
|
}
|
|
|
|
!"pP":
|
|
{
|
|
png_name := "mandelbrot-image-" || png_number || ".png"
|
|
png_number +:= 1
|
|
w.get_pixels().to_file(png_name)
|
|
write ("Wrote ", png_name)
|
|
}
|
|
|
|
Window.RESIZE:
|
|
redraw := &yes
|
|
}
|
|
|
|
WDelay(w, 100)
|
|
}
|
|
}
|
|
end
|
|
|
|
procedure count_mandelbrot_iterations (cx, cy, max_iter)
|
|
local x, y, xsquared, ysquared, iter, tmp
|
|
|
|
x := 0
|
|
y := 0
|
|
iter := 0
|
|
until (iter = max_iter |
|
|
4 < (xsquared := x * x) + (ysquared := y * y)) do
|
|
{
|
|
tmp := xsquared - ysquared + cx
|
|
y := (2 * x * y) + cy
|
|
x := tmp
|
|
iter +:= 1
|
|
}
|
|
return iter
|
|
end
|
|
|
|
procedure map_iterations_to_color (max_iter, iter)
|
|
return "black " ||
|
|
integer((Math.log (iter) * 100.0) / Math.log (max_iter)) ||
|
|
"%"
|
|
end
|
|
|
|
procedure window_coords_to_point (w, xcoord, ycoord,
|
|
xcenter, ycenter,
|
|
pixels_per_unit)
|
|
local x, y
|
|
|
|
x := xcenter +
|
|
(((2.0 * xcoord) - w.get_width()) / (2.0 * pixels_per_unit))
|
|
y := ycenter +
|
|
((w.get_height() - (2.0 * ycoord)) / (2.0 * pixels_per_unit))
|
|
|
|
return [x, y]
|
|
end
|