Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,6 @@
---
category:
- Graphics
- Raster graphics operations
from: http://rosettacode.org/wiki/Mandelbrot_set
note: Fractals

View file

@ -0,0 +1,7 @@
;Task:
Generate and draw the [[wp:Mandelbrot set|Mandelbrot set]].
Note that there are [http://en.wikibooks.org/wiki/Fractals/Iterations_in_the_complex_plane/Mandelbrot_set many algorithms] to draw Mandelbrot set and there are [http://en.wikibooks.org/wiki/Pictures_of_Julia_and_Mandelbrot_sets many functions] which generate it .
<br><br>

View file

@ -0,0 +1,8 @@
F mandelbrot(a)
R (0.<50).reduce(0i, (z, _) -> z * z + @a)
F step(start, step, iterations)
R (0 .< iterations).map(i -> @start + (i * @step))
V rows = (step(1, -0.05, 41).map(y -> (step(-2.0, 0.0315, 80).map(x -> (I abs(mandelbrot(x + 1i * @y)) < 2 {*} E )))))
print(rows.map(row -> row.join()).join("\n"))

View file

@ -0,0 +1,55 @@
(defun abs-sq (z)
(+ (expt (realpart z) 2)
(expt (imagpart z) 2)))
(defun round-decimal (x places)
(/ (floor (* x (expt 10 places)) 1)
(expt 10 places)))
(defun round-complex (z places)
(complex (round-decimal (realpart z) places)
(round-decimal (imagpart z) places)))
(defun mandel-point-r (z c limit)
(declare (xargs :measure (nfix limit)))
(cond ((zp limit) 0)
((> (abs-sq z) 4) limit)
(t (mandel-point-r (+ (round-complex (* z z) 15) c)
c
(1- limit)))))
(defun mandel-point (z iters)
(- 5 (floor (mandel-point-r z z iters) (/ iters 5))))
(defun draw-mandel-row (im re cols width iters)
(declare (xargs :measure (nfix cols)))
(if (zp cols)
nil
(prog2$ (cw (coerce
(list
(case (mandel-point (complex re im)
iters)
(5 #\#)
(4 #\*)
(3 #\.)
(2 #\.)
(otherwise #\Space))) 'string))
(draw-mandel-row im
(+ re (/ (/ width 3)))
(1- cols)
width iters))))
(defun draw-mandel (im rows width height iters)
(if (zp rows)
nil
(progn$ (draw-mandel-row im -2 width width iters)
(cw "~%")
(draw-mandel (- im (/ (/ height 2)))
(1- rows)
width
height
iters))))
(defun draw-mandelbrot (width iters)
(let ((height (floor (* 1000 width) 3333)))
(draw-mandel 1 height width height iters)))

View file

@ -0,0 +1,38 @@
INT pix = 300, max iter = 256, REAL zoom = 0.33 / pix;
[-pix : pix, -pix : pix] INT plane;
COMPL ctr = 0.05 I 0.75 # center of set #;
# Compute the length of an orbit. #
PROC iterate = (COMPL z0) INT:
BEGIN COMPL z := 0, INT iter := 1;
WHILE (iter +:= 1) < max iter # not converged # AND ABS z < 2 # not diverged #
DO z := z * z + z0
OD;
iter
END;
# Compute set and find maximum orbit length. #
INT max col := 0;
FOR x FROM -pix TO pix
DO FOR y FROM -pix TO pix
DO COMPL z0 = ctr + (x * zoom) I (y * zoom);
IF (plane [x, y] := iterate (z0)) < max iter
THEN (plane [x, y] > max col | max col := plane [x, y])
FI
OD
OD;
# Make a plot. #
FILE plot;
INT num pix = 2 * pix + 1;
make device (plot, "gif", whole (num pix, 0) + "x" + whole (num pix, 0));
open (plot, "mandelbrot.gif", stand draw channel);
FOR x FROM -pix TO pix
DO FOR y FROM -pix TO pix
DO INT col = (plane [x, y] > max col | max col | plane [x, y]);
REAL c = sqrt (1- col / max col); # sqrt to enhance contrast #
draw colour (plot, c, c, c);
draw point (plot, (x + pix) / (num pix - 1), (y + pix) / (num pix - 1))
OD
OD;
close (plot)

View file

@ -0,0 +1,39 @@
begin
% -- This is an integer ascii Mandelbrot generator, translated from the %
% -- Compiler/AST Interpreter Task's ASCII Mandelbrot Set example program %
integer leftEdge, rightEdge, topEdge, bottomEdge, xStep, yStep, maxIter;
leftEdge := -420;
rightEdge := 300;
topEdge := 300;
bottomEdge := -300;
xStep := 7;
yStep := 15;
maxIter := 200;
for y0 := topEdge step - yStep until bottomEdge do begin
for x0 := leftEdge step xStep until rightEdge do begin
integer x, y, i;
string(1) theChar;
y := 0;
x := 0;
theChar := " ";
i := 0;
while i < maxIter do begin
integer x_x, y_y;
x_x := (x * x) div 200;
y_y := (y * y) div 200;
if x_x + y_y > 800 then begin
theChar := code( decode( "0" ) + i );
if i > 9 then theChar := "@";
i := maxIter
end;
y := x * y div 100 + y0;
x := x_x - y_y + x0;
i := i + 1
end while_i_lt_maxIter ;
writeon( theChar );
end for_x0 ;
write();
end for_y0
end.

View file

@ -0,0 +1,124 @@
(* The algorithm is borrowed from Wikipedia. The graphics is a
modification of the display made by the JavaScript entry. Output
from the program is a Portable Pixmap file. *)
#include "share/atspre_staload.hats"
staload "libats/libc/SATS/math.sats"
staload _ = "libats/libc/DATS/math.dats"
fn
mandel_iter {max_iter : nat}
(cx : double,
cy : double,
max_iter : int max_iter)
:<> intBtwe (0, max_iter) =
let
fun
loop {iter : nat | iter <= max_iter}
.<max_iter - iter>.
(x : double,
y : double,
iter : int iter) :<> intBtwe (0, max_iter) =
if iter = max_iter then
iter
else if 2.0 * 2.0 < (x * x) + (y * y) then
iter
else
let
val x = (x * x) - (y * y) + cx
and y = (2.0 * x * y) + cy
in
loop (x, y, succ iter)
end
in
loop (0.0, 0.0, 0)
end
fn (* Write a Portable Pixmap of the Mandelbrot set. *)
write_mandelbrot_ppm (outf : FILEref,
width : intGte 0,
height : intGte 0,
xmin : double,
xmax : double,
ymin : double,
ymax : double,
max_iter : intGte 0) : void =
let
prval [width : int] EQINT () = eqint_make_gint width
prval [height : int] EQINT () = eqint_make_gint height
macdef output (r, g, b) =
let
val r = min ($UNSAFE.cast{int} ,(r), 255)
and g = min ($UNSAFE.cast{int} ,(g), 255)
and b = min ($UNSAFE.cast{int} ,(b), 255)
in
fprint_val<uchar> (outf, $UNSAFE.cast r);
fprint_val<uchar> (outf, $UNSAFE.cast g);
fprint_val<uchar> (outf, $UNSAFE.cast b);
end
val xscale = (xmax - xmin) / g0i2f width
and yscale = (ymax - ymin) / g0i2f height
fun
loop_y {iy : nat | iy <= height}
.<height - iy>.
(iy : int iy) : void =
if iy <> height then
let
fun
loop_x {ix : nat | ix <= width}
.<width - ix>.
(ix : int ix) : void =
if ix <> width then
let
(* We want to go from top to bottom, left to right. *)
val x = xmin + (xscale * g0i2f ix)
and y = ymin + (yscale * g0i2f (height - iy))
val i = mandel_iter (x, y, max_iter)
(* We can PROVE that "i" is no greater than
"max_iter". *)
prval [i : int] EQINT () = eqint_make_gint i
prval [max_iter : int] EQINT () = eqint_make_gint max_iter
prval () = prop_verify {i <= max_iter} ()
val c = (4.0 * log (g0i2f i)) / log (g0i2f max_iter)
in
if i = max_iter then
output (0, 0, 0)
else if c < 1.0 then
output (0, 0, 255.0 * (c - 1.0))
else if c < 2.0 then
output (0, 255.0 * (c - 1.0), 255)
else
output (255.0 * (c - 2.0), 255, 255);
loop_x (succ ix)
end
in
loop_x 0;
loop_y (succ iy)
end
in
fprintln! (outf, "P6");
fprintln! (outf, width, " ", height);
fprintln! (outf, 255);
loop_y 0
end
implement
main0 () =
let
val outf = stdout_ref
val width = 1024
val height = 1024
val xmin = ~2.25
val xmax = 0.75
val ymin = ~1.5
val ymax = 1.5
val max_iter = 1000
in
write_mandelbrot_ppm (outf, width, height, xmin, xmax,
ymin, ymax, max_iter)
end

View file

@ -0,0 +1,893 @@
(*-*- ATS -*-*)
(* This program requires ats2-xprelude:
https://sourceforge.net/p/chemoelectric/ats2-xprelude
Also required is the SDL2 library for C. Not everything in the SDL
interface below is used. The interface is meant to be relatively
safe. For instance, you cannot create a window or renderer without
later destroying it, and you cannot use one at all that was not
properly created. Also you cannot accidentally use an
SDL_WindowEvent as an SDL_TextInputEvent, etc.
The program uses 32+32-bit fixed point to calculate escape times.
One does not need so many bits left of the decimal point, but this
is the fixed point format available from ats2-xprelude.
There are some "FIXME" notes below that refer to a few of the ways
the program could be improved. This is a demo version of something
I am likely to expand into a better program.
Compile the program with (for example)
"myatscc mandelbrot_task_interactive.dats"
##myatsccdef=\
patscc -std=gnu2x -O3 \
-DATS_MEMALLOC_GCBDW \
`pkg-config --define-variable=PATSHOME="${PATSHOME}" \
--cflags sdl2 ats2-xprelude bdw-gc` \
`pkg-config --define-variable=PATSHOME="${PATSHOME}" \
--variable=PATSCCFLAGS ats2-xprelude` \
-o $fname($1) $1 \
`pkg-config --define-variable=PATSHOME="${PATSHOME}" \
--libs sdl2 ats2-xprelude bdw-gc`
*)
(* How to use the program:
Left click : re-center the image
Double left-click : zoom in
Double right-click : zoom out
p or P : save an image as a Portable Arbitrary Map
q or Q : quit the program
The window is resizable.
Closing the window quits the program, just as the Q key does. *)
(*------------------------------------------------------------------*)
#include "share/atspre_staload.hats"
staload UN = "prelude/SATS/unsafe.sats"
#include "xprelude/HATS/xprelude.hats"
(* To use 32+32-bit fixed point: *)
staload "xprelude/SATS/fixed32p32.sats"
staload _ = "xprelude/DATS/fixed32p32.dats"
stadef realknd = fix32p32knd
typedef real = fixed32p32
(* Actually, one could use different kinds of real number for
different algorithms: fixed point, floating point,
multiple-precision rational, interval arithmetic, ... even
continued fractions. *)
(*------------------------------------------------------------------*)
(* This is a weak choice of ATS_EXTERN_PREFIX, but will spare us from
having to do a lot of writing. *)
#define ATS_EXTERN_PREFIX ""
extern fn atexit : (() -> void) -> int = "mac#%"
%{^
#define SDL_MAIN_HANDLED 1
#include <SDL.h>
ATSinline() atstype_bool
SDL_bool2ATS (SDL_bool b)
{
return (b == SDL_FALSE) ? atsbool_false : atsbool_true;
}
%}
typedef SDL_bool = $extype"SDL_bool"
extern fn SDL_bool2ATS (b : SDL_bool) :<> bool = "mac#%"
(* - - - - - - - - - - - - - - - - - - - - - - *)
(* Housekeeping. *)
extern fn SDL_SetMainReady () : void = "mac#%"
extern fn SDL_Init (flags : uint32) : void = "mac#%"
extern fn SDL_Quit () : void = "mac#%"
(* - - - - - - - - - - - - - - - - - - - - - - *)
(* Timers. *)
extern fn SDL_Delay (ms : uint32) : void = "mac#%"
(* - - - - - - - - - - - - - - - - - - - - - - *)
(* Video handling. *)
(* Screensavers are disabled by default, except in very early versions
of SDL2. *)
extern fn SDL_DisableScreenSaver () : void = "mac#%"
extern fn SDL_EnableScreenSaver () : void = "mac#%"
extern fn SDL_IsScreenSaverEnabled () : SDL_bool = "mac#%"
absvtype SDL_Window_ptr (p : addr) = ptr p
vtypedef SDL_Window_ptr0 = [p : addr] SDL_Window_ptr p
vtypedef SDL_Window_ptr1 = [p : agz] SDL_Window_ptr p
absvtype SDL_Renderer_ptr (p : addr) = ptr p
vtypedef SDL_Renderer_ptr0 = [p : addr] SDL_Renderer_ptr p
vtypedef SDL_Renderer_ptr1 = [p : agz] SDL_Renderer_ptr p
extern castfn SDL_Window_ptr2ptr :
{p : addr} (!SDL_Window_ptr p) -<> ptr p
extern castfn SDL_Renderer_ptr2ptr :
{p : addr} (!SDL_Renderer_ptr p) -<> ptr p
macdef SDL_INIT_EVENTS = $extval (uint32, "SDL_INIT_EVENTS")
macdef SDL_INIT_TIMER = $extval (uint32, "SDL_INIT_TIMER")
macdef SDL_INIT_VIDEO = $extval (uint32, "SDL_INIT_VIDEO")
macdef SDL_WINDOWPOS_CENTERED = $extval (int, "SDL_WINDOWPOS_CENTERED")
macdef SDL_WINDOWPOS_UNDEFINED = $extval (int, "SDL_WINDOWPOS_UNDEFINED")
macdef SDL_WINDOW_OPENGL = $extval (uint32, "SDL_WINDOW_OPENGL")
macdef SDL_WINDOW_RESIZABLE = $extval (uint32, "SDL_WINDOW_RESIZABLE")
extern fn
SDL_CreateWindow (title : string,
x : int, y : int,
w : int, h : int,
flags : uint32) : SDL_Window_ptr0 = "mac#%"
extern fn
SDL_DestroyWindow : SDL_Window_ptr1 -> void = "mac#%"
fn {}
SDL_DestroyWindow_null
(window : SDL_Window_ptr null) : void =
$UN.castvwtp0{void} window
extern fn
SDL_CreateRenderer (window : !SDL_Window_ptr1,
index : int,
flags : uint32) : SDL_Renderer_ptr0 = "mac#%"
extern fn
SDL_DestroyRenderer : SDL_Renderer_ptr1 -> void = "mac#%"
fn {}
SDL_DestroyRenderer_null
(renderer : SDL_Renderer_ptr null) : void =
$UN.castvwtp0{void} renderer
extern fn
SDL_GetRendererOutputSize (renderer : !SDL_Renderer_ptr1,
w : &int? >> int,
h : &int? >> int) : int = "mac#%"
extern fn
SDL_SetRenderDrawColor (renderer : !SDL_Renderer_ptr1,
r : uint8,
g : uint8,
b : uint8,
a : uint8) : int = "mac#%"
extern fn
SDL_RenderClear (renderer : !SDL_Renderer_ptr1) : int = "mac#%"
extern fn
SDL_RenderDrawPoint (renderer : !SDL_Renderer_ptr1,
x : int,
y : int) : int = "mac#%"
extern fn
SDL_RenderPresent (renderer : !SDL_Renderer_ptr1) : void = "mac#%"
(* - - - - - - - - - - - - - - - - - - - - - - *)
(* Event handling. *)
typedef SDL_Event (t : int) =
$extype_struct"SDL_Event" of
{
type = uint32 t,
timestamp = uint32
}
typedef SDL_Event = [t : int] SDL_Event t
extern fn
SDL_PollEvent (event : &SDL_Event? >> SDL_Event)
: intBtwe (0, 1) = "mac#%"
extern fn
SDL_GetMouseState (x : &int? >> int,
y : &int? >> int) : uint32 = "mac#%"
macdef SDL_BUTTON_LMASK = $extval (uint32, "SDL_BUTTON_LMASK")
macdef SDL_BUTTON_MMASK = $extval (uint32, "SDL_BUTTON_MMASK")
macdef SDL_BUTTON_RMASK = $extval (uint32, "SDL_BUTTON_RMASK")
macdef SDL_BUTTON_X1MASK = $extval (uint32, "SDL_BUTTON_X1MASK")
macdef SDL_BUTTON_X2MASK = $extval (uint32, "SDL_BUTTON_X2MASK")
(* - - - - - - - - - - - - - *)
stacst SDL_QUIT : int
macdef SDL_QUIT = $extval (uint32 SDL_QUIT, "SDL_QUIT")
typedef SDL_QuitEvent =
$extype_struct"SDL_QuitEvent" of
{
type = uint32 SDL_QUIT,
timestamp = uint32
}
extern praxi
SDL_Event2QuitEvent_v :
{p : addr}
SDL_Event SDL_QUIT @ p -<prf>
@(SDL_QuitEvent @ p,
SDL_QuitEvent @ p -<lin,prf> SDL_Event SDL_QUIT @ p)
(* - - - - - - - - - - - - - *)
stacst SDL_WINDOWEVENT : int
macdef SDL_WINDOWEVENT = $extval (uint32 SDL_WINDOWEVENT, "SDL_WINDOWEVENT")
typedef SDL_WindowEvent =
$extype_struct"SDL_WindowEvent" of
{
type = uint32 SDL_WINDOWEVENT,
timestamp = uint32,
windowID = uint32,
event = uint8,
padding1 = uint8,
padding2 = uint8,
padding3 = uint8,
data1 = int32,
data2 = int32
}
extern praxi
SDL_Event2WindowEvent_v :
{p : addr}
SDL_Event SDL_WINDOWEVENT @ p -<prf>
@(SDL_WindowEvent @ p,
SDL_WindowEvent @ p -<lin,prf> SDL_Event SDL_WINDOWEVENT @ p)
macdef SDL_WINDOWEVENT_NONE = $extval (uint8, "SDL_WINDOWEVENT_NONE")
macdef SDL_WINDOWEVENT_SHOWN = $extval (uint8, "SDL_WINDOWEVENT_SHOWN")
macdef SDL_WINDOWEVENT_HIDDEN = $extval (uint8, "SDL_WINDOWEVENT_HIDDEN")
macdef SDL_WINDOWEVENT_EXPOSED = $extval (uint8, "SDL_WINDOWEVENT_EXPOSED")
macdef SDL_WINDOWEVENT_MOVED = $extval (uint8, "SDL_WINDOWEVENT_MOVED")
macdef SDL_WINDOWEVENT_RESIZED = $extval (uint8, "SDL_WINDOWEVENT_RESIZED")
macdef SDL_WINDOWEVENT_SIZE_CHANGED = $extval (uint8, "SDL_WINDOWEVENT_SIZE_CHANGED")
macdef SDL_WINDOWEVENT_MINIMIZED = $extval (uint8, "SDL_WINDOWEVENT_MINIMIZED")
macdef SDL_WINDOWEVENT_MAXIMIZED = $extval (uint8, "SDL_WINDOWEVENT_MAXIMIZED")
macdef SDL_WINDOWEVENT_RESTORED = $extval (uint8, "SDL_WINDOWEVENT_RESTORED")
macdef SDL_WINDOWEVENT_ENTER = $extval (uint8, "SDL_WINDOWEVENT_ENTER")
macdef SDL_WINDOWEVENT_LEAVE = $extval (uint8, "SDL_WINDOWEVENT_LEAVE")
macdef SDL_WINDOWEVENT_FOCUS_GAINED = $extval (uint8, "SDL_WINDOWEVENT_FOCUS_GAINED")
macdef SDL_WINDOWEVENT_FOCUS_LOST = $extval (uint8, "SDL_WINDOWEVENT_FOCUS_LOST")
macdef SDL_WINDOWEVENT_CLOSE = $extval (uint8, "SDL_WINDOWEVENT_CLOSE")
macdef SDL_WINDOWEVENT_TAKE_FOCUS = $extval (uint8, "SDL_WINDOWEVENT_TAKE_FOCUS")
macdef SDL_WINDOWEVENT_HIT_TEST = $extval (uint8, "SDL_WINDOWEVENT_HIT_TEST")
macdef SDL_WINDOWEVENT_ICCPROF_CHANGED = $extval (uint8, "SDL_WINDOWEVENT_ICCPROF_CHANGED")
macdef SDL_WINDOWEVENT_DISPLAY_CHANGED = $extval (uint8, "SDL_WINDOWEVENT_DISPLAY_CHANGED")
(* - - - - - - - - - - - - - *)
stacst SDL_MOUSEMOTION : int
macdef SDL_MOUSEMOTION = $extval (uint32 SDL_MOUSEMOTION, "SDL_MOUSEMOTION")
typedef SDL_MouseMotionEvent =
$extype_struct"SDL_MouseMotionEvent" of
{
type = uint32 SDL_MOUSEMOTION,
timestamp = uint32,
windowID = uint32,
which = uint32,
state = uint32,
x = int32,
y = int32,
xrel = int32,
yrel = int32
}
extern praxi
SDL_Event2MouseMotionEvent_v :
{p : addr}
SDL_Event SDL_MOUSEMOTION @ p -<prf>
@(SDL_MouseMotionEvent @ p,
SDL_MouseMotionEvent @ p -<lin,prf> SDL_Event SDL_MOUSEMOTION @ p)
(* - - - - - - - - - - - - - *)
stacst SDL_MOUSEBUTTONDOWN : int
macdef SDL_MOUSEBUTTONDOWN = $extval (uint32 SDL_MOUSEBUTTONDOWN, "SDL_MOUSEBUTTONDOWN")
stacst SDL_MOUSEBUTTONUP : int
macdef SDL_MOUSEBUTTONUP = $extval (uint32 SDL_MOUSEBUTTONUP, "SDL_MOUSEBUTTONUP")
typedef SDL_MouseButtonEvent (t : int) =
[t == SDL_MOUSEBUTTONDOWN || t == SDL_MOUSEBUTTONUP]
$extype_struct"SDL_MouseButtonEvent" of
{
type = uint32 t,
timestamp = uint32,
windowID = uint32,
which = uint32,
button = uint8,
state = uint8,
clicks = uint8,
padding1 = uint8,
x = int32,
y = int32
}
typedef SDL_MouseButtonEvent = [t : int] SDL_MouseButtonEvent t
extern praxi
SDL_Event2MouseButtonEvent_v :
{p : addr}
{t : int | t == SDL_MOUSEBUTTONDOWN || t == SDL_MOUSEBUTTONUP}
SDL_Event t @ p -<prf>
@(SDL_MouseButtonEvent t @ p,
SDL_MouseButtonEvent t @ p -<lin,prf> SDL_Event t @ p)
macdef SDL_BUTTON_LEFT = $extval (uint8, "SDL_BUTTON_LEFT")
macdef SDL_BUTTON_MIDDLE = $extval (uint8, "SDL_BUTTON_MIDDLE")
macdef SDL_BUTTON_RIGHT = $extval (uint8, "SDL_BUTTON_RIGHT")
macdef SDL_BUTTON_X1 = $extval (uint8, "SDL_BUTTON_X1")
macdef SDL_BUTTON_X2 = $extval (uint8, "SDL_BUTTON_X2")
macdef SDL_PRESSED = $extval (uint8, "SDL_PRESSED")
macdef SDL_RELEASED = $extval (uint8, "SDL_RELEASED")
(* - - - - - - - - - - - - - *)
stacst SDL_TEXTINPUT : int
macdef SDL_TEXTINPUT = $extval (uint32 SDL_TEXTINPUT, "SDL_TEXTINPUT")
#define SDL_TEXTINPUTEVENT_TEXT_SIZE 32
typedef SDL_TextInputEvent =
$extype_struct"SDL_TextInputEvent" of
{
type = uint32 SDL_TEXTINPUT,
timestamp = uint32,
windowID = uint32,
text = @[char][SDL_TEXTINPUTEVENT_TEXT_SIZE]
}
extern praxi
SDL_Event2TextInputEvent_v :
{p : addr}
SDL_Event SDL_TEXTINPUT @ p -<prf>
@(SDL_TextInputEvent @ p,
SDL_TextInputEvent @ p -<lin,prf> SDL_Event SDL_TEXTINPUT @ p)
(*------------------------------------------------------------------*)
exception bailout of string
typedef rgba = @(uint8, uint8, uint8, uint8)
val empty_scene_color =
@(g0i2u 200, g0i2u 200, g0i2u 200, g0i2u 255) : rgba
typedef rgba_array (w : int, h : int) =
matrixref (rgba, w, h)
typedef scene_computer =
{w, h : nat}
(int w, int h, real, real, real) -<cloref1>
rgba_array (w, h)
vtypedef situation (p : addr, q : addr,
w : int, h : int) =
[null < p; null < q; 0 <= w; 0 <= h]
@{window = SDL_Window_ptr p,
renderer = SDL_Renderer_ptr q,
width = int w,
height = int h,
xcenter = real,
ycenter = real,
pixels_per_unit = real,
compute_scene = scene_computer}
vtypedef situation (w : int, h : int) =
[p, q : agz]
situation (p, q, w, h)
vtypedef situation =
[w, h : nat]
situation (w, h)
fn
destroy_situation (situation : situation) : void =
begin
SDL_DestroyRenderer (situation.renderer);
SDL_DestroyWindow (situation.window)
end
fn
get_renderer_size (situation : &situation)
: [renderer_width, renderer_height : nat]
@(int renderer_width, int renderer_height) =
let
var w : int
var h : int
val status = SDL_GetRendererOutputSize (situation.renderer, w, h)
val w = g1ofg0 w and h = g1ofg0 h
in
if (status < 0) + (w < 0) + (h < 0) then
begin
destroy_situation situation;
$raise bailout "rendering error"
end
else
@(w, h)
end
fn
resize_needed (situation : &situation) : bool =
let
val @(w, h) = get_renderer_size situation
in
(w <> situation.width) + (h <> situation.height)
end
(*------------------------------------------------------------------*)
fn
compute_escape_times
{w, h : nat}
{mxtm : nat}
(width : int w,
height : int h,
xcenter : real,
ycenter : real,
pixels_per_unit : real,
max_time : uint16 mxtm)
: matrixref ([tm : nat | tm <= mxtm] uint16 tm, w, h) =
let
typedef tm = [tm : nat | tm <= mxtm] uint16 tm
val times = matrixref_make_elt<tm> (i2sz width, i2sz height,
max_time)
and ppu2 = pixels_per_unit + pixels_per_unit
fun
ij_loop {i, j : nat | i <= w; j <= h}
.<w - i, h - j>.
(i : int i,
j : int j) :<!refwrt> void =
if i = width then
()
else if j = height then
ij_loop (succ i, 0)
else
let
val cx = xcenter + (g0i2f ((i + i) - width) / ppu2)
and cy = ycenter + (g0i2f (height - (j + j)) / ppu2)
fun
tm_loop {tm : nat | tm <= mxtm}
.<mxtm - tm>.
(x : real,
y : real,
xx : real,
yy : real,
tm : uint16 tm)
:<> [tm1 : nat | tm1 <= mxtm] uint16 tm1 =
if tm = max_time then
tm
else if g0i2f 4 < xx + yy then
tm
else
let
val x = xx - yy + cx and y = ((x + x) * y) + cy
val xx = x * x and yy = y * y
in
tm_loop (x, y, xx, yy, succ tm)
end
val tm = tm_loop (g0i2f 0, g0i2f 0,
g0i2f 0, g0i2f 0,
g1i2u 0)
in
times[i, height, j] := tm;
ij_loop (i, succ j)
end
in
ij_loop (0, 0);
times
end
fn
the_durn_simplest_scene_computer
{w, h : nat}
(width : int w,
height : int h,
xcenter : real,
ycenter : real,
pixels_per_unit : real)
:<cloref1> rgba_array (w, h) =
let
val escape_times =
compute_escape_times (width, height, xcenter, ycenter,
pixels_per_unit, g1i2u 255)
and points = matrixref_make_elt<rgba> (i2sz width, i2sz height,
empty_scene_color)
fn {}
time2rgba {tm : nat | tm <= 255}
(tm : uint16 tm) : rgba =
let
val v = (g0u2u (g1i2u 255 - tm)) : uint8
in
@(v, v, v, g0i2u 255)
end
fun
loop {i, j : nat | i <= w; j <= h}
.<w - i, h - j>.
(i : int i,
j : int j) : void =
if i = width then
()
else if j = height then
loop (succ i, 0)
else
begin
points[i, height, j] :=
time2rgba escape_times[i, height, j];
loop (i, succ j)
end
in
loop (0, 0);
points
end
(*------------------------------------------------------------------*)
(* Writing an image to a Portable Arbitrary Map. *)
fn
write_rgba_points_as_pam
{w, h : nat}
(outf : FILEref,
width : int w,
height : int h,
points : rgba_array (w, h)) : void =
let
fun
loop {i, j : nat | i <= w; j <= h}
.<h - j, w - i>.
(i : int i,
j : int j) : void =
if j = height then
()
else if i = width then
loop (0, succ j)
else
let
val @(r, g, b, a) = points[i, height, j]
in
fprint! (outf, int2uchar0 (g0u2i r));
fprint! (outf, int2uchar0 (g0u2i g));
fprint! (outf, int2uchar0 (g0u2i b));
fprint! (outf, int2uchar0 (g0u2i a));
loop (succ i, j)
end
in
(* Portable Arbitrary Map:
https://netpbm.sourceforge.net/doc/pam.html *)
fprintln! (outf, "P7");
fprintln! (outf, "WIDTH ", width);
fprintln! (outf, "HEIGHT ", height);
fprintln! (outf, "DEPTH 4");
fprintln! (outf, "MAXVAL 255");
fprintln! (outf, "TUPLTYPE RGB_ALPHA");
fprintln! (outf, "ENDHDR");
loop (0, 0)
end
(* For this demo, simply number the images, starting at 1 on each run
of the program. *)
val image_number : ref uint = ref 1U
fn
write_image {w, h : nat}
(width : int w,
height : int h,
points : rgba_array (w, h)) : void =
let
val filename =
strptr2string (string_append ("mandelbrot-image-",
tostring_val<uint> !image_number,
".pam"))
in
case+ fileref_open_opt (filename, file_mode_w) of
| ~ None_vt () =>
println! ("ERROR: could not open ", filename, " for writing.")
| ~ Some_vt outf =>
begin
write_rgba_points_as_pam (outf, width, height, points);
fileref_close (outf);
println! ("SUCCESS: wrote ", filename);
!image_number := succ !image_number
end
end
(*------------------------------------------------------------------*)
val initial_width : intGte 0 = 400
val initial_height : intGte 0 = 400
val initial_xcenter : real = g0f2f ~0.75
val initial_ycenter : real = g0f2f 0.0
val initial_pixels_per_unit : real = g0f2f 150.0
val initial_scene_computer : scene_computer =
the_durn_simplest_scene_computer
(* Zoom factor could be adjustable, but is not in this simple demo. *)
val zoom_factor : real = g0f2f 2.0
val min_pixels_per_unit : real = g0f2f 10.0
fn
set_render_rgba (renderer : !SDL_Renderer_ptr1,
rgba : rgba) : int =
let
val @(r, g, b, a) = rgba
in
SDL_SetRenderDrawColor (renderer, r, g, b, a)
end
fn
draw_scene {w, h : nat}
(renderer : !SDL_Renderer_ptr1,
width : int w,
height : int h,
points : rgba_array (w, h)) : void =
let
prval () = mul_gte_gte_gte {w, h} ()
fun
loop {i, j : nat | i <= w; j <= h}
.<w - i, h - j>.
(renderer : !SDL_Renderer_ptr1,
i : int i,
j : int j) : void =
if i = width then
()
else if j = height then
loop (renderer, succ i, 0)
else
let
val rgba = points[i, height, j]
val _ = set_render_rgba (renderer, rgba)
val _ = SDL_RenderDrawPoint (renderer, i, j)
in
loop (renderer, i, succ j)
end
in
ignoret (set_render_rgba (renderer, empty_scene_color));
ignoret (SDL_RenderClear (renderer));
loop (renderer, 0, 0);
end
fnx
situation_changed
{w, h : nat}
(situation : &situation (w, h) >> situation,
event : &SDL_Event? >> SDL_Event) : void =
let
val compute_scene = situation.compute_scene
val points =
compute_scene (situation.width, situation.height,
situation.xcenter, situation.ycenter,
situation.pixels_per_unit)
in
SDL_Delay (g0i2u 16);
event_loop (situation, points, event)
end
and
event_loop {w, h : nat}
(situation : &situation (w, h) >> situation,
points : rgba_array (w, h),
event : &SDL_Event? >> SDL_Event) : void =
let
macdef quit_the_event_loop =
()
macdef present_the_scene =
present_scene (situation, points, event)
macdef deal_with_changed_situation =
situation_changed (situation, event)
macdef write_an_image =
write_image (situation.width, situation.height, points);
in
if resize_needed situation then
let
val @(w, h) = get_renderer_size situation
in
situation.width := w;
situation.height := h;
deal_with_changed_situation
end
else
let
in
draw_scene (situation.renderer,
situation.width, situation.height,
points);
case+ SDL_PollEvent (event) of
| 0 => present_the_scene
| 1 =>
if event.type = SDL_QUIT then
quit_the_event_loop
else if event.type = SDL_WINDOWEVENT then
let
prval @(pf, fpf) = SDL_Event2WindowEvent_v (view@ event)
prval () = view@ event := pf
val window_event = event
prval () = view@ event := fpf (view@ event)
in
if window_event.event = SDL_WINDOWEVENT_SIZE_CHANGED then
deal_with_changed_situation
else if window_event.event = SDL_WINDOWEVENT_CLOSE then
quit_the_event_loop
else
present_the_scene
end
else if event.type = SDL_MOUSEBUTTONDOWN then
let
prval @(pf, fpf) = SDL_Event2MouseButtonEvent_v (view@ event)
prval () = view@ event := pf
val button_event = event
prval () = view@ event := fpf (view@ event)
in
if button_event.button = SDL_BUTTON_LEFT then
begin
if button_event.clicks = g0i2u 1 then
let (* Re-center. *)
val x = g0i2i button_event.x
and y = g0i2i button_event.y
and w = situation.width
and h = situation.height
and ppu = situation.pixels_per_unit
val ppu2 = ppu + ppu
in
situation.xcenter :=
situation.xcenter + (g0i2f (x + x - w) / ppu2);
situation.ycenter :=
situation.ycenter + (g0i2f (h - y - y) / ppu2);
deal_with_changed_situation
end
else
let (* Zoom in. *)
val new_ppu = situation.pixels_per_unit * zoom_factor
in
situation.pixels_per_unit := new_ppu;
deal_with_changed_situation
end
end
else if button_event.button = SDL_BUTTON_RIGHT then
begin
if button_event.clicks = g0i2u 1 then
present_the_scene
else
let (* Zoom out *)
val new_ppu = situation.pixels_per_unit / zoom_factor
in
if min_pixels_per_unit <= new_ppu then
situation.pixels_per_unit := new_ppu;
deal_with_changed_situation
end
end
else
present_the_scene
end
else if event.type = SDL_TEXTINPUT then
let
prval @(pf, fpf) = SDL_Event2TextInputEvent_v (view@ event)
prval () = view@ event := pf
var text_event = event
prval () = view@ event := fpf (view@ event)
macdef text = text_event.text
in
case+ @(text[0], text[1]) of
| @('q', '\0') => quit_the_event_loop
| @('Q', '\0') => quit_the_event_loop
| @('p', '\0') =>
begin
write_an_image;
present_the_scene
end
| @('P', '\0') =>
begin
write_an_image;
present_the_scene
end
| _ => present_the_scene
end
else
present_the_scene
end
end
and
present_scene {w, h : nat}
(situation : &situation (w, h) >> situation,
points : rgba_array (w, h),
event : &SDL_Event? >> SDL_Event) : void =
begin
SDL_RenderPresent (situation.renderer);
SDL_Delay (g0i2u 16);
event_loop (situation, points, event)
end
fn
run_program () : void =
let
(* FIXME: For best form, we should also set up a signal handler
that runs SDL_Quit, so the display does not get stuck in an
undesired state even if the program crashes. For instance,
there could be a signaled divide by zero or overflow event. And
we are at least changing whether the screensaver is enabled. *)
val _ = atexit SDL_Quit
val () = SDL_Init (SDL_INIT_EVENTS
lor SDL_INIT_TIMER
lor SDL_INIT_VIDEO)
(* FIXME: Find out whether the screensaver was enabled BEFORE we
started SDL2, and set SDL2 to whichever setting it was. *)
val () = SDL_EnableScreenSaver ()
val window = SDL_CreateWindow ("mandelbrot_task_interactive",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
initial_width, initial_height,
SDL_WINDOW_RESIZABLE)
val p_window = SDL_Window_ptr2ptr window
prval () = lemma_ptr_param p_window
in
if iseqz p_window then
begin
SDL_DestroyWindow_null window;
$raise bailout "failed to initialize a window"
end
else
let
val renderer = SDL_CreateRenderer (window, ~1, g0i2u 0)
val p_renderer = SDL_Renderer_ptr2ptr renderer
prval () = lemma_ptr_param p_renderer
in
if iseqz p_renderer then
begin
SDL_DestroyRenderer_null renderer;
SDL_DestroyWindow window;
$raise bailout "failed to initialize a renderer"
end
else
let
var situation : situation =
@{window = window,
renderer = renderer,
width = initial_width,
height = initial_height,
xcenter = initial_xcenter,
ycenter = initial_ycenter,
pixels_per_unit = initial_pixels_per_unit,
compute_scene = initial_scene_computer}
var event : SDL_Event?
in
situation_changed (situation, event);
destroy_situation situation
end
end
end
implement
main () =
try
begin
SDL_SetMainReady ();
run_program ();
0
end
with
| ~ bailout msg =>
begin
println! ("Error: ", msg);
1
end
(*------------------------------------------------------------------*)

View file

@ -0,0 +1,22 @@
BEGIN {
XSize=59; YSize=21;
MinIm=-1.0; MaxIm=1.0;MinRe=-2.0; MaxRe=1.0;
StepX=(MaxRe-MinRe)/XSize; StepY=(MaxIm-MinIm)/YSize;
for(y=0;y<YSize;y++)
{
Im=MinIm+StepY*y;
for(x=0;x<XSize;x++)
{
Re=MinRe+StepX*x; Zr=Re; Zi=Im;
for(n=0;n<30;n++)
{
a=Zr*Zr; b=Zi*Zi;
if(a+b>4.0) break;
Zi=2*Zr*Zi+Im; Zr=a-b+Re;
}
printf "%c",62-n;
}
print "";
}
exit;
}

View file

@ -0,0 +1,40 @@
with Lumen.Binary;
package body Mandelbrot is
function Create_Image (Width, Height : Natural) return Lumen.Image.Descriptor is
use type Lumen.Binary.Byte;
Result : Lumen.Image.Descriptor;
X0, Y0 : Float;
X, Y, Xtemp : Float;
Iteration : Float;
Max_Iteration : constant Float := 1000.0;
Color : Lumen.Binary.Byte;
begin
Result.Width := Width;
Result.Height := Height;
Result.Complete := True;
Result.Values := new Lumen.Image.Pixel_Matrix (1 .. Width, 1 .. Height);
for Screen_X in 1 .. Width loop
for Screen_Y in 1 .. Height loop
X0 := -2.5 + (3.5 / Float (Width) * Float (Screen_X));
Y0 := -1.0 + (2.0 / Float (Height) * Float (Screen_Y));
X := 0.0;
Y := 0.0;
Iteration := 0.0;
while X * X + Y * Y <= 4.0 and then Iteration < Max_Iteration loop
Xtemp := X * X - Y * Y + X0;
Y := 2.0 * X * Y + Y0;
X := Xtemp;
Iteration := Iteration + 1.0;
end loop;
if Iteration = Max_Iteration then
Color := 255;
else
Color := 0;
end if;
Result.Values (Screen_X, Screen_Y) := (R => Color, G => Color, B => Color, A => 0);
end loop;
end loop;
return Result;
end Create_Image;
end Mandelbrot;

View file

@ -0,0 +1,7 @@
with Lumen.Image;
package Mandelbrot is
function Create_Image (Width, Height : Natural) return Lumen.Image.Descriptor;
end Mandelbrot;

View file

@ -0,0 +1,155 @@
with System.Address_To_Access_Conversions;
with Lumen.Window;
with Lumen.Image;
with Lumen.Events;
with GL;
with Mandelbrot;
procedure Test_Mandelbrot is
Program_End : exception;
Win : Lumen.Window.Handle;
Image : Lumen.Image.Descriptor;
Tx_Name : aliased GL.GLuint;
Wide, High : Natural := 400;
-- Create a texture and bind a 2D image to it
procedure Create_Texture is
use GL;
package GLB is new System.Address_To_Access_Conversions (GLubyte);
IP : GLpointer;
begin -- Create_Texture
-- Allocate a texture name
glGenTextures (1, Tx_Name'Unchecked_Access);
-- Bind texture operations to the newly-created texture name
glBindTexture (GL_TEXTURE_2D, Tx_Name);
-- Select modulate to mix texture with color for shading
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-- Wrap textures at both edges
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-- How the texture behaves when minified and magnified
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-- Create a pointer to the image. This sort of horror show is going to
-- be disappearing once Lumen includes its own OpenGL bindings.
IP := GLB.To_Pointer (Image.Values.all'Address).all'Unchecked_Access;
-- Build our texture from the image we loaded earlier
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, GLsizei (Image.Width), GLsizei (Image.Height), 0,
GL_RGBA, GL_UNSIGNED_BYTE, IP);
end Create_Texture;
-- Set or reset the window view parameters
procedure Set_View (W, H : in Natural) is
use GL;
begin -- Set_View
GL.glEnable (GL.GL_TEXTURE_2D);
glClearColor (0.8, 0.8, 0.8, 1.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity;
glViewport (0, 0, GLsizei (W), GLsizei (H));
glOrtho (0.0, GLdouble (W), GLdouble (H), 0.0, -1.0, 1.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity;
end Set_View;
-- Draw our scene
procedure Draw is
use GL;
begin -- Draw
-- clear the screen
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
GL.glBindTexture (GL.GL_TEXTURE_2D, Tx_Name);
-- fill with a single textured quad
glBegin (GL_QUADS);
begin
glTexCoord2f (1.0, 0.0);
glVertex2i (GLint (Wide), 0);
glTexCoord2f (0.0, 0.0);
glVertex2i (0, 0);
glTexCoord2f (0.0, 1.0);
glVertex2i (0, GLint (High));
glTexCoord2f (1.0, 1.0);
glVertex2i (GLint (Wide), GLint (High));
end;
glEnd;
-- flush rendering pipeline
glFlush;
-- Now show it
Lumen.Window.Swap (Win);
end Draw;
-- Simple event handler routine for keypresses and close-window events
procedure Quit_Handler (Event : in Lumen.Events.Event_Data) is
begin -- Quit_Handler
raise Program_End;
end Quit_Handler;
-- Simple event handler routine for Exposed events
procedure Expose_Handler (Event : in Lumen.Events.Event_Data) is
pragma Unreferenced (Event);
begin -- Expose_Handler
Draw;
end Expose_Handler;
-- Simple event handler routine for Resized events
procedure Resize_Handler (Event : in Lumen.Events.Event_Data) is
begin -- Resize_Handler
Wide := Event.Resize_Data.Width;
High := Event.Resize_Data.Height;
Set_View (Wide, High);
-- Image := Mandelbrot.Create_Image (Width => Wide, Height => High);
-- Create_Texture;
Draw;
end Resize_Handler;
begin
-- Create Lumen window, accepting most defaults; turn double buffering off
-- for simplicity
Lumen.Window.Create (Win => Win,
Name => "Mandelbrot fractal",
Width => Wide,
Height => High,
Events => (Lumen.Window.Want_Exposure => True,
Lumen.Window.Want_Key_Press => True,
others => False));
-- Set up the viewport and scene parameters
Set_View (Wide, High);
-- Now create the texture and set up to use it
Image := Mandelbrot.Create_Image (Width => Wide, Height => High);
Create_Texture;
-- Enter the event loop
declare
use Lumen.Events;
begin
Select_Events (Win => Win,
Calls => (Key_Press => Quit_Handler'Unrestricted_Access,
Exposed => Expose_Handler'Unrestricted_Access,
Resized => Resize_Handler'Unrestricted_Access,
Close_Window => Quit_Handler'Unrestricted_Access,
others => No_Callback));
end;
exception
when Program_End =>
null;
end Test_Mandelbrot;

View file

@ -0,0 +1,43 @@
#!/usr/bin/hopper
#include <jambo.h>
Main
Initialize '300, ancho, alto'
Set '-2,0.47,-1.12,1.12' Init 'min real, max real, min complex, max complex'
Init zero 'submaxRminR, submaxCminC'
Let ( submaxRminR := 'max real' Minus 'min real')
Let ( submaxCminC := 'maxcomplex' Minus 'mincomplex' )
Init zero 'a2,b2,a,b,ta'
Loop for (i=1, Less equal(i, ancho),++i)
Let ( ta := Add(min real, Div ( Mul( submaxRminR, Minus one(i)), Minus one(ancho) )) )
Loop for (j=1, Less equal (j, alto),++j)
Let ( b := Add( min complex, Div ( Mul (submaxCminC, Minus one(j)), Minus one(alto))) )
a=ta, a2=a, b2=b
k=1000, color=256
Loop if (Sqradd (a,b) Is less than (4), And (k) )
Add(Sqrdiff(a,b), a2),
Add(b2, Mul(2, Mul(a, b)))
Move to (b), Move to (a)
--color
--k
Back
Color back (color), Print("O")
Back
Prnl
Back
Pause
End

View file

@ -0,0 +1,48 @@
SCREEN 1,320,200,5,1
WINDOW 2,"Mandelbrot",,0,1
maxIteration = 100
xmin = -2
xmax = 1
ymin = -1.5
ymax = 1.5
xs = 300
ys = 180
st = .01 ' use e.g. st = .05 for a coarser but faster picture
' and perhaps also lower maxIteration = 10 or so
xp = xs / (xmax - xmin) * st
yp = ys / (ymax - ymin) * st
FOR x0 = xmin TO xmax STEP st
FOR y0 = ymin TO ymax STEP st
x = 0
y = 0
iteration = 0
WHILE (x * x + y * y <= (2 * 2) AND iteration < maxIteration)
xtemp = x * x - y * y + x0
y = 2 * x * y + y0
x = xtemp
iteration = iteration + 1
WEND
IF iteration <> maxIteration THEN
c = iteration
ELSE
c = 0
END IF
COLOR c MOD 32
AREA ((x0 - xmin) * xp / st, (y0 - ymin) * yp / st)
AREA STEP (xp, 0)
AREA STEP (0, yp)
AREA STEP (-xp, 0)
AREA STEP (0, -yp)
AREAFILL
NEXT
NEXT
' endless loop, use Run -> Stop from the menu to stop program
WHILE (1)
WEND

View file

@ -0,0 +1,36 @@
10 HGR2
20 XC = -0.5 : REM CENTER COORD X
30 YC = 0 : REM " " Y
40 S = 2 : REM SCALE
45 IT = 20 : REM ITERATIONS
50 XR = S * (280 / 192): REM TOTAL RANGE OF X
60 YR = S : REM " " " Y
70 X0 = XC - (XR/2) : REM MIN VALUE OF X
80 X1 = XC + (XR/2) : REM MAX " " X
90 Y0 = YC - (YR/2) : REM MIN " " Y
100 Y1 = YC + (YR/2) : REM MAX " " Y
110 XM = XR / 279 : REM SCALING FACTOR FOR X
120 YM = YR / 191 : REM " " " Y
130 FOR YI = 0 TO 3 : REM INTERLEAVE
140 FOR YS = 0+YI TO 188+YI STEP 4 : REM Y SCREEN COORDINATE
145 HCOLOR=3 : HPLOT 0,YS TO 279,YS
150 FOR XS = 0 TO 278 STEP 2 : REM X SCREEN COORDINATE
170 X = XS * XM + X0 : REM TRANSL SCREEN TO TRUE X
180 Y = YS * YM + Y0 : REM TRANSL SCREEN TO TRUE Y
190 ZX = 0
200 ZY = 0
210 XX = 0
220 YY = 0
230 FOR I = 0 TO IT
240 ZY = 2 * ZX * ZY + Y
250 ZX = XX - YY + X
260 XX = ZX * ZX
270 YY = ZY * ZY
280 C = IT-I
290 IF XX+YY >= 4 GOTO 301
300 NEXT I
301 IF C >= 8 THEN C = C - 8 : GOTO 301
310 HCOLOR = C : HPLOT XS, YS TO XS+1, YS
320 NEXT XS
330 NEXT YS
340 NEXT YI

View file

@ -0,0 +1,3 @@
150 FOR XS = 0 TO 279
301 C = (C - INT(C/2)*2)*3
310 HCOLOR = C: HPLOT XS, YS

View file

@ -0,0 +1,28 @@
inMandelbrot?: function [c][
z: to :complex [0 0]
do.times: 50 [
z: c + z*z
if 4 < abs z -> return false
]
return true
]
mandelbrot: function [settings][
y: 0
while [y < settings\height][
Y: settings\yStart + y * settings\yStep
x: 0
while [x < settings\width][
X: settings\xStart + x * settings\xStep
if? inMandelbrot? to :complex @[X Y] -> prints "*"
else -> prints " "
x: x + 1
]
print ""
y: y + 1
]
]
mandelbrot #[ yStart: 1.0 yStep: neg 0.05
xStart: neg 2.0 xStep: 0.0315
height: 40 width: 80 ]

View file

@ -0,0 +1,117 @@
Max_Iteration := 256
Width := Height := 400
File := "MandelBrot." Width ".bmp"
Progress, b2 w400 fs9, Creating Colours ...
Gosub, CreateColours
Gosub, CreateBitmap
Progress, Off
Gui, -Caption
Gui, Margin, 0, 0
Gui, Add, Picture,, %File%
Gui, Show,, MandelBrot
Return
GuiClose:
GuiEscape:
ExitApp
;---------------------------------------------------------------------------
CreateBitmap: ; create and save a 32bit bitmap file
;---------------------------------------------------------------------------
; define header details
HeaderBMP := 14
HeaderDIB := 40
DataOffset := HeaderBMP + HeaderDIB
ImageSize := Width * Height * 4 ; 32bit
FileSize := DataOffset + ImageSize
Resolution := 3780 ; from mspaint
; create bitmap header
VarSetCapacity(IMAGE, FileSize, 0)
NumPut(Asc("B") , IMAGE, 0x00, "Char")
NumPut(Asc("M") , IMAGE, 0x01, "Char")
NumPut(FileSize , IMAGE, 0x02, "UInt")
NumPut(DataOffset , IMAGE, 0x0A, "UInt")
NumPut(HeaderDIB , IMAGE, 0x0E, "UInt")
NumPut(Width , IMAGE, 0x12, "UInt")
NumPut(Height , IMAGE, 0x16, "UInt")
NumPut(1 , IMAGE, 0x1A, "Short") ; Planes
NumPut(32 , IMAGE, 0x1C, "Short") ; Bits per Pixel
NumPut(ImageSize , IMAGE, 0x22, "UInt")
NumPut(Resolution , IMAGE, 0x26, "UInt")
NumPut(Resolution , IMAGE, 0x2A, "UInt")
; fill in Data
Gosub, CreatePixels
; save Bitmap to file
FileDelete, %File%
Handle := DllCall("CreateFile", "Str", File, "UInt", 0x40000000
, "UInt", 0, "UInt", 0, "UInt", 2, "UInt", 0, "UInt", 0)
DllCall("WriteFile", "UInt", Handle, "UInt", &IMAGE, "UInt"
, FileSize, "UInt *", Bytes, "UInt", 0)
DllCall("CloseHandle", "UInt", Handle)
Return
;---------------------------------------------------------------------------
CreatePixels: ; create pixels for [-2 < x < 1] [-1.5 < y < 1.5]
;---------------------------------------------------------------------------
Loop, % Height // 2 + 1 {
yi := A_Index - 1
y0 := -1.5 + yi / Height * 3 ; range -1.5 .. +1.5
Progress, % 200*yi // Height, % "Current line: " 2*yi " / " Height
Loop, %Width% {
xi := A_Index - 1
x0 := -2 + xi / Width * 3 ; range -2 .. +1
Gosub, Mandelbrot
p1 := DataOffset + 4 * (Width * yi + xi)
NumPut(Colour, IMAGE, p1, "UInt")
p2 := DataOffset + 4 * (Width * (Height-yi) + xi)
NumPut(Colour, IMAGE, p2, "UInt")
}
}
Return
;---------------------------------------------------------------------------
Mandelbrot: ; calculate a colour for each pixel
;---------------------------------------------------------------------------
x := y := Iteration := 0
While, (x*x + y*y <= 4) And (Iteration < Max_Iteration) {
xtemp := x*x - y*y + x0
y := 2*x*y + y0
x := xtemp
Iteration++
}
Colour := Iteration = Max_Iteration ? 0 : Colour_%Iteration%
Return
;---------------------------------------------------------------------------
CreateColours: ; borrowed from PureBasic example
;---------------------------------------------------------------------------
Loop, 64 {
i4 := (i3 := (i2 := (i1 := A_Index - 1) + 64) + 64) + 64
Colour_%i1% := RGB(4*i1 + 128, 4*i1, 0)
Colour_%i2% := RGB(64, 255, 4*i1)
Colour_%i3% := RGB(64, 255 - 4*i1, 255)
Colour_%i4% := RGB(64, 0, 255 - 4*i1)
}
Return
;---------------------------------------------------------------------------
RGB(r, g, b) { ; return 24bit color value
;---------------------------------------------------------------------------
Return, (r&0xFF)<<16 | g<<8 | b
}

View file

@ -0,0 +1,43 @@
main() {
auto cx,cy,x,y,x2,y2;
auto iter;
auto xmin,xmax,ymin,ymax,maxiter,dx,dy;
xmin = -8601;
xmax = 2867;
ymin = -4915;
ymax = 4915;
maxiter = 32;
dx = (xmax-xmin)/79;
dy = (ymax-ymin)/24;
cy=ymin;
while( cy<=ymax ) {
cx=xmin;
while( cx<=xmax ) {
x = 0;
y = 0;
x2 = 0;
y2 = 0;
iter=0;
while( iter<maxiter ) {
if( x2+y2>16384 ) break;
y = ((x*y)>>11)+cy;
x = x2-y2+cx;
x2 = (x*x)>>12;
y2 = (y*y)>>12;
iter++;
}
putchar(' '+iter);
cx =+ dx;
}
putchar(13);
putchar(10);
cy =+ dy;
}
return(0);
}

View file

@ -0,0 +1,34 @@
fastgraphics
graphsize 384,384
refresh
kt = 319 : m = 4.0
xmin = -2.1 : xmax = 0.6 : ymin = -1.35 : ymax = 1.35
dx = (xmax - xmin) / graphwidth : dy = (ymax - ymin) / graphheight
for x = 0 to graphwidth
jx = xmin + x * dx
for y = 0 to graphheight
jy = ymin + y * dy
k = 0 : wx = 0.0 : wy = 0.0
do
tx = wx * wx - wy * wy + jx
ty = 2.0 * wx * wy + jy
wx = tx
wy = ty
r = wx * wx + wy * wy
k = k + 1
until r > m or k > kt
if k > kt then
color black
else
if k < 16 then color k * 8, k * 8, 128 + k * 4
if k >= 16 and k < 64 then color 128 + k - 16, 128 + k - 16, 192 + k - 16
if k >= 64 then color kt - k, 128 + (kt - k) / 2, kt - k
end if
plot x, y
next y
refresh
next x
imgsave "Mandelbrot_BASIC-256.png", "PNG"

View file

@ -0,0 +1,22 @@
sizex% = 300 : sizey% = 300
maxiter% = 128
VDU 23,22,sizex%;sizey%;8,8,16,128
ORIGIN 0,sizey%
GCOL 1
FOR X% = 0 TO 2*sizex%-2 STEP 2
xi = X%/200 - 2
FOR Y% = 0 TO sizey%-2 STEP 2
yi = Y% / 200
x = 0
y = 0
FOR I% = 1 TO maxiter%
IF x*x+y*y > 4 EXIT FOR
xt = xi + x*x-y*y
y = yi + 2*x*y
x = xt
NEXT
IF I%>maxiter% I%=0
COLOUR 1,I%*15,I%*8,0
PLOT X%,Y% : PLOT X%,-Y%
NEXT
NEXT X%

View file

@ -0,0 +1,10 @@
0>:00p58*`#@_0>:01p78vv$$<
@^+1g00,+55_v# !`\+*9<>4v$
@v30p20"?~^"< ^+1g10,+*8<$
@>p0\>\::*::882**02g*0v >^
`*:*" d":+*:-*"[Z"+g3 < |<
v-*"[Z"+g30*g20**288\--\<#
>2**5#>8*:*/00g"P"*58*:*v^
v*288 p20/**288:+*"[Z"+-<:
>*%03 p58*:*/01g"3"* v>::^
\_^#!:-1\+-*2*:*85<^

View file

@ -0,0 +1,17 @@
#!/usr/bin/env bx
use b
Main():
num outside = 16, ox = -0.5, oy = 0, r = 1.5
long i, max_i = 100, rb_i = 30
space()
uint32_t *px = pixel()
num d = 2*r/h, x0 = ox-d*w_2, y0 = oy+d*h_2
for(y, 0, h):
cmplx c = x0 + (y0-d*y)*I
repeat(w):
cmplx w = 0
for i=0; i < max_i && cabs(w) < outside; ++i
w = w*w + c
*px++ = i < max_i ? rainbow(i*359 / rb_i % 360) : black
c += d

View file

@ -0,0 +1,145 @@
A mandelbrot set fractal viewer in brainf*ck written by Erik Bosman
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[
>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+
<<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>>
>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+[>>>>>>[>>>>>>>[-]>>]<<<<<<<<<[<<<<<<<<<]>>
>>>>>[-]+<<<<<<++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<+++++++[-[->>>
>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[[-]>>>>>>[>>>>>
>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>
[>>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<
<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>+++++++++++++++[[
>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[
>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[
-<<+>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<
<<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<
[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>
>>>>[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+
<<<<<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>
>>>>>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<
+>>>>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<
<]<+<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<
<<<]>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->
>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<
<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++++++++++++++++
+++++++>>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>[<<<<<<<+<[-<+>>>>+<<[-]]>[-<<[->+>>>-
<<<<]>>>]>>>>>>>>>>>>>[>>[-]>[-]>[-]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>>>>>>[>>>>>
[-<<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>[-<<<<<<<<
<+>>>>>>>>>]>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>>]+>[-
]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>>>>>>>]<<<
<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+>>]<
<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[->>>>
>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-]<->>>
[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<
<<<<+>>>>>]<<<<<[->>>>>+<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+>>>>>>>>
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++
+++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-<<<<<<<+
>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[
-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>>]>[-<<<<<<[->>>>>+<++<<<<]>>>>>[-<
<<<<+>>>>>]<->+>]<[->+<]<<<<<[->>>>>+<<<<<]>>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<
[->>>>->>>>>[>>[-<<->>]+<<[->>->[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]
+>>>>>>[>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<<<<<<<<<<[<<<<<
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<
[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<
<<<+<[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<
<<<<<+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<
<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+<]>>>>>>>>]<<<
<<<<<+<[>[->>>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>[->>>>+<<<<]>]<[->>>>-<<<<<<<
<<<<<<<+>>>>>>>>>>]<]>>[->>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>>+<<<<
]<<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>>>>>>>>>]<<<<<<<<<
[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<<<<<<
+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<<<<<<
<<<<<]]>[-]>>[-]>[-]>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<
<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[
[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>
[-<<+>>]<<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<
<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[
>[-]<->>>[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[
>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>
>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>[-]>>>>+++++++++++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<
<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<
<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-
<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>
>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>>>
[-<<<->>>]<<<[->>>+<<<]>>>>>>>>]<<<<<<<<+<[>[->+>[-<-<<<<<<<<<<+>>>>>>>>>>>>[-<<
+>>]<]>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<<<]>>[-<+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<]>
[-<<+>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>
>>>>>>]<<<<<<<<+<[>[->+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>[-<+>]>]<[-<-<<<<<<<<<<+>>>>
>>>>>>>]<<]>>>[-<<+>[-<-<<<<<<<<<<+>>>>>>>>>>>]>]<[-<+>]<<<<<<<<<<<<]>>>>>+<<<<<
]>>>>>>>>>[>>>[-]>[-]>[-]>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>>>[-<<<<<
<+>>>>>>]<<<<<<[->>>>>>+<<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>
>]>>[-<<<<<<<[->>>>>+<++<<<<]>>>>>[-<<<<<+>>>>>]<->+>>]<<[->>+<<]<<<<<[->>>>>+<<
<<<]+>>>>[-<<<<->>>>]+<<<<[->>>>->>>>>[>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<
<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>[-<<->>]+<<[->>->[-<<<+>>>]<
<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<
<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+
<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>[->>>+<<<]>]<[->>>-
<<<<<<<<<<<<<+>>>>>>>>>>]<]>>[->>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>+<<<
]<<<<<<<<<<<]>>>>>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]]>>>>[-<<<<+>
>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<<[->>>-
<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[
->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>
>>]<<<<[->>>>+>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>[>>>>>>
>>>]<<<<<<<<<[>[->>>>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<
<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<
<<<<]]>>>>>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>[-<<<<+
>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<+>>>>>
]<<<<<[->>>>>+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>
>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[-<<+
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<
<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>
>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<+>>>
>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+
<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<<<<]
>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<
]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->>>+<
<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>
>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>->>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>]<<+>>>>[-<<<<
->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[-<<<<<<<.>>>>>>>]<<<[-]>[-]>[-]>[-]>[-]>[-]>>>[
>[-]>[-]>[-]>[-]>[-]>[-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]>>>>]<<<<<<<<<
[<<<<<<<<<]>+++++++++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+>>>>>>>>>+<<<<<<<<
<<<<<<[<<<<<<<<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+[-]>>[>>>>>>>>>]<<<<<
<<<<[>>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<[<<<<<<<<<]>>>>>>>[-]+>>>]<<<<
<<<<<<]]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+>>[>+>>>>[-<<<<->>>>]<<<<[->>>
>+<<<<]>>>>>>>>]<<+<<<<<<<[>>>>>[->>+<<]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<
<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<<<<<[->>>>>>+<<<<<<]<
+<<<<<<<<<]>>>>>>>-<<<<[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>->>[>>
>>>[->>+<<]>>>>]<<<<<<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<
<<<<[->>>>>>+<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+<<<
<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>->>[-<<<<<<<+>>>>>>>]<<<<
<<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>[-<
<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<
<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<
<<[<<<<<<<<<]>>>>[-]<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>-<<<<<[<<<<<<<
<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++[-[->>>>>>>>
>+<<<<<<<<<]>>>>>>>>>]>>>>>+>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<
<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+[-]>[>>>>>>>>>]<<<<<<<<<[>>>>>>>>[-<<<<<<<+>>>>>>
>]<<<<<<<[->>>>>>>+<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<
<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+>[>+>>>>>[-<<<<<->>>>>]<<<<<[->>>>>+<<<<<]>>>>>>
>>]<+<<<<<<<<[>>>>>>[->>+<<]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<-
>>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<
<<<]>>>>>>>>-<<<<<[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>->[>>>
>>>[->>+<<]>>>]<<<<<<<<<[>[-]<->>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<
<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>
+>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<->>>>>>]+<
<<<<<[->>>>>>->>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<
<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>
-<<[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>
>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<++++
+[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>->>>>>>>>>>>>>>>>>>>>>>>>>>>-<<<<<<[<<<<
<<<<<]]>>>]

View file

@ -0,0 +1,39 @@
#include <cstdlib>
#include <complex>
// get dimensions for arrays
template<typename ElementType, std::size_t dim1, std::size_t dim2>
std::size_t get_first_dimension(ElementType (&a)[dim1][dim2])
{
return dim1;
}
template<typename ElementType, std::size_t dim1, std::size_t dim2>
std::size_t get_second_dimension(ElementType (&a)[dim1][dim2])
{
return dim2;
}
template<typename ColorType, typename ImageType>
void draw_Mandelbrot(ImageType& image, //where to draw the image
ColorType set_color, ColorType non_set_color, //which colors to use for set/non-set points
double cxmin, double cxmax, double cymin, double cymax,//the rect to draw in the complex plane
unsigned int max_iterations) //the maximum number of iterations
{
std::size_t const ixsize = get_first_dimension(image);
std::size_t const iysize = get_first_dimension(image);
for (std::size_t ix = 0; ix < ixsize; ++ix)
for (std::size_t iy = 0; iy < iysize; ++iy)
{
std::complex<double> c(cxmin + ix/(ixsize-1.0)*(cxmax-cxmin), cymin + iy/(iysize-1.0)*(cymax-cymin));
std::complex<double> z = 0;
unsigned int iterations;
for (iterations = 0; iterations < max_iterations && std::abs(z) < 2.0; ++iterations)
z = z*z + c;
image[ix][iy] = (iterations == max_iterations) ? set_color : non_set_color;
}
}

View file

@ -0,0 +1,11 @@
#include <stdio.h>
int f(float X, float Y, float x, float y, int n){
return (x*x+y*y<4 && n<100)?1+f(X, Y, x*x-y*y+X, 2*x*y+Y, n+1):0;
}
main(){
for(float j=1; j>=-1; j-=.015)
for(float i=-2, x; i<=.5; i+=.015, x=f(i, j, 0, 0, 0))
printf("%c%s", x<10?' ':x<20?'.':x<50?':':x<80?'*':'#', i>-2?" ":"\n");
}

View file

@ -0,0 +1,138 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Windows.Forms;
/// <summary>
/// Generates bitmap of Mandelbrot Set and display it on the form.
/// </summary>
public class MandelbrotSetForm : Form
{
const double MaxValueExtent = 2.0;
Thread thread;
static double CalcMandelbrotSetColor(ComplexNumber c)
{
// from http://en.wikipedia.org/w/index.php?title=Mandelbrot_set
const int MaxIterations = 1000;
const double MaxNorm = MaxValueExtent * MaxValueExtent;
int iteration = 0;
ComplexNumber z = new ComplexNumber();
do
{
z = z * z + c;
iteration++;
} while (z.Norm() < MaxNorm && iteration < MaxIterations);
if (iteration < MaxIterations)
return (double)iteration / MaxIterations;
else
return 0; // black
}
static void GenerateBitmap(Bitmap bitmap)
{
double scale = 2 * MaxValueExtent / Math.Min(bitmap.Width, bitmap.Height);
for (int i = 0; i < bitmap.Height; i++)
{
double y = (bitmap.Height / 2 - i) * scale;
for (int j = 0; j < bitmap.Width; j++)
{
double x = (j - bitmap.Width / 2) * scale;
double color = CalcMandelbrotSetColor(new ComplexNumber(x, y));
bitmap.SetPixel(j, i, GetColor(color));
}
}
}
static Color GetColor(double value)
{
const double MaxColor = 256;
const double ContrastValue = 0.2;
return Color.FromArgb(0, 0,
(int)(MaxColor * Math.Pow(value, ContrastValue)));
}
public MandelbrotSetForm()
{
// form creation
this.Text = "Mandelbrot Set Drawing";
this.BackColor = System.Drawing.Color.Black;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.MaximizeBox = false;
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.ClientSize = new Size(640, 640);
this.Load += new System.EventHandler(this.MainForm_Load);
}
void MainForm_Load(object sender, EventArgs e)
{
thread = new Thread(thread_Proc);
thread.IsBackground = true;
thread.Start(this.ClientSize);
}
void thread_Proc(object args)
{
// start from small image to provide instant display for user
Size size = (Size)args;
int width = 16;
while (width * 2 < size.Width)
{
int height = width * size.Height / size.Width;
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
GenerateBitmap(bitmap);
this.BeginInvoke(new SetNewBitmapDelegate(SetNewBitmap), bitmap);
width *= 2;
Thread.Sleep(200);
}
// then generate final image
Bitmap finalBitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format24bppRgb);
GenerateBitmap(finalBitmap);
this.BeginInvoke(new SetNewBitmapDelegate(SetNewBitmap), finalBitmap);
}
void SetNewBitmap(Bitmap image)
{
if (this.BackgroundImage != null)
this.BackgroundImage.Dispose();
this.BackgroundImage = image;
}
delegate void SetNewBitmapDelegate(Bitmap image);
static void Main()
{
Application.Run(new MandelbrotSetForm());
}
}
struct ComplexNumber
{
public double Re;
public double Im;
public ComplexNumber(double re, double im)
{
this.Re = re;
this.Im = im;
}
public static ComplexNumber operator +(ComplexNumber x, ComplexNumber y)
{
return new ComplexNumber(x.Re + y.Re, x.Im + y.Im);
}
public static ComplexNumber operator *(ComplexNumber x, ComplexNumber y)
{
return new ComplexNumber(x.Re * y.Re - x.Im * y.Im,
x.Re * y.Im + x.Im * y.Re);
}
public double Norm()
{
return Re * Re + Im * Im;
}
}

View file

@ -0,0 +1,90 @@
/*
c program:
--------------------------------
1. draws Mandelbrot set for Fc(z)=z*z +c
using Mandelbrot algorithm ( boolean escape time )
-------------------------------
2. technique of creating ppm file is based on the code of Claudio Rocchini
http://en.wikipedia.org/wiki/Image:Color_complex_plot.jpg
create 24 bit color graphic file , portable pixmap file = PPM
see http://en.wikipedia.org/wiki/Portable_pixmap
to see the file use external application ( graphic viewer)
*/
#include <stdio.h>
#include <math.h>
int main()
{
/* screen ( integer) coordinate */
int iX,iY;
const int iXmax = 800;
const int iYmax = 800;
/* world ( double) coordinate = parameter plane*/
double Cx,Cy;
const double CxMin=-2.5;
const double CxMax=1.5;
const double CyMin=-2.0;
const double CyMax=2.0;
/* */
double PixelWidth=(CxMax-CxMin)/iXmax;
double PixelHeight=(CyMax-CyMin)/iYmax;
/* color component ( R or G or B) is coded from 0 to 255 */
/* it is 24 bit color RGB file */
const int MaxColorComponentValue=255;
FILE * fp;
char *filename="new1.ppm";
char *comment="# ";/* comment should start with # */
static unsigned char color[3];
/* Z=Zx+Zy*i ; Z0 = 0 */
double Zx, Zy;
double Zx2, Zy2; /* Zx2=Zx*Zx; Zy2=Zy*Zy */
/* */
int Iteration;
const int IterationMax=200;
/* bail-out value , radius of circle ; */
const double EscapeRadius=2;
double ER2=EscapeRadius*EscapeRadius;
/*create new file,give it a name and open it in binary mode */
fp= fopen(filename,"wb"); /* b - binary mode */
/*write ASCII header to the file*/
fprintf(fp,"P6\n %s\n %d\n %d\n %d\n",comment,iXmax,iYmax,MaxColorComponentValue);
/* compute and write image data bytes to the file*/
for(iY=0;iY<iYmax;iY++)
{
Cy=CyMin + iY*PixelHeight;
if (fabs(Cy)< PixelHeight/2) Cy=0.0; /* Main antenna */
for(iX=0;iX<iXmax;iX++)
{
Cx=CxMin + iX*PixelWidth;
/* initial value of orbit = critical point Z= 0 */
Zx=0.0;
Zy=0.0;
Zx2=Zx*Zx;
Zy2=Zy*Zy;
/* */
for (Iteration=0;Iteration<IterationMax && ((Zx2+Zy2)<ER2);Iteration++)
{
Zy=2*Zx*Zy + Cy;
Zx=Zx2-Zy2 +Cx;
Zx2=Zx*Zx;
Zy2=Zy*Zy;
};
/* compute pixel color (24 bit = 3 bytes) */
if (Iteration==IterationMax)
{ /* interior of Mandelbrot set = black */
color[0]=0;
color[1]=0;
color[2]=0;
}
else
{ /* exterior of Mandelbrot set = white */
color[0]=255; /* Red*/
color[1]=255; /* Green */
color[2]=255;/* Blue */
};
/*write color to the file*/
fwrite(color,1,3,fp);
}
}
fclose(fp);
return 0;
}

View file

@ -0,0 +1,240 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
void set_texture();
typedef struct {unsigned char r, g, b;} rgb_t;
rgb_t **tex = 0;
int gwin;
GLuint texture;
int width, height;
int tex_w, tex_h;
double scale = 1./256;
double cx = -.6, cy = 0;
int color_rotate = 0;
int saturation = 1;
int invert = 0;
int max_iter = 256;
void render()
{
double x = (double)width /tex_w,
y = (double)height/tex_h;
glClear(GL_COLOR_BUFFER_BIT);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2i(0, 0);
glTexCoord2f(x, 0); glVertex2i(width, 0);
glTexCoord2f(x, y); glVertex2i(width, height);
glTexCoord2f(0, y); glVertex2i(0, height);
glEnd();
glFlush();
glFinish();
}
int dump = 1;
void screen_dump()
{
char fn[100];
int i;
sprintf(fn, "screen%03d.ppm", dump++);
FILE *fp = fopen(fn, "w");
fprintf(fp, "P6\n%d %d\n255\n", width, height);
for (i = height - 1; i >= 0; i--)
fwrite(tex[i], 1, width * 3, fp);
fclose(fp);
printf("%s written\n", fn);
}
void keypress(unsigned char key, int x, int y)
{
switch(key) {
case 'q': glFinish();
glutDestroyWindow(gwin);
return;
case 27: scale = 1./256; cx = -.6; cy = 0; break;
case 'r': color_rotate = (color_rotate + 1) % 6;
break;
case '>': case '.':
max_iter += 128;
if (max_iter > 1 << 15) max_iter = 1 << 15;
printf("max iter: %d\n", max_iter);
break;
case '<': case ',':
max_iter -= 128;
if (max_iter < 128) max_iter = 128;
printf("max iter: %d\n", max_iter);
break;
case 'c': saturation = 1 - saturation;
break;
case 's': screen_dump(); return;
case 'z': max_iter = 4096; break;
case 'x': max_iter = 128; break;
case ' ': invert = !invert;
}
set_texture();
}
void hsv_to_rgb(int hue, int min, int max, rgb_t *p)
{
if (min == max) max = min + 1;
if (invert) hue = max - (hue - min);
if (!saturation) {
p->r = p->g = p->b = 255 * (max - hue) / (max - min);
return;
}
double h = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
# define VAL 255
double c = VAL * saturation;
double X = c * (1 - fabs(fmod(h, 2) - 1));
p->r = p->g = p->b = 0;
switch((int)h) {
case 0: p->r = c; p->g = X; return;
case 1: p->r = X; p->g = c; return;
case 2: p->g = c; p->b = X; return;
case 3: p->g = X; p->b = c; return;
case 4: p->r = X; p->b = c; return;
default:p->r = c; p->b = X;
}
}
void calc_mandel()
{
int i, j, iter, min, max;
rgb_t *px;
double x, y, zx, zy, zx2, zy2;
min = max_iter; max = 0;
for (i = 0; i < height; i++) {
px = tex[i];
y = (i - height/2) * scale + cy;
for (j = 0; j < width; j++, px++) {
x = (j - width/2) * scale + cx;
iter = 0;
zx = hypot(x - .25, y);
if (x < zx - 2 * zx * zx + .25) iter = max_iter;
if ((x + 1)*(x + 1) + y * y < 1/16) iter = max_iter;
zx = zy = zx2 = zy2 = 0;
for (; iter < max_iter && zx2 + zy2 < 4; iter++) {
zy = 2 * zx * zy + y;
zx = zx2 - zy2 + x;
zx2 = zx * zx;
zy2 = zy * zy;
}
if (iter < min) min = iter;
if (iter > max) max = iter;
*(unsigned short *)px = iter;
}
}
for (i = 0; i < height; i++)
for (j = 0, px = tex[i]; j < width; j++, px++)
hsv_to_rgb(*(unsigned short*)px, min, max, px);
}
void alloc_tex()
{
int i, ow = tex_w, oh = tex_h;
for (tex_w = 1; tex_w < width; tex_w <<= 1);
for (tex_h = 1; tex_h < height; tex_h <<= 1);
if (tex_h != oh || tex_w != ow)
tex = realloc(tex, tex_h * tex_w * 3 + tex_h * sizeof(rgb_t*));
for (tex[0] = (rgb_t *)(tex + tex_h), i = 1; i < tex_h; i++)
tex[i] = tex[i - 1] + tex_w;
}
void set_texture()
{
alloc_tex();
calc_mandel();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_w, tex_h,
0, GL_RGB, GL_UNSIGNED_BYTE, tex[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
render();
}
void mouseclick(int button, int state, int x, int y)
{
if (state != GLUT_UP) return;
cx += (x - width / 2) * scale;
cy -= (y - height/ 2) * scale;
switch(button) {
case GLUT_LEFT_BUTTON: /* zoom in */
if (scale > fabs(x) * 1e-16 && scale > fabs(y) * 1e-16)
scale /= 2;
break;
case GLUT_RIGHT_BUTTON: /* zoom out */
scale *= 2;
break;
/* any other button recenters */
}
set_texture();
}
void resize(int w, int h)
{
printf("resize %d %d\n", w, h);
width = w;
height = h;
glViewport(0, 0, w, h);
glOrtho(0, w, 0, h, -1, 1);
set_texture();
}
void init_gfx(int *c, char **v)
{
glutInit(c, v);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(640, 480);
gwin = glutCreateWindow("Mandelbrot");
glutDisplayFunc(render);
glutKeyboardFunc(keypress);
glutMouseFunc(mouseclick);
glutReshapeFunc(resize);
glGenTextures(1, &texture);
set_texture();
}
int main(int c, char **v)
{
init_gfx(&c, v);
printf("keys:\n\tr: color rotation\n\tc: monochrome\n\ts: screen dump\n\t"
"<, >: decrease/increase max iteration\n\tq: quit\n\tmouse buttons to zoom\n");
glutMainLoop();
return 0;
}

View file

@ -0,0 +1,340 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
void set_texture();
unsigned char *tex;
int gwin;
GLuint texture;
int width, height;
int old_width, old_height;
double scale = 1. / 256;
double cx = -.6, cy = 0;
int color_rotate = 0;
int saturation = 1;
int invert = 0;
int max_iter = 256;
void render()
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2d(0, 0);
glVertex2i(0, 0);
glTexCoord2d(1, 0);
glVertex2i(width, 0);
glTexCoord2d(1, 1);
glVertex2i(width, height);
glTexCoord2d(0, 1);
glVertex2i(0, height);
glEnd();
glFlush();
glFinish();
}
int dump = 1;
void screen_dump()
{
char fn[100];
sprintf(fn, "screen%03d.ppm", dump++);
FILE *fp = fopen(fn, "w");
fprintf(fp, "P6\n%d %d\n255\n", width, height);
for (int i = height - 1; i >= 0; i -= 1) {
for (int j = 0; j < width; j += 1) {
fwrite(&tex[((i * width) + j) * 4], 1, 3, fp);
}
}
fclose(fp);
printf("%s written\n", fn);
}
void keypress(unsigned char key,[[maybe_unused]]
int x,[[maybe_unused]]
int y)
{
switch (key) {
case 'q':
glFinish();
glutDestroyWindow(gwin);
break;
case 27:
scale = 1. / 256;
cx = -.6;
cy = 0;
set_texture();
break;
case 'r':
color_rotate = (color_rotate + 1) % 6;
set_texture();
break;
case '>':
case '.':
max_iter += 128;
if (max_iter > 1 << 15)
max_iter = 1 << 15;
printf("max iter: %d\n", max_iter);
set_texture();
break;
case '<':
case ',':
max_iter -= 128;
if (max_iter < 128)
max_iter = 128;
printf("max iter: %d\n", max_iter);
set_texture();
break;
case 'c':
saturation = 1 - saturation;
set_texture();
break;
case 's':
screen_dump();
break;
case 'z':
max_iter = 4096;
set_texture();
break;
case 'x':
max_iter = 128;
set_texture();
break;
case ' ':
invert = !invert;
set_texture();
break;
default:
set_texture();
break;
}
}
#define VAL 255
void hsv_to_rgba(int hue, int min, int max, unsigned char *px)
{
unsigned char r;
unsigned char g;
unsigned char b;
if (min == max)
max = min + 1;
if (invert)
hue = max - (hue - min);
if (!saturation) {
r = 255 * (max - hue) / (max - min);
g = r;
b = r;
} else {
double h =
fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
double c = VAL * saturation;
double X = c * (1 - fabs(fmod(h, 2) - 1));
r = 0;
g = 0;
b = 0;
switch ((int) h) {
case 0:
r = c;
g = X;
break;
case 1:
r = X;
g = c;
break;
case 2:
g = c;
b = X;
break;
case 3:
g = X;
b = c;
break;
case 4:
r = X;
b = c;
break;
default:
r = c;
b = X;
break;
}
}
/* Using an alpha channel neatly solves the problem of aligning
* rows on 4-byte boundaries (at the expense of memory, of
* course). */
px[0] = r;
px[1] = g;
px[2] = b;
px[3] = 255; /* Alpha channel. */
}
void calc_mandel()
{
int i, j, iter, min, max;
double x, y, zx, zy, zx2, zy2;
unsigned short *hsv = malloc(width * height * sizeof(unsigned short));
min = max_iter;
max = 0;
for (i = 0; i < height; i++) {
y = (i - height / 2) * scale + cy;
for (j = 0; j < width; j++) {
x = (j - width / 2) * scale + cx;
iter = 0;
zx = hypot(x - .25, y);
if (x < zx - 2 * zx * zx + .25)
iter = max_iter;
if ((x + 1) * (x + 1) + y * y < 1 / 16)
iter = max_iter;
zx = 0;
zy = 0;
zx2 = 0;
zy2 = 0;
while (iter < max_iter && zx2 + zy2 < 4) {
zy = 2 * zx * zy + y;
zx = zx2 - zy2 + x;
zx2 = zx * zx;
zy2 = zy * zy;
iter += 1;
}
if (iter < min)
min = iter;
if (iter > max)
max = iter;
hsv[(i * width) + j] = iter;
}
}
for (i = 0; i < height; i += 1) {
for (j = 0; j < width; j += 1) {
unsigned char *px = tex + (((i * width) + j) * 4);
hsv_to_rgba(hsv[(i * width) + j], min, max, px);
}
}
free(hsv);
}
void alloc_tex()
{
if (tex == NULL || width != old_width || height != old_height) {
free(tex);
tex = malloc(height * width * 4 * sizeof(unsigned char));
memset(tex, 0, height * width * 4 * sizeof(unsigned char));
old_width = width;
old_height = height;
}
}
void set_texture()
{
alloc_tex();
calc_mandel();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
render();
}
void mouseclick(int button, int state, int x, int y)
{
if (state != GLUT_UP)
return;
cx += (x - width / 2) * scale;
cy -= (y - height / 2) * scale;
switch (button) {
case GLUT_LEFT_BUTTON: /* zoom in */
if (scale > fabs((double) x) * 1e-16
&& scale > fabs((double) y) * 1e-16)
scale /= 2;
break;
case GLUT_RIGHT_BUTTON: /* zoom out */
scale *= 2;
break;
/* any other button recenters */
}
set_texture();
}
void resize(int w, int h)
{
printf("resize %d %d\n", w, h);
width = w;
height = h;
glViewport(0, 0, w, h);
glOrtho(0, w, 0, h, -1, 1);
set_texture();
}
void init_gfx(int *c, char **v)
{
glutInit(c, v);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(640, 480);
gwin = glutCreateWindow("Mandelbrot");
glutDisplayFunc(render);
glutKeyboardFunc(keypress);
glutMouseFunc(mouseclick);
glutReshapeFunc(resize);
glGenTextures(1, &texture);
set_texture();
}
int main(int c, char **v)
{
tex = NULL;
init_gfx(&c, v);
printf
("keys:\n\tr: color rotation\n\tc: monochrome\n\ts: screen dump\n\t"
"<, >: decrease/increase max iteration\n\tq: quit\n\tmouse buttons to zoom\n");
glutMainLoop();
return 0;
}
// local variables:
// mode: C
// c-file-style: "k&r"
// c-basic-offset: 4
// end:

View file

@ -0,0 +1,3 @@
main(k){float i,j,r,x,y=-16;while(puts(""),y++<15)for(x
=0;x++<84;putchar(" .:-;!/>)|&IH%*#"[k&15]))for(i=k=r=0;
j=r*r-i*i-2+x/25,i=2*r*i+y/10,j*j+i*i<11&&k++<111;r=j);}

View file

@ -0,0 +1,100 @@
/**
ascii Mandelbrot using 16 bits of fixed point integer maths with a selectable fractional precision in bits.
This is still only 16 bits mathc and allocating more than 6 bits of fractional precision leads to an overflow that adds noise to the plot..
This code frequently casts to short to ensure we're not accidentally benefitting from GCC promotion from short 16 bits to int.
gcc fixedPoint.c -lm
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include <string.h>
short s(short i);
short toPrec(double f, int bitsPrecision);
int main(int argc, char* argv[])
{
// chosen to match https://www.youtube.com/watch?v=DC5wi6iv9io
int width = 32; // basic width of a zx81
int height = 22; // basic width of a zx81
int zoom=3; // bigger with finer detail ie a smaller step size - leave at 1 for 32x22
// params
short bitsPrecision = 6;
printf("PRECISION=%d\n", bitsPrecision);
short X1 = toPrec(3.5,bitsPrecision) / zoom;
short X2 = toPrec(2.25,bitsPrecision) ;
short Y1 = toPrec(3,bitsPrecision)/zoom ; // horiz pos
short Y2 = toPrec(1.5,bitsPrecision) ; // vert pos
short LIMIT = toPrec(4,bitsPrecision);
// fractal
//char * chr = ".:-=X$#@.";
char * chr = "abcdefghijklmnopqr ";
//char * chr = ".,'~=+:;[/<&?oxOX#.";
short maxIters = strlen(chr);
short py=0;
while (py < height*zoom) {
short px=0;
while (px < width*zoom) {
short x0 = s(s(px*X1) / width) - X2;
short y0 = s(s(py*Y1) / height) - Y2;
short x=0;
short y=0;
short i=0;
short xSqr;
short ySqr;
while (i < maxIters) {
xSqr = s(x * x) >> bitsPrecision;
ySqr = s(y * y) >> bitsPrecision;
// Breakout if sum is > the limit OR breakout also if sum is negative which indicates overflow of the addition has occurred
// The overflow check is only needed for precisions of over 6 bits because for 7 and above the sums come out overflowed and negative therefore we always run to maxIters and we see nothing.
// By including the overflow break out we can see the fractal again though with noise.
if ((xSqr + ySqr) >= LIMIT || (xSqr+ySqr) < 0) {
break;
}
short xt = xSqr - ySqr + x0;
y = s(s(s(x * y) >> bitsPrecision) * 2) + y0;
x=xt;
i = i + 1;
}
i = i - 1;
printf("%c", chr[i]);
px = px + 1;
}
printf("\n");
py = py + 1;
}
}
// convert decimal value to a fixed point value in the given precision
short toPrec(double f, int bitsPrecision) {
short whole = ((short)floor(f) << (bitsPrecision));
short part = (f-floor(f))*(pow(2,bitsPrecision));
short ret = whole + part;
return ret;
}
// convenient casting
short s(short i) {
return i;
}

View file

@ -0,0 +1,58 @@
module mandelbrot;
extern fn int atoi(char *s);
extern fn int printf(char *s, ...);
extern fn void putchar(int c);
fn void main(int argc, char **argv)
{
int w = atoi(argv[1]);
int h = w;
const LIMIT = 2.0;
const SQUARE_LIMIT = LIMIT * LIMIT;
printf("P4\n%d %d\n", w, h);
int iter = 50;
int bit_num = 0;
char byte_acc = 0;
for (double y = 0; y < h; y++)
{
for (double x = 0; x < w; x++)
{
double zr;
double zi;
double ti;
double tr;
double cr = (2.0 * x / w - 1.5);
double ci = (2.0 * y / h - 1.0);
for (int i = 0; i < iter && (tr + ti <= SQUARE_LIMIT); i++)
{
zi = 2.0 * zr * zi + ci;
zr = tr - ti + cr;
tr = zr * zr;
ti = zi * zi;
}
byte_acc <<= 1;
if (tr + ti <= SQUARE_LIMIT) byte_acc |= 0x01;
++bit_num;
if (bit_num == 8)
{
putchar(byte_acc);
byte_acc = 0;
bit_num = 0;
}
else if (x == w - 1)
{
byte_acc <<= (8 - w % 8);
putchar(byte_acc);
byte_acc = 0;
bit_num = 0;
}
}
}
}

View file

@ -0,0 +1,51 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. MANDELBROT-SET-PROGRAM.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 COMPLEX-ARITHMETIC.
05 X PIC S9V9(9).
05 Y PIC S9V9(9).
05 X-A PIC S9V9(6).
05 X-B PIC S9V9(6).
05 Y-A PIC S9V9(6).
05 X-A-SQUARED PIC S9V9(6).
05 Y-A-SQUARED PIC S9V9(6).
05 SUM-OF-SQUARES PIC S9V9(6).
05 ROOT PIC S9V9(6).
01 LOOP-COUNTERS.
05 I PIC 99.
05 J PIC 99.
05 K PIC 999.
77 PLOT-CHARACTER PIC X.
PROCEDURE DIVISION.
CONTROL-PARAGRAPH.
PERFORM OUTER-LOOP-PARAGRAPH
VARYING I FROM 1 BY 1 UNTIL I IS GREATER THAN 24.
STOP RUN.
OUTER-LOOP-PARAGRAPH.
PERFORM INNER-LOOP-PARAGRAPH
VARYING J FROM 1 BY 1 UNTIL J IS GREATER THAN 64.
DISPLAY ''.
INNER-LOOP-PARAGRAPH.
MOVE SPACE TO PLOT-CHARACTER.
MOVE ZERO TO X-A.
MOVE ZERO TO Y-A.
MULTIPLY J BY 0.0390625 GIVING X.
SUBTRACT 1.5 FROM X.
MULTIPLY I BY 0.083333333 GIVING Y.
SUBTRACT 1 FROM Y.
PERFORM ITERATION-PARAGRAPH VARYING K FROM 1 BY 1
UNTIL K IS GREATER THAN 100 OR PLOT-CHARACTER IS EQUAL TO '#'.
DISPLAY PLOT-CHARACTER WITH NO ADVANCING.
ITERATION-PARAGRAPH.
MULTIPLY X-A BY X-A GIVING X-A-SQUARED.
MULTIPLY Y-A BY Y-A GIVING Y-A-SQUARED.
SUBTRACT Y-A-SQUARED FROM X-A-SQUARED GIVING X-B.
ADD X TO X-B.
MULTIPLY X-A BY Y-A GIVING Y-A.
MULTIPLY Y-A BY 2 GIVING Y-A.
SUBTRACT Y FROM Y-A.
MOVE X-B TO X-A.
ADD X-A-SQUARED TO Y-A-SQUARED GIVING SUM-OF-SQUARES.
MOVE FUNCTION SQRT (SUM-OF-SQUARES) TO ROOT.
IF ROOT IS GREATER THAN 2 THEN MOVE '#' TO PLOT-CHARACTER.

View file

@ -0,0 +1,24 @@
(defn complex-add
[[a0 b0] [a1 b1]]
[(+ a0 a1) (+ b0 b1)])
(defn complex-square
[[a b]]
[(- (* a a) (* b b)) (* 2 a b)])
(defn complex-abs
[[a b]]
(Math/sqrt (+ (* a a) (* b b))))
(defn f
[z c]
(complex-add z (complex-square c)))
(defn mandelbrot?
[z]
(> 2 (complex-abs (nth (iterate (partial f z) [0 0]) 20))))
(doseq [y (range 1 -1 -0.05)]
(doseq [x (range -2 0.5 0.0315)]
(print (if (mandelbrot? [(double x) (double y)]) "*" " ")))
(println ""))

View file

@ -0,0 +1,45 @@
(defpackage #:mandelbrot
(:use #:cl))
(in-package #:mandelbrot)
(deftype pixel () '(unsigned-byte 8))
(deftype image () '(array pixel))
(defun write-pgm (image filespec)
(declare (image image))
(with-open-file (s filespec :direction :output :element-type 'pixel :if-exists :supersede)
(let* ((width (array-dimension image 1))
(height (array-dimension image 0))
(header (format nil "P5~A~D ~D~A255~A" #\Newline width height #\Newline #\Newline)))
(loop for c across header
do (write-byte (char-code c) s))
(dotimes (row height)
(dotimes (col width)
(write-byte (aref image row col) s))))))
(defparameter *x-max* 800)
(defparameter *y-max* 800)
(defparameter *cx-min* -2.5)
(defparameter *cx-max* 1.5)
(defparameter *cy-min* -2.0)
(defparameter *cy-max* 2.0)
(defparameter *escape-radius* 2)
(defparameter *iteration-max* 40)
(defun mandelbrot (filespec)
(let ((pixel-width (/ (- *cx-max* *cx-min*) *x-max*))
(pixel-height (/ (- *cy-max* *cy-min*) *y-max*))
(image (make-array (list *y-max* *x-max*) :element-type 'pixel :initial-element 0)))
(loop for y from 0 below *y-max*
for cy from *cy-min* by pixel-height
do (loop for x from 0 below *x-max*
for cx from *cx-min* by pixel-width
for iteration = (loop with c = (complex cx cy)
for iteration from 0 below *iteration-max*
for z = c then (+ (* z z) c)
while (< (abs z) *escape-radius*)
finally (return iteration))
for pixel = (round (* 255 (/ (- *iteration-max* iteration) *iteration-max*)))
do (setf (aref image y x) pixel)))
(write-pgm image filespec)))

View file

@ -0,0 +1,35 @@
include "cowgol.coh";
const xmin := -8601;
const xmax := 2867;
const ymin := -4915;
const ymax := 4915;
const maxiter := 32;
const dx := (xmax-xmin)/79;
const dy := (ymax-ymin)/24;
var cy: int16 := ymin;
while cy <= ymax loop
var cx: int16 := xmin;
while cx <= xmax loop
var x: int32 := 0;
var y: int32 := 0;
var x2: int32 := 0;
var y2: int32 := 0;
var iter: uint8 := 0;
while iter < maxiter and x2 + y2 <= 16384 loop
y := ((x*y)>>11)+cy as int32;
x := x2-y2+cx as int32;
x2 := (x*x)>>12;
y2 := (y*y)>>12;
iter := iter + 1;
end loop;
print_char(' ' + iter);
cx := cx + dx;
end loop;
print_nl();
cy := cy + dy;
end loop;

View file

@ -0,0 +1,45 @@
define max = 15, w = 640, h = 480
define py = 0, px = 0, sx = 0, sy = 0
define xx = 0, xy = 0
bgcolor 0, 0, 0
cls graphics
fill on
do
let px = 0
do
let sy = (py - h / 2) / 150
let sx = (px - w / 2) / 150
let i = 0
let x = 0
let y = 0
let xy = x * x + y * y
do
let xx = x * x - y * y + sx + .1
let y = 2 * x * y + sy
let x = xx
let i = i + 1
loop i < max and xy < 4
wait
fgcolor 220 + i * x, 220 + i * y, 230 + i * xy
rect px, py, 4, 4
let px = px + 4
loop px < w
let py = py + 4
loop py < h

View file

@ -0,0 +1,13 @@
void main() {
import std.stdio, std.complex;
for (real y = -1.2; y < 1.2; y += 0.05) {
for (real x = -2.05; x < 0.55; x += 0.03) {
auto z = 0.complex;
foreach (_; 0 .. 100)
z = z ^^ 2 + complex(x, y);
write(z.abs < 2 ? '#' : '.');
}
writeln;
}
}

View file

@ -0,0 +1,8 @@
void main() {
import std.stdio, std.complex, std.range, std.algorithm;
foreach (immutable y; iota(-1.2, 1.2, 0.05))
iota(-2.05, 0.55, 0.03).map!(x => 0.complex
.recurrence!((a, n) => a[n - 1] ^^ 2 + complex(x, y))
.drop(100).front.abs < 2 ? '#' : '.').writeln;
}

View file

@ -0,0 +1,27 @@
import qd;
double lensqr(cdouble c) { return c.re * c.re + c.im * c.im; }
const Limit = 150;
void main() {
screen(640, 480);
for (int y = 0; y < screen.h; ++y) {
flip; events;
for (int x = 0; x < screen.w; ++x) {
auto
c_x = x * 1.0 / screen.w - 0.5,
c_y = y * 1.0 / screen.h - 0.5,
c = c_y * 2.0i + c_x * 3.0 - 1.0,
z = 0.0i + 0.0,
i = 0;
for (; i < Limit; ++i) {
z = z * z + c;
if (lensqr(z) > 4) break;
}
auto value = cast(ubyte) (i * 255.0 / Limit);
pset(x, y, rgb(value, value, value));
}
}
while (true) { flip; events; }
}

View file

@ -0,0 +1,17 @@
const maxIter = 256;
var x, y, i : Integer;
for y:=-39 to 39 do begin
for x:=-39 to 39 do begin
var c := Complex(y/40-0.5, x/40);
var z := Complex(0, 0);
for i:=1 to maxIter do begin
z := z*z + c;
if Abs(z)>=4 then Break;
end;
if i>=maxIter then
Print('#')
else Print('.');
end;
PrintLn('');
end;

View file

@ -0,0 +1,36 @@
class Complex {
double _r,_i;
Complex(this._r,this._i);
double get r => _r;
double get i => _i;
String toString() => "($r,$i)";
Complex operator +(Complex other) => new Complex(r+other.r,i+other.i);
Complex operator *(Complex other) =>
new Complex(r*other.r-i*other.i,r*other.i+other.r*i);
double abs() => r*r+i*i;
}
void main() {
double start_x=-1.5;
double start_y=-1.0;
double step_x=0.03;
double step_y=0.1;
for(int y=0;y<20;y++) {
String line="";
for(int x=0;x<70;x++) {
Complex c=new Complex(start_x+step_x*x,start_y+step_y*y);
Complex z=new Complex(0.0, 0.0);
for(int i=0;i<100;i++) {
z=z*(z)+c;
if(z.abs()>2) {
break;
}
}
line+=z.abs()>2 ? " " : "*";
}
print(line);
}
}

View file

@ -0,0 +1,69 @@
_2.1 sx # xmin = -2.1
0.7 sX # xmax = 0.7
_1.2 sy # ymin = -1.2
1.2 sY # ymax = 1.2
32 sM # maxiter = 32
80 sW # image width
25 sH # image height
8 k # precision
[ q ] sq # quitter helper macro
# for h from 0 to H-1
0 sh
[
lh lH =q # quit if H reached
# for w from 0 to W-1
0 sw
[
lw lW =q # quit if W reached
# (w,h) -> (R,I)
# | |
# | ymin + h*(ymax-ymin)/(height-1)
# xmin + w*(xmax-xmin)/(width-1)
lX lx - lW 1 - / lw * lx + sR
lY ly - lH 1 - / lh * ly + sI
# iterate for (R,I)
0 sr # r:=0
0 si # i:=0
0 sa # a:=0 (r squared)
0 sb # b:=0 (i squared)
0 sm # m:=0
# do while m!=M and a+b=<4
[
lm lM =q # exit if m==M
la lb + 4<q # exit if >4
2 lr * li * lI + si # i:=2*r*i+I
la lb - lR + sr # r:=a-b+R
lm 1 + sm # m+=1
lr 2 ^ sa # a:=r*r
li 2 ^ sb # b:=i*i
l0 x # loop
] s0
l0 x
lm 32 + P # print "pixel"
lw 1 + sw # w+=1
l1 x # loop
] s1
l1 x
A P # linefeed
lh 1 + sh # h+=1
l2 x # loop
] s2
l2 x

View file

@ -0,0 +1,37 @@
_2.1 sx 0.7 sX _1.2 sy 1.2 sY
32 sM
640 sW 480 sH
8 k
[P5] P A P
lW n 32 P lH n A P
lM 1 - n A P
[ q ] sq
0 sh
[
lh lH =q
0 sw
[
lw lW =q
lX lx - lW 1 - / lw * lx + sR
lY ly - lH 1 - / lh * ly + sI
0 sr 0 si 0 sa 0 sb 0 sm
[
lm lM =q
la lb + 4<q
2 lr * li * lI + si
la lb - lR + sr
lm 1 + sm
lr 2 ^ sa
li 2 ^ sb
l0 x
] s0
l0 x
lm 1 - P
lw 1 + sw
l1 x
] s1
l1 x
lh 1 + sh
l2 x
] s2
l2 x

View file

@ -0,0 +1,51 @@
void drawMandelbrot(Bitmap bmp, float range, Complex center, ColorAlpha * palette, int nPalEntries, int nIterations, float scale)
{
int x, y;
int w = bmp.width, h = bmp.height;
ColorAlpha * picture = (ColorAlpha *)bmp.picture;
double logOf2 = log(2);
Complex d
{
w > h ? range : range * w / h,
h > w ? range : range * h / w
};
Complex C0 { center.a - d.a/2, center.b - d.b/2 };
Complex C = C0;
double delta = d.a / w;
for(y = 0; y < h; y++, C.a = C0.a, C.b += delta)
{
for(x = 0; x < w; x++, picture++, C.a += delta)
{
Complex Z { };
int i;
double ii = 0;
bool out = false;
double Za2 = Z.a * Z.a, Zb2 = Z.b * Z.b;
for(i = 0; i < nIterations; i++)
{
double z2;
Z = { Za2 - Zb2, 2*Z.a*Z.b };
Z.a += C.a;
Z.b += C.b;
Za2 = Z.a * Z.a, Zb2 = Z.b * Z.b;
z2 = Za2 + Zb2;
if(z2 >= 2*2)
{
ii = (double)(i + 1 - log(0.5 * log(z2)) / logOf2);
out = true;
break;
}
}
if(out)
{
float si = (float)(ii * scale);
int i0 = ((int)si) % nPalEntries;
*picture = palette[i0];
}
else
*picture = black;
}
}
}

View file

@ -0,0 +1,135 @@
class Mandelbrot : Window
{
caption = $"Mandelbrot";
borderStyle = sizable;
hasMaximize = true;
hasMinimize = true;
hasClose = true;
clientSize = { 600, 600 };
Point mouseStart, mouseEnd;
bool dragging;
bool needUpdate;
float scale;
int nIterations; nIterations = 256;
ColorAlpha * palette;
int nPalEntries;
Complex center { -0.75, 0 };
float range; range = 4;
Bitmap bmp { };
Mandelbrot()
{
static ColorKey keys[] =
{
{ navy, 0.0f },
{ Color { 146, 213, 237 }, 0.198606268f },
{ white, 0.3f },
{ Color { 255, 255, 124 }, 0.444250882f },
{ Color { 255, 100, 0 }, 0.634146333f },
{ navy, 1 }
};
nPalEntries = 30000;
palette = new ColorAlpha[nPalEntries];
scale = nPalEntries / 175.0f;
PaletteGradient(palette, nPalEntries, keys, sizeof(keys)/sizeof(keys[0]), 1.0);
needUpdate = true;
}
~Mandelbrot() { delete palette; }
void OnRedraw(Surface surface)
{
if(needUpdate)
{
drawMandelbrot(bmp, range, center, palette, nPalEntries, nIterations, scale);
needUpdate = false;
}
surface.Blit(bmp, 0,0, 0,0, bmp.width, bmp.height);
if(dragging)
{
surface.foreground = lime;
surface.Rectangle(mouseStart.x, mouseStart.y, mouseEnd.x, mouseEnd.y);
}
}
bool OnLeftButtonDown(int x, int y, Modifiers mods)
{
mouseEnd = mouseStart = { x, y };
Capture();
dragging = true;
Update(null);
return true;
}
bool OnLeftButtonUp(int x, int y, Modifiers mods)
{
if(dragging)
{
int dx = Abs(mouseEnd.x - mouseStart.x), dy = Abs(mouseEnd.y - mouseStart.y);
if(dx > 4 && dy > 4)
{
int w = clientSize.w, h = clientSize.h;
float rangeX = w > h ? range : range * w / h;
float rangeY = h > w ? range : range * h / w;
center.a += ((mouseStart.x + mouseEnd.x) - w) / 2.0f * rangeX / w;
center.b += ((mouseStart.y + mouseEnd.y) - h) / 2.0f * rangeY / h;
range = dy > dx ? dy * range / h : dx * range / w;
needUpdate = true;
Update(null);
}
ReleaseCapture();
dragging = false;
}
return true;
}
bool OnMouseMove(int x, int y, Modifiers mods)
{
if(dragging)
{
mouseEnd = { x, y };
Update(null);
}
return true;
}
bool OnRightButtonDown(int x, int y, Modifiers mods)
{
range = 4;
nIterations = 256;
center = { -0.75, 0 };
needUpdate = true;
Update(null);
return true;
}
void OnResize(int width, int height)
{
bmp.Allocate(null, width, height, 0, pixelFormat888, false);
needUpdate = true;
Update(null);
}
bool OnKeyHit(Key key, unichar ch)
{
switch(key)
{
case space: case keyPadPlus: case plus:
nIterations += 256;
needUpdate = true;
Update(null);
break;
}
return true;
}
}
Mandelbrot mandelbrotForm {};

View file

@ -0,0 +1,36 @@
PROGRAM MANDELBROT
!$KEY
!$INCLUDE="PC.LIB"
BEGIN
SCREEN(7)
GR_WINDOW(-2,1.5,2,-1.5)
FOR X0=-2 TO 2 STEP 0.01 DO
FOR Y0=-1.5 TO 1.5 STEP 0.01 DO
X=0
Y=0
ITERATION=0
MAX_ITERATION=223
WHILE (X*X+Y*Y<=(2*2) AND ITERATION<MAX_ITERATION) DO
X_TEMP=X*X-Y*Y+X0
Y=2*X*Y+Y0
X=X_TEMP
ITERATION=ITERATION+1
END WHILE
IF ITERATION<>MAX_ITERATION THEN
C=ITERATION
ELSE
C=0
END IF
PSET(X0,Y0,C)
END FOR
END FOR
END PROGRAM

View file

@ -0,0 +1,19 @@
for y0 = 0 to 299
cy = (y0 - 150) / 120
for x0 = 0 to 299
cx = (x0 - 220) / 120
x = 0 ; y = 0 ; iter = 0
while iter < 64 and x * x + y * y < 4
h = x * x - y * y + cx
y = 2 * x * y + cy
x = h
iter += 1
.
if iter = 64
iter = 0
.
color3 iter / 16 0 0
move x0 / 3 y0 / 3
rect 0.4 0.4
.
.

View file

@ -0,0 +1,11 @@
(lib 'math) ;; fractal function
(lib 'plot)
;; (fractal z zc n) iterates z := z^2 + c, n times
;; 100 iterations
(define (mset z) (if (= Infinity (fractal 0 z 100)) Infinity z))
;; plot function argument inside square (-2 -2), (2,2)
(plot-z-arg mset -2 -2)
;; result here [http://www.echolalie.org/echolisp/help.html#fractal]

View file

@ -0,0 +1,29 @@
defmodule Mandelbrot do
def set do
xsize = 59
ysize = 21
minIm = -1.0
maxIm = 1.0
minRe = -2.0
maxRe = 1.0
stepX = (maxRe - minRe) / xsize
stepY = (maxIm - minIm) / ysize
Enum.each(0..ysize, fn y ->
im = minIm + stepY * y
Enum.map(0..xsize, fn x ->
re = minRe + stepX * x
62 - loop(0, re, im, re, im, re*re+im*im)
end) |> IO.puts
end)
end
defp loop(n, _, _, _, _, _) when n>=30, do: n
defp loop(n, _, _, _, _, v) when v>4.0, do: n-1
defp loop(n, re, im, zr, zi, _) do
a = zr * zr
b = zi * zi
loop(n+1, re, im, a-b+re, 2*zr*zi+im, a+b)
end
end
Mandelbrot.set

View file

@ -0,0 +1,42 @@
; === Mandelbrot ============================================
(setq mandel-size (cons 76 34))
(setq xmin -2)
(setq xmax .5)
(setq ymin -1.2)
(setq ymax 1.2)
(setq max-iter 20)
(defun mandel-iter-point (x y)
"Run the actual iteration for each point."
(let ((xp 0)
(yp 0)
(it 0)
(xt 0))
(while (and (< (+ (* xp xp) (* yp yp)) 4) (< it max-iter))
(setq xt (+ (* xp xp) (* -1 yp yp) x))
(setq yp (+ (* 2 xp yp) y))
(setq xp xt)
(setq it (1+ it)))
it))
(defun mandel-iter (p)
"Return string for point based on whether inside/outside the set."
(let ((it (mandel-iter-point (car p) (cdr p))))
(if (= it max-iter) "*" "-")))
(defun mandel-pos (x y)
"Convert screen coordinates to input coordinates."
(let ((xp (+ xmin (* (- xmax xmin) (/ (float x) (car mandel-size)))))
(yp (+ ymin (* (- ymax ymin) (/ (float y) (cdr mandel-size))))))
(cons xp yp)))
(defun mandel ()
"Plot the Mandelbrot set."
(dotimes (y (cdr mandel-size))
(dotimes (x (car mandel-size))
(if (= x 0)
(insert(format "\n%s" (mandel-iter (mandel-pos x y))))
(insert(format "%s" (mandel-iter (mandel-pos x y))))))))
(mandel)

View file

@ -0,0 +1,54 @@
; === Graphical Mandelbrot ============================================
(setq mandel-size (cons 320 300))
(setq xmin -2)
(setq xmax .5)
(setq ymin -1.2)
(setq ymax 1.2)
(setq max-iter 20)
(defun mandel-iter-point (x y)
"Run the actual iteration for each point."
(let ((xp 0)
(yp 0)
(it 0)
(xt 0))
(while (and (< (+ (* xp xp) (* yp yp)) 4) (< it max-iter))
(setq xt (+ (* xp xp) (* -1 yp yp) x))
(setq yp (+ (* 2 xp yp) y))
(setq xp xt)
(setq it (1+ it)))
it))
(defun mandel-iter (p)
"Return string for point based on whether inside/outside the set."
(let ((it (mandel-iter-point (car p) (cdr p))))
(if (= it max-iter) "*" (if (cl-oddp it) "+" "-"))))
(defun mandel-pos (x y)
"Convert screen coordinates to input coordinates."
(let ((xp (+ xmin (* (- xmax xmin) (/ (float x) (car mandel-size)))))
(yp (+ ymin (* (- ymax ymin) (/ (float y) (cdr mandel-size))))))
(cons xp yp)))
(defun string-to-image (str)
"Convert image data string to XPM image."
(create-image (concat (format "/* XPM */
static char * mandel[] = {
\"%i %i 3 1\",
\"+ c #ff0000\",
\"- c #0000ff\",
\"* c #000000\"," (car mandel-size) (cdr mandel-size))
str "};") 'xpm t))
(defun mandel-pic ()
"Plot the Mandelbrot set."
(setq all "")
(dotimes (y (cdr mandel-size))
(setq line "")
(dotimes (x (car mandel-size))
(setq line (concat line (mandel-iter (mandel-pos x y)))))
(setq all (concat all "\"" line "\",\n")))
(insert-image (string-to-image all)))
(mandel-pic)

View file

@ -0,0 +1,50 @@
-module(mandelbrot).
-export([test/0]).
magnitude(Z) ->
R = complex:real(Z),
I = complex:imaginary(Z),
R * R + I * I.
mandelbrot(A, MaxI, Z, I) ->
case (I < MaxI) and (magnitude(Z) < 2.0) of
true ->
NZ = complex:add(complex:mult(Z, Z), A),
mandelbrot(A, MaxI, NZ, I + 1);
false ->
case I of
MaxI ->
$*;
_ ->
$
end
end.
test() ->
lists:map(
fun(S) -> io:format("~s",[S]) end,
[
[
begin
Z = complex:make(X, Y),
mandelbrot(Z, 50, Z, 1)
end
|| X <- seq_float(-2, 0.5, 0.0315)
] ++ "\n"
|| Y <- seq_float(-1,1, 0.05)
] ),
ok.
% **************************************************
% Copied from https://gist.github.com/andruby/241489
% **************************************************
seq_float(Min, Max, Inc, Counter, Acc) when (Counter*Inc + Min) >= Max ->
lists:reverse([Max|Acc]);
seq_float(Min, Max, Inc, Counter, Acc) ->
seq_float(Min, Max, Inc, Counter+1, [Inc * Counter + Min|Acc]).
seq_float(Min, Max, Inc) ->
seq_float(Min, Max, Inc, 0, []).
% **************************************************

View file

@ -0,0 +1,60 @@
open System.Drawing
open System.Windows.Forms
type Complex =
{
re : float;
im : float
}
let cplus (x:Complex) (y:Complex) : Complex =
{
re = x.re + y.re;
im = x.im + y.im
}
let cmult (x:Complex) (y:Complex) : Complex =
{
re = x.re * y.re - x.im * y.im;
im = x.re * y.im + x.im * y.re;
}
let norm (x:Complex) : float =
x.re*x.re + x.im*x.im
type Mandel = class
inherit Form
static member xPixels = 500
static member yPixels = 500
val mutable bmp : Bitmap
member x.mandelbrot xMin xMax yMin yMax maxIter =
let rec mandelbrotIterator z c n =
if (norm z) > 2.0 then false else
match n with
| 0 -> true
| n -> let z' = cplus ( cmult z z ) c in
mandelbrotIterator z' c (n-1)
let dx = (xMax - xMin) / (float (Mandel.xPixels))
let dy = (yMax - yMin) / (float (Mandel.yPixels))
in
for xi = 0 to Mandel.xPixels-1 do
for yi = 0 to Mandel.yPixels-1 do
let c = {re = xMin + (dx * float(xi) ) ;
im = yMin + (dy * float(yi) )} in
if (mandelbrotIterator {re=0.;im=0.;} c maxIter) then
x.bmp.SetPixel(xi,yi,Color.Azure)
else
x.bmp.SetPixel(xi,yi,Color.Black)
done
done
member public x.generate () = x.mandelbrot (-1.5) 0.5 (-1.0) 1.0 200 ; x.Refresh()
new() as x = {bmp = new Bitmap(Mandel.xPixels , Mandel.yPixels)} then
x.Text <- "Mandelbrot set" ;
x.Width <- Mandel.xPixels ;
x.Height <- Mandel.yPixels ;
x.BackgroundImage <- x.bmp;
x.generate();
x.Show();
end
let f = new Mandel()
do Application.Run(f)

View file

@ -0,0 +1,12 @@
let getMandelbrotValues width height maxIter ((xMin,xMax),(yMin,yMax)) =
let mandIter (cr:float,ci:float) =
let next (zr,zi) = (cr + (zr * zr - zi * zi)), (ci + (zr * zi + zi * zr))
let rec loop = function
| step,_ when step=maxIter->0
| step,(zr,zi) when ((zr * zr + zi * zi) > 2.0) -> step
| step,z -> loop ((step + 1), (next z))
loop (0,(0.0, 0.0))
let forPos =
let dx, dy = (xMax - xMin) / (float width), (yMax - yMin) / (float height)
fun y x -> mandIter ((xMin + dx * float(x)), (yMin + dy * float(y)))
[0..height-1] |> List.map(fun y->[0..width-1] |> List.map (forPos y))

View file

@ -0,0 +1,3 @@
getMandelbrotValues 80 25 50 ((-2.0,1.0),(-1.0,1.0))
|> List.map(fun row-> row |> List.map (function | 0 ->" " |_->".") |> String.concat "")
|> List.iter (printfn "%s")

View file

@ -0,0 +1,20 @@
open System.Drawing
open System.Windows.Forms
let showGraphic (colorForIter: int -> Color) (width: int) (height:int) maxIter view =
new Form()
|> fun frm ->
frm.Width <- width
frm.Height <- height
frm.BackgroundImage <-
new Bitmap(width,height)
|> fun bmp ->
getMandelbrotValues width height maxIter view
|> List.mapi (fun y row->row |> List.mapi (fun x v->((x,y),v))) |> List.collect id
|> List.iter (fun ((x,y),v) -> bmp.SetPixel(x,y,(colorForIter v)))
bmp
frm.Show()
let toColor = (function | 0 -> (0,0,0) | n -> ((31 &&& n) |> fun x->(0, 18 + x * 5, 36 + x * 7))) >> Color.FromArgb
showGraphic toColor 640 480 5000 ((-2.0,1.0),(-1.0,1.0))

View file

@ -0,0 +1,25 @@
1.1 S I1=-1.2; S I2=1.2; S R1=-2; S R2=.5
1.2 S MIT=30
1.3 F Y=1,24; D 2
1.4 Q
2.1 T !
2.2 F X=1,70; D 3
3.1 S R=X*(R2-R1)/70+R1
3.2 S I=Y*(I2-I1)/24+I1
3.3 S C1=R; S C2=I
3.4 F T=1,MIT; D 4
4.1 S C3=C1
4.2 S C1=C1*C1 - C2*C2
4.3 S C2=C3*C2 + C2*C3
4.4 S C1=C1+R
4.5 S C2=C2+I
4.6 I (-FABS(C1)+2)5.1
4.7 I (-FABS(C2)+2)5.1
4.8 I (MIT-T-1)6.1
5.1 S T=MIT; T "*"; R
6.1 T " "; R

View file

@ -0,0 +1,31 @@
! with ("::") or without (":") generalizations:
! : [a..b] ( steps a b -- a..b ) 2dup swap - 4 nrot 1 - / <range> ;
:: [a..b] ( steps a b -- a..b ) a b b a - steps 1 - / <range> ;
: >char ( n -- c )
dup -1 = [ drop 32 ] [ 26 mod CHAR: a + ] if ;
! iterates z' = z^2 + c, Factor does complex numbers!
: iter ( c z -- z' ) dup * + ;
: unbound ( c -- ? ) absq 4 > ;
:: mz ( c max i z -- n )
{
{ [ i max >= ] [ -1 ] }
{ [ z unbound ] [ i ] }
[ c max i 1 + c z iter mz ]
} cond ;
: mandelzahl ( c max -- n ) 0 0 mz ;
:: mandel ( w h max -- )
h -1. 1. [a..b] ! range over y
[ w -2. 1. [a..b] ! range over x
[ dupd swap rect> max mandelzahl >char ] map
>string print
drop ! old y
] each
;
70 25 1000 mandel

View file

@ -0,0 +1,30 @@
#!/usr/bin/env fennel
(fn mandelzahl [cr ci max i tr ti tr2 ti2]
"Calculates the Mandelbrot escape number of a complex point c"
(if (>= i max) -1
(>= (+ tr2 ti2) 4) i
(let [(tr ti) (values (+ (- tr2 ti2) cr)
(+ (* tr ti 2) ci))]
(mandelzahl cr ci max (+ i 1)
tr ti (* tr tr) (* ti ti)))))
(fn mandel [w h max]
"Entry point, generate a 'graphical' representation of the Mandelbrot set"
(for [y -1.0 1.0 (/ 2.0 h)]
(var line {})
(for [x -2.0 1.0 (/ 3.0 w)]
(let [mz (mandelzahl x y max 0 0 0 0 0)]
(tset line (+ (length line) 1)
(or (and (< mz 0) " ")
(string.char (+ (string.byte :a) (% mz 26)))))))
(print (table.concat line))))
(fn arg-def [pos default]
"A helper fn to extract command line parameter with defaults"
(or (tonumber (and arg (. arg pos))) default))
(let [width (arg-def 1 140)
height (arg-def 2 50)
max (arg-def 3 1e5)]
(mandel width height max))

View file

@ -0,0 +1,24 @@
500 value max-iter
: mandel ( gmp F: imin imax rmin rmax -- )
0e 0e { F: imin F: imax F: rmin F: rmax F: Zr F: Zi }
dup bheight 0 do
i s>f dup bheight s>f f/ imax imin f- f* imin f+ TO Zi
dup bwidth 0 do
i s>f dup bwidth s>f f/ rmax rmin f- f* rmin f+ TO Zr
Zr Zi max-iter
begin 1- dup
while fover fdup f* fover fdup f*
fover fover f+ 4e f<
while f- Zr f+
frot frot f* 2e f* Zi f+
repeat fdrop fdrop
drop 0 \ for a pretty grayscale image, replace with: 255 max-iter */
else drop 255
then fdrop fdrop
over i j rot g!
loop
loop drop ;
80 24 graymap
dup -1e 1e -2e 1e mandel

View file

@ -0,0 +1,44 @@
include lib/graphics.4th \ graphics support is needed
640 pic_width ! \ width of the image
480 pic_height ! \ height of the image
create shade \ map the shades of the image
' black , \ this is the colorscheme
' blue ,
' cyan ,
' green ,
' yellow ,
' red ,
' magenta ,
' blue ,
' cyan ,
' green ,
' yellow ,
' white ,
does> swap cells + @c execute ; \ loop through the shades available
color_image \ we're making a color image
15121 -15120 do \ do y-coordinate
15481 -21000 do \ do x-coordinate
j 0 0 0 ( l u v i)
200 0 do \ get color
>r
over dup 10 / * 1000 / \ calculate X and Y
over dup 10 / * 1000 / \ if X+Y > 40000
over over + r> swap 40000 > \ use the color in the loop
if
drop drop drop i 11 min leave
else \ otherwise try the next one
j swap >r - - >r * 5000 / over + r> swap r>
then
loop \ drop all parameters and set the shade
shade drop drop drop \ now set the proper pixel
j 15120 + 63 / i 21000 + 57 / set_pixel
57 +loop \ we're scaling the x-coordinate
63 +loop \ we're scaling the y-coordinate
s" mandelbt.ppm" save_image \ done, save the image
dup gshow
free bye

View file

@ -0,0 +1,56 @@
program mandelbrot
implicit none
integer , parameter :: rk = selected_real_kind (9, 99)
integer , parameter :: i_max = 800
integer , parameter :: j_max = 600
integer , parameter :: n_max = 100
real (rk), parameter :: x_centre = -0.5_rk
real (rk), parameter :: y_centre = 0.0_rk
real (rk), parameter :: width = 4.0_rk
real (rk), parameter :: height = 3.0_rk
real (rk), parameter :: dx_di = width / i_max
real (rk), parameter :: dy_dj = -height / j_max
real (rk), parameter :: x_offset = x_centre - 0.5_rk * (i_max + 1) * dx_di
real (rk), parameter :: y_offset = y_centre - 0.5_rk * (j_max + 1) * dy_dj
integer, dimension (i_max, j_max) :: image
integer :: i
integer :: j
integer :: n
real (rk) :: x
real (rk) :: y
real (rk) :: x_0
real (rk) :: y_0
real (rk) :: x_sqr
real (rk) :: y_sqr
do j = 1, j_max
y_0 = y_offset + dy_dj * j
do i = 1, i_max
x_0 = x_offset + dx_di * i
x = 0.0_rk
y = 0.0_rk
n = 0
do
x_sqr = x ** 2
y_sqr = y ** 2
if (x_sqr + y_sqr > 4.0_rk) then
image (i, j) = 255
exit
end if
if (n == n_max) then
image (i, j) = 0
exit
end if
y = y_0 + 2.0_rk * x * y
x = x_0 + x_sqr - y_sqr
n = n + 1
end do
end do
end do
open (10, file = 'out.pgm')
write (10, '(a/ i0, 1x, i0/ i0)') 'P2', i_max, j_max, 255
write (10, '(i0)') image
close (10)
end program mandelbrot

View file

@ -0,0 +1,56 @@
#define pix 1./120
#define zero_x 320
#define zero_y 240
#define maxiter 250
screen 12
type complex
r as double
i as double
end type
operator + (x as complex, y as complex) as complex
dim as complex ret
ret.r = x.r + y.r
ret.i = x.i + y.i
return ret
end operator
operator * (x as complex, y as complex) as complex
dim as complex ret
ret.r = x.r*y.r - x.i*y.i
ret.i = x.r*y.i + x.i*y.r
return ret
end operator
operator abs ( x as complex ) as double
return sqr(x.r*x.r + x.i*x.i)
end operator
dim as complex c, z
dim as integer x, y, iter
for x=0 to 639
for y=0 to 240
c.r = (x-zero_x)*pix
c.i = (y-zero_y)*pix
z.r = 0.0
z.i = 0.0
for iter=0 to maxiter
z = z*z + c
if abs(z)>2 then
pset(x,y),iter mod 16
pset(x,480-y),iter mod 16
goto cont
end if
next iter
pset(x,y),1
pset(x,480-y),1
cont:
next y
next x
while inkey=""
wend
end

View file

@ -0,0 +1,35 @@
// Maximum levels for each pixel.
levels = 60
// Create a random color for each level.
colors = new array[[levels]]
for a = 0 to levels-1
colors@a = new color[randomFloat[0,1], randomFloat[0,1], randomFloat[0,1]]
// Make this number smaller for higher resolution.
stepsize = .005
g = new graphics
g.antialiased[false]
for im = -1.2 to 1.2 step stepsize
{
imag = i * im
for real = -2 to 1 step stepsize
{
C = real + imag
z = 0
count = -1
do
{
z = z^2 + C
count=count+1;
} while abs[z] < 4 and count < levels
g.color[colors@((count-1) mod levels)]
g.fillRectSize[real, im, stepsize, stepsize]
}
}
g.show[]

View file

@ -0,0 +1,44 @@
###sysinclude X.uh
$ff0000 sto szin
300 sto maxiter
maxypixel sto YRES
maxxpixel sto XRES
myscreen "Mandelbrot" @YRES @XRES graphic
@YRES 2 / (#d) sto y2
@YRES 2 / (#d) sto x2
#g 0. @XRES (#d) 1. i: {#d
#g 0. @YRES (#d) 1. {#d
#d
{#d}§i 400. - @x2 - @x2 /
sto x
{#d} @y2 - @y2 /
sto y
zero#d xa zero#d ya zero iter
(( #d
@x @xa dup* @ya dup* -+
@y @xa *2 @ya *+ sto ya
sto xa #g inc iter
@iter @maxiter >= then((>))
#d ( @xa dup* @ya dup* + 4. > )))
#g @iter @maxiter == { #d
myscreen {d} {d}§i @szin [][]
}{ #d
myscreen {d} {d}§i #g @iter 64 * [][]
}
#d}
#d}
(( ( myscreen key? 10000 usleep )))
myscreen !graphic
end
{ „x” }
{ „x2” }
{ „y” }
{ „y2” }
{ „xa” }
{ „ya” }
{ „iter” }
{ „maxiter” }
{ „szin” }
{ „YRES” }
{ „XRES” }
{ „myscreen” }

View file

@ -0,0 +1,40 @@
default(f32)
type complex = (f32, f32)
fun dot(c: complex): f32 =
let (r, i) = c
in r * r + i * i
fun multComplex(x: complex, y: complex): complex =
let (a, b) = x
let (c, d) = y
in (a*c - b * d,
a*d + b * c)
fun addComplex(x: complex, y: complex): complex =
let (a, b) = x
let (c, d) = y
in (a + c,
b + d)
fun divergence(depth: int, c0: complex): int =
loop ((c, i) = (c0, 0)) = while i < depth && dot(c) < 4.0 do
(addComplex(c0, multComplex(c, c)),
i + 1)
in i
fun mandelbrot(screenX: int, screenY: int, depth: int, view: (f32,f32,f32,f32)): [screenX][screenY]int =
let (xmin, ymin, xmax, ymax) = view
let sizex = xmax - xmin
let sizey = ymax - ymin
in map (fn (x: int): [screenY]int =>
map (fn (y: int): int =>
let c0 = (xmin + (f32(x) * sizex) / f32(screenX),
ymin + (f32(y) * sizey) / f32(screenY))
in divergence(depth, c0))
(iota screenY))
(iota screenX)
fun main(screenX: int, screenY: int, depth: int, xmin: f32, ymin: f32, xmax: f32, ymax: f32): [screenX][screenY]int =
mandelbrot(screenX, screenY, depth, (xmin, ymin, xmax, ymax))

View file

@ -0,0 +1,42 @@
_xmin = -8601
_xmax = 2867
_ymin = -4915
_ymax = 4915
_maxiter = 32
_dx = ( _xmax - _xmin ) / 79
_dy = ( _ymax - _ymin ) / 24
void local fn MandelbrotSet
printf @"\n"
SInt32 cy = _ymin
while ( cy <= _ymax )
SInt32 cx = _xmin
while ( cx <= _xmax )
SInt32 x = 0
SInt32 y = 0
SInt32 x2 = 0
SInt32 y2 = 0
SInt32 iter = 0
while ( iter < _maxiter )
if ( x2 + y2 > 16384 ) then break
y = ( ( x * y ) >> 11 ) + (SInt32)cy
x = x2 - y2 + (SInt32)cx
x2 = ( x * x ) >> 12
y2 = ( y * y ) >> 12
iter++
wend
print fn StringWithFormat( @"%3c", iter + 32 );
cx += _dx
wend
printf @"\n"
cy += _dy
wend
end fn
window 1, @"Mandelbrot Set", ( 0, 0, 820, 650 )
WindowSetBackgroundColor( 1, fn ColorBlack )
text @"Impact", 10.0, fn ColorWithRGB( 1.000, 0.800, 0.000, 1.0 )
fn MandelbrotSet
HandleEvents

View file

@ -0,0 +1,49 @@
const int MaxIterations = 1000;
const vec2 Focus = vec2(-0.51, 0.54);
const float Zoom = 1.0;
vec3
color(int iteration, float sqLengthZ) {
// If the point is within the mandlebrot set
// just color it black
if(iteration == MaxIterations)
return vec3(0.0);
// Else we give it a smoothed color
float ratio = (float(iteration) - log2(log2(sqLengthZ))) / float(MaxIterations);
// Procedurally generated colors
return mix(vec3(1.0, 0.0, 0.0), vec3(1.0, 1.0, 0.0), sqrt(ratio));
}
void
mainImage(out vec4 fragColor, in vec2 fragCoord) {
// C is the aspect-ratio corrected UV coordinate.
vec2 c = (-1.0 + 2.0 * fragCoord / iResolution.xy) * vec2(iResolution.x / iResolution.y, 1.0);
// Apply scaling, then offset to get a zoom effect
c = (c * exp(-Zoom)) + Focus;
vec2 z = c;
int iteration = 0;
while(iteration < MaxIterations) {
// Precompute for efficiency
float zr2 = z.x * z.x;
float zi2 = z.y * z.y;
// The larger the square length of Z,
// the smoother the shading
if(zr2 + zi2 > 32.0) break;
// Complex multiplication, then addition
z = vec2(zr2 - zi2, 2.0 * z.x * z.y) + c;
++iteration;
}
// Generate the colors
fragColor = vec4(color(iteration, dot(z,z)), 1.0);
// Apply gamma correction
fragColor.rgb = pow(fragColor.rgb, vec3(0.5));
}

View file

@ -0,0 +1,20 @@
10 SCALE# = 1/60 : ZEROX = 160
20 ZEROY = 100 : MAXIT = 32
30 SCREEN 1
40 FOR X = 0 TO 2*ZEROX - 1
50 CR# = (X-ZEROX)*SCALE#
60 FOR Y = 0 TO ZEROY
70 CI# = (ZEROY-Y)*SCALE#
80 ZR# = 0
90 ZI# = 0
100 FOR I = 1 TO MAXIT
110 BR# = CR# + ZR#*ZR# - ZI#*ZI#
120 ZI# = CI# + 2*ZR#*ZI#
130 ZR# = BR#
140 IF ZR#*ZR# + ZI#*ZI# > 4 THEN GOTO 170
150 NEXT I
160 GOTO 190
170 PSET (X, Y), 1 + (I MOD 3)
180 PSET (X, 2*ZEROY-Y), 1+(I MOD 3)
190 NEXT Y
200 NEXT X

View file

@ -0,0 +1,2 @@
set terminal png
set output 'mandelbrot.png'

View file

@ -0,0 +1,9 @@
rmax = 2
nmax = 100
complex (x, y) = x * {1, 0} + y * {0, 1}
mandelbrot (z, z0, n) = n == nmax || abs (z) > rmax ? n : mandelbrot (z ** 2 + z0, z0, n + 1)
set samples 200
set isosamples 200
set pm3d map
set size square
splot [-2 : .8] [-1.4 : 1.4] mandelbrot (complex (0, 0), complex (x, y), 0) notitle

View file

@ -0,0 +1,24 @@
package main
import "fmt"
import "math/cmplx"
func mandelbrot(a complex128) (z complex128) {
for i := 0; i < 50; i++ {
z = z*z + a
}
return
}
func main() {
for y := 1.0; y >= -1.0; y -= 0.05 {
for x := -2.0; x <= 0.5; x += 0.0315 {
if cmplx.Abs(mandelbrot(complex(x, y))) < 2 {
fmt.Print("*")
} else {
fmt.Print(" ")
}
}
fmt.Println("")
}
}

View file

@ -0,0 +1,60 @@
package main
import (
"fmt"
"image"
"image/color"
"image/draw"
"image/png"
"math/cmplx"
"os"
)
const (
maxEsc = 100
rMin = -2.
rMax = .5
iMin = -1.
iMax = 1.
width = 750
red = 230
green = 235
blue = 255
)
func mandelbrot(a complex128) float64 {
i := 0
for z := a; cmplx.Abs(z) < 2 && i < maxEsc; i++ {
z = z*z + a
}
return float64(maxEsc-i) / maxEsc
}
func main() {
scale := width / (rMax - rMin)
height := int(scale * (iMax - iMin))
bounds := image.Rect(0, 0, width, height)
b := image.NewNRGBA(bounds)
draw.Draw(b, bounds, image.NewUniform(color.Black), image.ZP, draw.Src)
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
fEsc := mandelbrot(complex(
float64(x)/scale+rMin,
float64(y)/scale+iMin))
b.Set(x, y, color.NRGBA{uint8(red * fEsc),
uint8(green * fEsc), uint8(blue * fEsc), 255})
}
}
f, err := os.Create("mandelbrot.png")
if err != nil {
fmt.Println(err)
return
}
if err = png.Encode(f, b); err != nil {
fmt.Println(err)
}
if err = f.Close(); err != nil {
fmt.Println(err)
}
}

View file

@ -0,0 +1,3 @@
20{40{0.1{.{;..*2$.*\-
20/3$-@@*10/3$-..*2$.*+1600<}*}32*'
*'=\;\;@@(}60*;(n\}40*;]''+

View file

@ -0,0 +1,30 @@
use fmt;
use math;
type complex = struct {
re: f64,
im: f64
};
export fn main() void = {
for (let y = -1.2; y < 1.2; y += 0.05) {
for (let x = -2.05; x < 0.55; x += 0.03) {
let z = complex {re = 0.0, im = 0.0};
for (let m = 0z; m < 100; m += 1) {
let tz = z;
z.re = tz.re*tz.re - tz.im*tz.im;
z.im = tz.re*tz.im + tz.im*tz.re;
z.re += x;
z.im += y;
};
fmt::print(if (abs(z) < 2f64) '#' else '.')!;
};
fmt::println()!;
};
};
fn abs(z: complex) f64 = {
return math::sqrtf64(z.re*z.re + z.im*z.im);
};

View file

@ -0,0 +1,15 @@
import Data.Bool ( bool )
import Data.Complex (Complex ((:+)), magnitude)
mandelbrot :: RealFloat a => Complex a -> Complex a
mandelbrot a = iterate ((a +) . (^ 2)) 0 !! 50
main :: IO ()
main =
mapM_
putStrLn
[ [ bool ' ' '*' (2 > magnitude (mandelbrot (x :+ y)))
| x <- [-2, -1.9685 .. 0.5]
]
| y <- [1, 0.95 .. -1]
]

View file

@ -0,0 +1,13 @@
-- first attempt
-- putStrLn $ foldr (++) "" [ if x==(-2) then "\n" else let (a, b) = iterate (\(x', y') -> (x'^2-y'^2+x, 2*x'*y'+y)) (0, 0) !! 500 in (snd.head.filter (\(v, c)->v) $ zip ([(<0.01), (<0.025), (<0.05), (<0.1), (<0.5), (<1), (<4), (\_ -> True)] <*> [a^2 + b^2]) [".", "\'", ":", "!", "|", "}", "#", " "]) | y <- [1, 0.98 .. -1], x <- [-2, -1.98 .. 0.5]]
-- replaced iterate with foldr, modified the snd.head part and a introduced a check to stop the magnitude from exploding
-- foldr(>>)(return())[putStrLn[let(a,b)=foldr(\_(u,w)->if(u^2+w^2<4)then(u^2-w^2+x,2*u*w+y)else(u,w))(0,0)[1..500]in snd.last$(filter(\(f,v)->f)$zip(map(a^2+b^2>)[0,0.01,0.025,0.05,0.1,0.5,1,4])['.','\'',':','!','|','}','#',' '])|x<-[-2,-1.98..0.5]]|y<-[1,0.98.. -1]]
-- without different characters in the output
-- foldr(>>)(return())[putStrLn[let(a,b)=foldr(\_(u,w)->(u^2-w^2+x,2*u*w+y))(0,0)[1..500]in if a^2+b^2<4 then '*' else ' '|x<-[-2,-1.98..0.5]]|y<-[1,0.98.. -1]]
-- using mapM_ instead of foldr, bind operator instead of list comprehension and replacing 'let' with a lambda function
-- mapM_ putStrLn $[1,0.98.. -1]>>= \y->return $[-2,-1.98..0.5]>>= \x->return (if(\(a,b)->a^2+b^2<4)(foldr(\_(u,w)->(u^2-w^2+x,2*u*w+y))(0,0)[1..500]) then '*' else ' ')
-- open GHCI > Copy and paste any of above one-liners > Hit enter

View file

@ -0,0 +1,32 @@
main :: IO ()
main =
putStrLn $
concat
[ go x y
| y <- [1, 0.98 .. -1],
x <- [-2, -1.98 .. 0.5]
]
where
go x y
| x == (-2) = "\n"
| otherwise =
let (a, b) =
iterate
(\(x', y') -> (x' ^ 2 - y' ^ 2 + x, 2 * x' * y' + y))
(0, 0)
!! 500
in ( snd . head . filter fst $
zip
( [ (< 0.01),
(< 0.025),
(< 0.05),
(< 0.1),
(< 0.5),
(< 1),
(< 4),
const True
]
<*> [a ^ 2 + b ^ 2]
)
[".", "\'", ":", "!", "|", "}", "#", " "]
)

View file

@ -0,0 +1,20 @@
main :: IO ()
main =
mapM_
putStrLn
$ [1, 0.98 .. -1]
>>= \y ->
[ [-2, -1.98 .. 0.5]
>>= \x ->
[ if (\(a, b) -> a ^ 2 + b ^ 2 < 4)
( foldr
( \_ (u, w) ->
(u ^ 2 - w ^ 2 + x, 2 * u * w + y)
)
(0, 0)
[1 .. 500]
)
then '*'
else ' '
]
]

View file

@ -0,0 +1 @@
haxe -swf mandelbrot.swf -main Mandelbrot

View file

@ -0,0 +1,49 @@
class Mandelbrot extends flash.display.Sprite
{
inline static var MAX_ITER = 255;
public static function main() {
var w = flash.Lib.current.stage.stageWidth;
var h = flash.Lib.current.stage.stageHeight;
var mandelbrot = new Mandelbrot(w, h);
flash.Lib.current.stage.addChild(mandelbrot);
mandelbrot.drawMandelbrot();
}
var image:flash.display.BitmapData;
public function new(width, height) {
super();
var bitmap:flash.display.Bitmap;
image = new flash.display.BitmapData(width, height, false);
bitmap = new flash.display.Bitmap(image);
this.addChild(bitmap);
}
public function drawMandelbrot() {
image.lock();
var step_x = 3.0 / (image.width-1);
var step_y = 2.0 / (image.height-1);
for (i in 0...image.height) {
var ci = i * step_y - 1.0;
for (j in 0...image.width) {
var k = 0;
var zr = 0.0;
var zi = 0.0;
var cr = j * step_x - 2.0;
while (k <= MAX_ITER && (zr*zr + zi*zi) <= 4) {
var temp = zr*zr - zi*zi + cr;
zi = 2*zr*zi + ci;
zr = temp;
k ++;
}
paint(j, i, k);
}
}
image.unlock();
}
inline function paint(x, y, iter) {
var color = iter > MAX_ITER? 0 : iter * 0x100;
image.setPixel(x, y, color);
}
}

View file

@ -0,0 +1,55 @@
#! /bin/sh
exec huginn -E "${0}" "${@}"
#! huginn
import Algorithms as algo;
import Mathematics as math;
import Terminal as term;
mandelbrot( x, y ) {
c = math.Complex( x, y );
z = math.Complex( 0., 0. );
s = -1;
for ( i : algo.range( 50 ) ) {
z = z * z + c;
if ( | z | > 2. ) {
s = i;
break;
}
}
return ( s );
}
main( argv_ ) {
imgSize = term_size( argv_ );
yRad = 1.2;
yScale = 2. * yRad / real( imgSize[0] );
xScale = 3.3 / real( imgSize[1] );
glyphTab = [ ".", ":", "-", "+", "+" ].resize( 12, "*" ).resize( 26, "%" ).resize( 50, "@" ).push( " " );
for ( y : algo.range( imgSize[0] ) ) {
line = "";
for ( x : algo.range( imgSize[1] ) ) {
line += glyphTab[ mandelbrot( xScale * real( x ) - 2.3, yScale * real( y ) - yRad ) ];
}
print( line + "\n" );
}
return ( 0 );
}
term_size( argv_ ) {
lines = 25;
columns = 80;
if ( size( argv_ ) == 3 ) {
lines = integer( argv_[1] );
columns = integer( argv_[2] );
} else {
lines = term.lines();
columns = term.columns();
if ( ( lines % 2 ) == 0 ) {
lines -= 1;
}
}
lines -= 1;
columns -= 1;
return ( ( lines, columns ) );
}

View file

@ -0,0 +1,45 @@
PRO Mandelbrot,xRange,yRange,xPixels,yPixels,iterations
xPixelstartVec = Lindgen( xPixels) * Float(xRange[1]-xRange[0]) / $
xPixels + xRange[0]
yPixelstartVec = Lindgen( yPixels) * Float(YRANGE[1]-yrange[0])$
/ yPixels + yRange[0]
constArr = Complex( Rebin( xPixelstartVec, xPixels, yPixels),$
Rebin( Transpose(yPixelstartVec), xPixels, yPixels))
valArr = ComplexArr( xPixels, yPixels)
res = IntArr( xPixels, yPixels)
oriIndex = Lindgen( Long(xPixels) * yPixels)
FOR i = 0, iterations-1 DO BEGIN ; only one loop needed
; calculation for whole array at once
valArr = valArr^2 - constArr
whereIn = Where( Abs( valArr) LE 4.0d, COMPLEMENT=whereOut)
IF whereIn[0] EQ -1 THEN BREAK
valArr = valArr[ whereIn]
constArr = constArr[ whereIn]
IF whereOut[0] NE -1 THEN BEGIN
res[ oriIndex[ whereOut]] = i+1
oriIndex = oriIndex[ whereIn]
ENDIF
ENDFOR
tv,res ; open a window and show the result
END
Mandelbrot,[-1.,2.3],[-1.3,1.3],640,512,200
END

View file

@ -0,0 +1 @@
GDL>.run mandelbrot

View file

@ -0,0 +1 @@
GDL> Mandelbrot,[-1.,2.3],[-1.3,1.3],640,512,200

View file

@ -0,0 +1,46 @@
link graphics
procedure main()
width := 750
height := 600
limit := 100
WOpen("size="||width||","||height)
every x:=1 to width & y:=1 to height do
{
z:=complex(0,0)
c:=complex(2.5*x/width-2.0,(2.0*y/height-1.0))
j:=0
while j<limit & cAbs(z)<2.0 do
{
z := cAdd(cMul(z,z),c)
j+:= 1
}
Fg(mColor(j,limit))
DrawPoint(x,y)
}
WriteImage("./mandelbrot.gif")
WDone()
end
procedure mColor(x,limit)
max_color := 2^16-1
color := integer(max_color*(real(x)/limit))
return(if x=limit
then "black"
else color||","||color||",0")
end
record complex(r,i)
procedure cAdd(x,y)
return complex(x.r+y.r,x.i+y.i)
end
procedure cMul(x,y)
return complex(x.r*y.r-x.i*y.i,x.r*y.i+x.i*y.r)
end
procedure cAbs(x)
return sqrt(x.r*x.r+x.i*x.i)
end

View file

@ -0,0 +1,186 @@
"Mandelbrot"
The story headline is "A Non-Interactive Set".
Include Glimmr Drawing Commands by Erik Temple.
[Q20 fixed-point or floating-point: see definitions below]
Use floating-point math.
Finished is a room.
The graphics-window is a graphics g-window spawned by the main-window.
The position is g-placeabove.
When play begins:
let f10 be 10 as float;
now min re is ( -20 as float ) fdiv f10;
now max re is ( 6 as float ) fdiv f10;
now min im is ( -12 as float ) fdiv f10;
now max im is ( 12 as float ) fdiv f10;
now max iterations is 100;
add color g-Black to the palette;
add color g-Red to the palette;
add hex "#FFA500" to the palette;
add color g-Yellow to the palette;
add color g-Green to the palette;
add color g-Blue to the palette;
add hex "#4B0082" to the palette;
add hex "#EE82EE" to the palette;
open up the graphics-window.
Min Re is a number that varies.
Max Re is a number that varies.
Min Im is a number that varies.
Max Im is a number that varies.
Max Iterations is a number that varies.
Min X is a number that varies.
Max X is a number that varies.
Min Y is a number that varies.
Max Y is a number that varies.
The palette is a list of numbers that varies.
[vertically mirrored version]
Window-drawing rule for the graphics-window when max im is fneg min im:
clear the graphics-window;
let point be { 0, 0 };
now min X is 0 as float;
now min Y is 0 as float;
let mX be the width of the graphics-window minus 1;
let mY be the height of the graphics-window minus 1;
now max X is mX as float;
now max Y is mY as float;
let L be the column order with max mX;
repeat with X running through L:
now entry 1 in point is X;
repeat with Y running from 0 to mY / 2:
now entry 2 in point is Y;
let the scaled point be the complex number corresponding to the point;
let V be the Mandelbrot result for the scaled point;
let C be the color corresponding to V;
if C is 0, next;
draw a rectangle (C) in the graphics-window at the point with size 1 by 1;
now entry 2 in point is mY - Y;
draw a rectangle (C) in the graphics-window at the point with size 1 by 1;
yield to VM;
rule succeeds.
[slower non-mirrored version]
Window-drawing rule for the graphics-window:
clear the graphics-window;
let point be { 0, 0 };
now min X is 0 as float;
now min Y is 0 as float;
let mX be the width of the graphics-window minus 1;
let mY be the height of the graphics-window minus 1;
now max X is mX as float;
now max Y is mY as float;
let L be the column order with max mX;
repeat with X running through L:
now entry 1 in point is X;
repeat with Y running from 0 to mY:
now entry 2 in point is Y;
let the scaled point be the complex number corresponding to the point;
let V be the Mandelbrot result for the scaled point;
let C be the color corresponding to V;
if C is 0, next;
draw a rectangle (C) in the graphics-window at the point with size 1 by 1;
yield to VM;
rule succeeds.
To decide which list of numbers is column order with max (N - number):
let L be a list of numbers;
let L2 be a list of numbers;
let D be 64;
let rev be false;
while D > 0:
let X be 0;
truncate L2 to 0 entries;
while X <= N:
if D is 64 or X / D is odd, add X to L2;
increase X by D;
if rev is true:
reverse L2;
let rev be false;
otherwise:
let rev be true;
add L2 to L;
let D be D / 2;
decide on L.
To decide which list of numbers is complex number corresponding to (P - list of numbers):
let R be a list of numbers;
extend R to 2 entries;
let X be entry 1 in P as float;
let X be (max re fsub min re) fmul (X fdiv max X);
let X be X fadd min re;
let Y be entry 2 in P as float;
let Y be (max im fsub min im) fmul (Y fdiv max Y);
let Y be Y fadd min im;
now entry 1 in R is X;
now entry 2 in R is Y;
decide on R.
To decide which number is Mandelbrot result for (P - list of numbers):
let c_re be entry 1 in P;
let c_im be entry 2 in P;
let z_re be 0 as float;
let z_im be z_re;
let threshold be 4 as float;
let runs be 0;
while 1 is 1:
[ z = z * z ]
let r2 be z_re fmul z_re;
let i2 be z_im fmul z_im;
let ri be z_re fmul z_im;
let z_re be r2 fsub i2;
let z_im be ri fadd ri;
[ z = z + c ]
let z_re be z_re fadd c_re;
let z_im be z_im fadd c_im;
let norm be (z_re fmul z_re) fadd (z_im fmul z_im);
increase runs by 1;
if norm is greater than threshold, decide on runs;
if runs is max iterations, decide on 0.
To decide which number is color corresponding to (V - number):
let L be the number of entries in the palette;
let N be the remainder after dividing V by L;
decide on entry (N + 1) in the palette.
Section - Fractional numbers (for Glulx only)
To decide which number is (N - number) as float: (- (numtof({N})) -).
To decide which number is (N - number) fadd (M - number): (- (fadd({N}, {M})) -).
To decide which number is (N - number) fsub (M - number): (- (fsub({N}, {M})) -).
To decide which number is (N - number) fmul (M - number): (- (fmul({N}, {M})) -).
To decide which number is (N - number) fdiv (M - number): (- (fdiv({N}, {M})) -).
To decide which number is fneg (N - number): (- (fneg({N})) -).
To yield to VM: (- glk_select_poll(gg_event); -).
Use Q20 fixed-point math translates as (- Constant Q20_MATH; -).
Use floating-point math translates as (- Constant FLOAT_MATH; -).
Include (-
#ifdef Q20_MATH;
! Q11.20 format: 1 sign bit, 11 integer bits, 20 fraction bits
[ numtof n r; @shiftl n 20 r; return r; ];
[ fadd n m; return n+m; ];
[ fsub n m; return n-m; ];
[ fmul n m; n = n + $$1000000000; @sshiftr n 10 n; m = m + $$1000000000; @sshiftr m 10 m; return n * m; ];
[ fdiv n m; @sshiftr m 20 m; return n / m; ];
[ fneg n; return -n; ];
#endif;
#ifdef FLOAT_MATH;
[ numtof f; @"S2:400" f f; return f; ];
[ fadd n m; @"S3:416" n m n; return n; ];
[ fsub n m; @"S3:417" n m n; return n; ];
[ fmul n m; @"S3:418" n m n; return n; ];
[ fdiv n m; @"S3:419" n m n; return n; ];
[ fneg n; @bitxor n $80000000 n; return n; ];
#endif;
-).

View file

@ -0,0 +1 @@
mcf=. (<: 2:)@|@(] ((*:@] + [)^:((<: 2:)@|@])^:1000) 0:) NB. 1000 iterations test

View file

@ -0,0 +1,4 @@
domain=. |.@|:@({.@[ + ] *~ j./&i.&>/@+.@(1j1 + ] %~ -~/@[))&>/
load 'viewmat'
viewmat mcf "0 @ domain (_2j_1 1j1) ; 0.01 NB. Complex interval and resolution

View file

@ -0,0 +1 @@
viewmat mcf "0 @ domain (_2j_1 1j1) ; 0.1 NB. Complex interval and resolution

View file

@ -0,0 +1,43 @@
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
public class Mandelbrot extends JFrame {
private final int MAX_ITER = 570;
private final double ZOOM = 150;
private BufferedImage I;
private double zx, zy, cX, cY, tmp;
public Mandelbrot() {
super("Mandelbrot Set");
setBounds(100, 100, 800, 600);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
I = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < getHeight(); y++) {
for (int x = 0; x < getWidth(); x++) {
zx = zy = 0;
cX = (x - 400) / ZOOM;
cY = (y - 300) / ZOOM;
int iter = MAX_ITER;
while (zx * zx + zy * zy < 4 && iter > 0) {
tmp = zx * zx - zy * zy + cX;
zy = 2.0 * zx * zy + cY;
zx = tmp;
iter--;
}
I.setRGB(x, y, iter | (iter << 8));
}
}
}
@Override
public void paint(Graphics g) {
g.drawImage(I, 0, 0, this);
}
public static void main(String[] args) {
new Mandelbrot().setVisible(true);
}
}

View file

@ -0,0 +1,294 @@
import static java.awt.Color.HSBtoRGB;
import static java.awt.Color.black;
import static java.awt.event.KeyEvent.VK_BACK_SLASH;
import static java.awt.event.KeyEvent.VK_ESCAPE;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import static java.lang.Integer.signum;
import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.System.currentTimeMillis;
import static java.util.Locale.ROOT;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.function.Consumer;
import java.util.function.Predicate;
import javax.swing.JFrame;
/*
* click: point to center
* ctrl-click: point to origin
* drag: point to mouse release point
* ctrl-drag: point to origin + zoom
* back-slash: back to previous point
* esc: back to previous zoom point - zoom
*/
public class Mandelbrot extends JFrame {
private static final long serialVersionUID = 1L;
private Insets insets;
private int width, height;
private double widthHeightRatio;
private int minX, minY;
private double Zoom;
private int mpX, mpY, mdX, mdY;
private boolean isCtrlDown, ctrl;
private Stack stack = new Stack();
private BufferedImage image;
private boolean newImage = true;
public static void main(String[] args) {
new Mandelbrot(800, 600); // (800, 600), (1024, 768), (1600, 900), (1920, 1080)
//new Mandelbrot(800, 600, 4.5876514379235943e-09, -0.6092161175392330, -0.4525577210859453);
//new Mandelbrot(800, 600, 5.9512354925205320e-10, -0.6092146769531246, -0.4525564820098262);
//new Mandelbrot(800, 600, 6.7178527589983420e-08, -0.7819036465400592, -0.1298363433443265);
//new Mandelbrot(800, 600, 4.9716091454775210e-09, -0.7818800036717134, -0.1298044093748981);
//new Mandelbrot(800, 600, 7.9333341281639390e-06, -0.7238770725243187, -0.2321214232559487);
/*
new Mandelbrot(800, 600, new double[][] {
{5.0000000000000000e-03, -2.6100000000000000, -1.4350000000000000}, // done!
{3.5894206549118390e-04, -0.7397795969773300, -0.4996473551637279}, // done!
{3.3905106941862460e-05, -0.6270410477828043, -0.4587021918164572}, // done!
{6.0636337351945460e-06, -0.6101531446039512, -0.4522561221394852}, // done!
{1.5502741161769430e-06, -0.6077214060084073, -0.4503995886987711}, // done!
});
//*/
}
public Mandelbrot(int width, int height) {
this(width, height, .005, -2.61, -1.435);
}
public Mandelbrot(int width, int height, double Zoom, double r, double i) {
this(width, height, new double[] {Zoom, r, i});
}
public Mandelbrot(int width, int height, double[] ... points) {
super("Mandelbrot Set");
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Dimension screen = getToolkit().getScreenSize();
setBounds(
rint((screen.getWidth() - width) / 2),
rint((screen.getHeight() - height) / 2),
width,
height
);
addMouseListener(mouseAdapter);
addMouseMotionListener(mouseAdapter);
addKeyListener(keyAdapter);
Point point = stack.push(points);
this.Zoom = point.Zoom;
this.minX = point.minX;
this.minY = point.minY;
setVisible(true);
insets = getInsets();
this.width = width -= insets.left + insets.right;
this.height = height -= insets.top + insets.bottom;
widthHeightRatio = (double) width / height;
}
private int rint(double d) {
return (int) Math.rint(d); // half even
}
private void repaint(boolean newImage) {
this.newImage = newImage;
repaint();
}
private MouseAdapter mouseAdapter = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
stack.push(false);
if (!ctrl) {
minX -= width / 2 ;
minY -= height / 2;
}
minX += e.getX() - insets.left;
minY += e.getY() - insets.top;
ctrl = false;
repaint(true);
}
public void mousePressed(MouseEvent e) {
mpX = e.getX();
mpY = e.getY();
ctrl = isCtrlDown;
}
public void mouseDragged(MouseEvent e) {
if (!ctrl) return;
setMdCoord(e);
repaint();
}
private void setMdCoord(MouseEvent e) {
int dx = e.getX() - mpX;
int dy = e.getY() - mpY;
mdX = mpX + max(abs(dx), rint(abs(dy) * widthHeightRatio) * signum(dx));
mdY = mpY + max(abs(dy), rint(abs(dx) / widthHeightRatio) * signum(dy));
acceptIf(insets.left, ge(mdX), setMdXY);
acceptIf(insets.top, ge(mdY), setMdYX);
acceptIf(insets.left+width-1, le(mdX), setMdXY);
acceptIf(insets.top+height-1, le(mdY), setMdYX);
}
private void acceptIf(int value, Predicate<Integer> p, Consumer<Integer> c) { if (p.test(value)) c.accept(value); }
private Predicate<Integer> ge(int md) { return v-> v >= md; }
private Predicate<Integer> le(int md) { return v-> v <= md; }
private Consumer<Integer> setMdXY = v-> mdY = mpY + rint(abs((mdX=v)-mpX) / widthHeightRatio) * signum(mdY-mpY);
private Consumer<Integer> setMdYX = v-> mdX = mpX + rint(abs((mdY=v)-mpY) * widthHeightRatio) * signum(mdX-mpX);
public void mouseReleased(MouseEvent e) {
if (e.getX() == mpX && e.getY() == mpY) return;
stack.push(ctrl);
if (!ctrl) {
minX += mpX - (mdX = e.getX());
minY += mpY - (mdY = e.getY());
}
else {
setMdCoord(e);
if (mdX < mpX) { int t=mpX; mpX=mdX; mdX=t; }
if (mdY < mpY) { int t=mpY; mpY=mdY; mdY=t; }
minX += mpX - insets.left;
minY += mpY - insets.top;
double rZoom = (double) width / abs(mdX - mpX);
minX *= rZoom;
minY *= rZoom;
Zoom /= rZoom;
}
ctrl = false;
repaint(true);
}
};
private KeyAdapter keyAdapter = new KeyAdapter() {
public void keyPressed(KeyEvent e) {
isCtrlDown = e.isControlDown();
}
public void keyReleased(KeyEvent e) {
isCtrlDown = e.isControlDown();
}
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
boolean isEsc = c == VK_ESCAPE;
if (!isEsc && c != VK_BACK_SLASH) return;
repaint(stack.pop(isEsc));
}
};
private class Point {
public boolean type;
public double Zoom;
public int minX;
public int minY;
Point(boolean type, double Zoom, int minX, int minY) {
this.type = type;
this.Zoom = Zoom;
this.minX = minX;
this.minY = minY;
}
}
private class Stack extends java.util.Stack<Point> {
private static final long serialVersionUID = 1L;
public Point push(boolean type) {
return push(type, Zoom, minX, minY);
}
public Point push(boolean type, double ... point) {
double Zoom = point[0];
return push(type, Zoom, rint(point[1]/Zoom), rint(point[2]/Zoom));
}
public Point push(boolean type, double Zoom, int minX, int minY) {
return push(new Point(type, Zoom, minX, minY));
}
public Point push(double[] ... points) {
Point lastPoint = push(false, points[0]);
for (int i=0, e=points.length-1; i<e; i+=1) {
double[] point = points[i];
lastPoint = push(point[0] != points[i+1][0], point);
done(printPoint(lastPoint));
}
return lastPoint;
}
public boolean pop(boolean type) {
for (;;) {
if (empty()) return false;
Point d = super.pop();
Zoom = d.Zoom;
minX = d.minX;
minY = d.minY;
if (!type || d.type) return true;
}
}
}
@Override
public void paint(Graphics g) {
if (newImage) newImage();
g.drawImage(image, insets.left, insets.top, this);
//g.drawLine(insets.left+width/2, insets.top+0, insets.left+width/2, insets.top+height);
//g.drawLine(insets.left+0, insets.top+height/2, insets.left+width, insets.top+height/2);
if (!ctrl) return;
g.drawRect(min(mpX, mdX), min(mpY, mdY), abs(mpX - mdX), abs(mpY - mdY));
}
private void newImage() {
long milli = printPoint();
image = new BufferedImage(width, height, TYPE_INT_RGB);
int maxX = minX + width;
int maxY = minY + height;
for (int x = minX; x < maxX; x+=1) {
double r = x * Zoom;
for (int y = minY; y < maxY; y+=1) {
double i = y * Zoom;
//System.out.printf("%+f%+fi\n", r, i);
// 0f 1/6f 1/3f 1/2f 2/3f 5/6f
//straight -> red yellow green cian blue magenta <- reverse
image.setRGB(x-minX, y-minY, color(r, i, 360, false, 2/3f));
}
}
newImage = false;
done(milli);
}
private long printPoint() {
return printPoint(Zoom, minX, minY);
}
private long printPoint(Point point) {
return printPoint(point.Zoom, point.minX, point.minY);
}
private long printPoint(double Zoom, int minX, int minY) {
return printPoint(Zoom, minX*Zoom, minY*Zoom);
}
private long printPoint(Object ... point) {
System.out.printf(ROOT, "{%.16e, %.16g, %.16g},", point);
return currentTimeMillis();
}
private void done(long milli) {
milli = currentTimeMillis() - milli;
System.out.println(" // " + milli + "ms done!");
}
private int color(double r0, double i0, int max, boolean straight, float shift) {
int n = -1;
double r=0, i=0, r2=0, i2=0;
do {
i = r*(i+i) + i0;
r = r2-i2 + r0;
r2 = r*r;
i2 = i*i;
}
while (++n < max && r2 + i2 < 4);
return n == max
? black.getRGB()
: HSBtoRGB(shift + (float) (straight ? n : max-n) / max * 11/12f + (straight ? 0f : 1/12f), 1, 1)
;
}
}

View file

@ -0,0 +1,69 @@
function mandelIter(cx, cy, maxIter) {
var x = 0.0;
var y = 0.0;
var xx = 0;
var yy = 0;
var xy = 0;
var i = maxIter;
while (i-- && xx + yy <= 4) {
xy = x * y;
xx = x * x;
yy = y * y;
x = xx - yy + cx;
y = xy + xy + cy;
}
return maxIter - i;
}
function mandelbrot(canvas, xmin, xmax, ymin, ymax, iterations) {
var width = canvas.width;
var height = canvas.height;
var ctx = canvas.getContext('2d');
var img = ctx.getImageData(0, 0, width, height);
var pix = img.data;
for (var ix = 0; ix < width; ++ix) {
for (var iy = 0; iy < height; ++iy) {
var x = xmin + (xmax - xmin) * ix / (width - 1);
var y = ymin + (ymax - ymin) * iy / (height - 1);
var i = mandelIter(x, y, iterations);
var ppos = 4 * (width * iy + ix);
if (i > iterations) {
pix[ppos] = 0;
pix[ppos + 1] = 0;
pix[ppos + 2] = 0;
} else {
var c = 3 * Math.log(i) / Math.log(iterations - 1.0);
if (c < 1) {
pix[ppos] = 255 * c;
pix[ppos + 1] = 0;
pix[ppos + 2] = 0;
}
else if ( c < 2 ) {
pix[ppos] = 255;
pix[ppos + 1] = 255 * (c - 1);
pix[ppos + 2] = 0;
} else {
pix[ppos] = 255;
pix[ppos + 1] = 255;
pix[ppos + 2] = 255 * (c - 2);
}
}
pix[ppos + 3] = 255;
}
}
ctx.putImageData(img, 0, 0);
}
var canvas = document.createElement('canvas');
canvas.width = 900;
canvas.height = 600;
document.body.insertBefore(canvas, document.body.childNodes[0]);
mandelbrot(canvas, -2, 1, -1, 1, 1000);

View file

@ -0,0 +1,22 @@
var mandelIter;
fetch("./mandelIter.wasm")
.then(res => {
if (res.ok) return res.arrayBuffer();
throw new Error('Unable to fetch WASM.');
})
.then(bytes => { return WebAssembly.compile(bytes); })
.then(module => { return WebAssembly.instantiate(module); })
.then(instance => { WebAssembly.instance = instance; draw(); })
function mandelbrot(canvas, xmin, xmax, ymin, ymax, iterations) {
// ...
var i = WebAssembly.instance.exports.mandelIter(x, y, iterations);
// ...
}
function draw() {
// canvas initialization if necessary
// ...
mandelbrot(canvas, -2, 1, -1, 1, 1000);
// ...
}

View file

@ -0,0 +1,14 @@
# SVG STUFF
def svg(id; width; height):
"<svg width='\(width // "100%")' height='\(height // "100%") '
id='\(id)'
xmlns='http://www.w3.org/2000/svg'>";
def pixel(x;y;r;g;b;a):
"<circle cx='\(x)' cy='\(y)' r='1' fill='rgb(\(r|floor),\(g|floor),\(b|floor))' />";
# "UNTIL"
# As soon as "condition" is true, then emit . and stop:
def do_until(condition; next):
def u: if condition then . else (next|u) end;
u;

View file

@ -0,0 +1,40 @@
def Mandeliter( cx; cy; maxiter ):
# [i, x, y, x^2+y^2]
[ maxiter, 0.0, 0.0, 0.0 ]
| do_until( .[0] == 0 or .[3] > 4;
.[1] as $x | .[2] as $y
| ($x * $y) as $xy
| ($x * $x) as $xx
| ($y * $y) as $yy
| [ (.[0] - 1), # i
($xx - $yy + cx), # x
($xy + $xy + cy), # y
($xx+$yy) # xx+yy
] )
| maxiter - .[0];
# width and height should be specified as the number of pixels.
# obj == { xmin: _, xmax: _, ymin: _, ymax: _ }
def Mandelbrot( obj; width; height; iterations ):
def pixies:
range(0; width) as $ix
| (obj.xmin + ((obj.xmax - obj.xmin) * $ix / (width - 1))) as $x
| range(0; height) as $iy
| (obj.ymin + ((obj.ymax - obj.ymin) * $iy / (height - 1))) as $y
| Mandeliter( $x; $y; iterations ) as $i
| if $i == iterations then
pixel($ix; $iy; 0; 0; 0; 255)
else
(3 * ($i|log)/((iterations - 1.0)|log)) as $c # redness
| if $c < 1 then
pixel($ix;$iy; 255*$c; 0; 0; 255)
elif $c < 2 then
pixel($ix;$iy; 255; 255*($c-1); 0; 255)
else
pixel($ix;$iy; 255; 255; 255*($c-2); 255)
end
end;
svg("mandelbrot"; "100%"; "100%"),
pixies,
"</svg>";

View file

@ -0,0 +1 @@
Mandelbrot( {"xmin": -2, "xmax": 1, "ymin": -1, "ymax":1}; 900; 600; 1000 )

View file

@ -0,0 +1,14 @@
function mandelbrot(a)
z = 0
for i=1:50
z = z^2 + a
end
return z
end
for y=1.0:-0.05:-1.0
for x=-2.0:0.0315:0.5
abs(mandelbrot(complex(x, y))) < 2 ? print("*") : print(" ")
end
println()
end

Some files were not shown because too many files have changed in this diff Show more