Mandelbrot set: Difference between revisions
(917 intermediate revisions by more than 100 users not shown) | |||
Line 1: | Line 1: | ||
{{ |
{{wikipedia|Mandelbrot_set}} |
||
{{task|Fractals}} [[Category:Graphics]] [[Category:Raster graphics operations]] |
|||
[[Category:Raster graphics operations]] |
|||
;Task: |
|||
{{task|Fractals}}Generate and draw the [[wp:Mandelbrot set|Mandelbrot set]]. |
|||
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> |
|||
=={{header|11l}}== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="11l">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"))</syntaxhighlight> |
|||
=={{header|ACL2}}== |
|||
<syntaxhighlight lang="lisp">(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)))</syntaxhighlight> |
|||
{{out}} |
|||
<pre>> (draw-mandelbrot 60 100) |
|||
# |
|||
.. |
|||
.#### |
|||
. # .##. |
|||
##*###############. |
|||
#.################## |
|||
.######################. |
|||
######. ####################### |
|||
##########.###################### |
|||
############################################## |
|||
##########.###################### |
|||
######. ####################### |
|||
.######################. |
|||
#.################## |
|||
##*###############. |
|||
. # .##. |
|||
.#### |
|||
.. </pre> |
|||
=={{header|AArch64 Assembly}}== |
|||
{{trans|AWK}} |
|||
'''Compiler:''' [[GNU Compiler Collection]] (v12.2.0) |
|||
{{works with|gcc|Raspberry Pi 400, Debian GNU/Linux 12 (bookworm) 64 bits}} |
|||
[[Category:GNU Compiler Collection]] |
|||
The size of the drawn image is adjustable through <tt>xsize</tt> and <tt>ysize</tt>, and the precision through <tt>limit</tt>. |
|||
<syntaxhighlight lang="aarch64 assembly"> |
|||
#include <stdio.h> |
|||
.globl main |
|||
.section .text |
|||
.macro NEWLINE |
|||
mov x0, #10 |
|||
stp x9, x10, [sp, #-16]! |
|||
bl putchar |
|||
ldp x9, x10, [sp], 16 |
|||
.endm |
|||
.macro PRINTCHAR p |
|||
mov x1, \p |
|||
mov x0, #64 |
|||
sub x0, x0, x1 |
|||
stp x9, x10, [sp, #-16]! |
|||
bl putchar |
|||
ldp x9, x10, [sp], 16 |
|||
.endm |
|||
xsize .req x9 |
|||
xsize_w .req w9 |
|||
ysize .req x10 |
|||
ysize_w .req w10 |
|||
min_imag .req s8 |
|||
max_imag .req s9 |
|||
min_real .req s10 |
|||
max_real .req s9 |
|||
imag .req s11 |
|||
real .req s12 |
|||
step_x .req s13 |
|||
step_y .req s14 |
|||
zi .req s15 |
|||
zr .req s16 |
|||
a .req s17 |
|||
b .req s18 |
|||
ftemp_1 .req s19 |
|||
ftemp_2 .req s20 |
|||
y .req x19 |
|||
y_w .req w19 |
|||
x .req x20 |
|||
x_w .req w20 |
|||
n .req x21 |
|||
limit .req x22 |
|||
itemp_1 .req x23 |
|||
itemp_1w .req w23 |
|||
/* |
|||
redefining register names |
|||
for easier implementation |
|||
*/ |
|||
main: |
|||
stp xzr, lr, [sp, #-16]! |
|||
stp d8, d9, [sp, #-16]! |
|||
stp d10, d11,[sp, #-16]! |
|||
stp d12, d13,[sp, #-16]! |
|||
stp d14, d15,[sp, #-16]! |
|||
stp x19, x20,[sp, #-16]! |
|||
stp x21, x22,[sp, #-16]! |
|||
stp x23, x24,[sp, #-16]! |
|||
mov xsize, #108 |
|||
mov ysize, #72 |
|||
mov limit, #32 |
|||
fmov min_imag, #-1.0 |
|||
fmov max_imag, #1.0 |
|||
fmov min_real, #-2.0 |
|||
// fmov max_real #1.0 |
|||
fsub step_x, max_real, min_real |
|||
scvtf ftemp_1, xsize_w |
|||
fdiv step_x, step_x, ftemp_1 |
|||
fsub step_y, max_imag, min_imag |
|||
scvtf ftemp_1, ysize_w |
|||
fdiv step_y, step_y, ftemp_1 |
|||
mov y, #0 |
|||
1: |
|||
cmp y, ysize |
|||
b.eq 20f |
|||
scvtf ftemp_1, y_w |
|||
fmadd imag, step_y, ftemp_1, min_imag |
|||
mov x, #0 |
|||
2: |
|||
cmp x, xsize |
|||
b.eq 15f |
|||
scvtf ftemp_1, x_w |
|||
fmadd real, step_y, ftemp_1, min_real |
|||
fmov zr, real |
|||
fmov zi, imag |
|||
mov n, #0 |
|||
3: |
|||
cmp n, limit |
|||
b.eq 10f |
|||
fmul a, zr, zr |
|||
fmul b, zi, zi |
|||
fadd ftemp_1, a, b |
|||
fmov ftemp_2, #4.0 |
|||
fcmp ftemp_1, ftemp_2 |
|||
b.gt 10f |
|||
fmul zi, zi, zr |
|||
fmov ftemp_2, #2.0 |
|||
fmadd zi, zi, ftemp_2, imag |
|||
fsub zr, a, b |
|||
fadd zr, zr, real |
|||
add n, n, #1 |
|||
b 3b |
|||
10: |
|||
add x, x, #1 |
|||
PRINTCHAR n |
|||
b 2b |
|||
15: |
|||
add y, y, #1 |
|||
NEWLINE |
|||
b 1b |
|||
20: |
|||
ldp x23, x24,[sp], 16 |
|||
ldp x21, x22,[sp], 16 |
|||
ldp x19, x20,[sp], 16 |
|||
ldp d14, d15,[sp], 16 |
|||
ldp d12, d13,[sp], 16 |
|||
ldp d10, d11,[sp], 16 |
|||
ldp d8, d9, [sp], 16 |
|||
ldp xzr, lr, [sp], 16 |
|||
ret |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
@@@@@@@@@@?????????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<<;;9827873 ;<========>>>>>>>?????????????????? |
|||
@@@@@@@@@@????????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<<<;:984-047:;<<========>>>>>>>????????????????? |
|||
@@@@@@@@@???????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<;::9861479:;<<<========>>>>>>>>??????????????? |
|||
@@@@@@@@@??????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<;;:9964*469:;;<<<=======>>>>>>>>>?????????????? |
|||
@@@@@@@@??????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<<;:7871 ,489:;<<<<=======>>>>>>>>>????????????? |
|||
@@@@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<<<;;:74441 3663;<<<<<=======>>>>>>>>>???????????? |
|||
@@@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<<<;;:821.- 3 7:;<<<<<<======>>>>>>>>>??????????? |
|||
@@@@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<;;;;::970 ,+::;<<<<<<=====>>>>>>>>>>?????????? |
|||
@@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<;;;;;:::97' 379:;;<<<<<<<====>>>>>>>>>?????????? |
|||
@@@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<;;;;;;:::983+ 79::;;;;<<<<<====>>>>>>>>>????????? |
|||
@@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<;::::::::98862 3799::;;;;;;;<<===>>>>>>>>>>???????? |
|||
@@@@@???>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<<:899*8999887764' 467888::;;;::3;<===>>>>>>>>>>??????? |
|||
@@@@@???>>>>>>>>>>>>>>>>>>>>>>>>>==========<<<<;;9242 6887/'5 31/% '/24-63 79::::929;<==>>>>>>>>>>??????? |
|||
@@@@???>>>>>>>>>>>>>>>>>>>>>>>>>========<<<<<<;;::60"00465, . " 1 889887$9;<===>>>>>>>>>>?????? |
|||
@@@@??>>>>>>>>>>>>>>>>>>>>>>>>>=======<<<<<<<;;;::#2( #*30+ 4674+55(*6<<==>>>>>>>>>>>????? |
|||
@@@@??>>>>>>>>>>>>>>>>>>>>>>>======<<<<<<<<<;;;;:984+ . 4 + +39<<===>>>>>>>>>>????? |
|||
@@@??>>>>>>>>>>>>>>>>>>>>>>>=====<<<<<<<<<<;;;;::98( / 36:;<<==>>>>>>>>>>>???? |
|||
@@@??>>>>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<;;;;;:9875* '29;;<<==>>>>>>>>>>>???? |
|||
@@@?>>>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<<;;;;;:97 62. /6:;;<<===>>>>>>>>>>>??? |
|||
@@@?>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<<<;;;;;:9/#/2 058::;<<===>>>>>>>>>>>??? |
|||
@@??>>>>>>>>>>>>>>>>====<<:;;;;;;<<<<;;;;;;::98 % 369:;;<<==>>>>>>>>>>>??? |
|||
@@?>>>>>>>>>>>>>>======<<:48:;;;;;;;;;;::::::9861 899;<<===>>>>>>>>>>>?? |
|||
@@?>>>>>>>>>>>=======<<<;:929:::::9,9:::::::99742 3/74:<<===>>>>>>>>>>>?? |
|||
@@>>>>>>>>>=========<<<;;;75899:995 799:::9998- 1-9<<===>>>>>>>>>>>>? |
|||
@@>>>>>>>==========<<<<;;:8/5)67885068889998874 /:;<====>>>>>>>>>>>? |
|||
@?>>>>>==========<<<<<<;;:974$/2 652 341788877 ' 39;;<====>>>>>>>>>>>? |
|||
@?>>>>==========<<<<<<<;::9862&& 11& ,0 437765 79;<<====>>>>>>>>>>>? |
|||
@>>>>==========<<<<<<<;;::9850 ..5654 064;<<====>>>>>>>>>>>> |
|||
@>>>==========<<<<<<<<;:::8752 )442" .7;<<====>>>>>>>>>>>> |
|||
@>>==========<<<<<<<<;:::9 52* 020 -%9;<<=====>>>>>>>>>>> |
|||
@>==========<<<<<<<<;999885 /- 27:;<<=====>>>>>>>>>>> |
|||
@>==========<<<;;;;:95788762 )* 8;<<<=====>>>>>>>>>>> |
|||
@==========<;;;;;;::9726543 $ #6:;<<<=====>>>>>>>>>>> |
|||
@===<====<;;;;;;::::8730//0# 29:;<<<=====>>>>>>>>>>> |
|||
@<<<<;;;9:::;;;:::98853 8:;;<<<=====>>>>>>>>>>> |
|||
@<<;;;::77999889986562* 79:;;<<<=====>>>>>>>>>>> |
|||
7 ""! 0589:;;<<<=====>>>>>>>>>>> |
|||
@<<;;;::77999889986562* 79:;;<<<=====>>>>>>>>>>> |
|||
@<<<<;;;9:::;;;:::98853 8:;;<<<=====>>>>>>>>>>> |
|||
@===<====<;;;;;;::::8730//0# 29:;<<<=====>>>>>>>>>>> |
|||
@==========<;;;;;;::9726543 $ #6:;<<<=====>>>>>>>>>>> |
|||
@>==========<<<;;;;:95788762 )* 8;<<<=====>>>>>>>>>>> |
|||
@>==========<<<<<<<<;999885 /- 27:;<<=====>>>>>>>>>>> |
|||
@>>==========<<<<<<<<;:::9 52* 020 -%9;<<=====>>>>>>>>>>> |
|||
@>>>==========<<<<<<<<;:::8752 )442" .7;<<====>>>>>>>>>>>> |
|||
@>>>>==========<<<<<<<;;::9850 ..5654 064;<<====>>>>>>>>>>>> |
|||
@?>>>>==========<<<<<<<;::9862&& 11& ,0 437765 79;<<====>>>>>>>>>>>? |
|||
@?>>>>>==========<<<<<<;;:974$/2 652 341788877 ' 39;;<====>>>>>>>>>>>? |
|||
@@>>>>>>>==========<<<<;;:8/5)67885068889998874 /:;<====>>>>>>>>>>>? |
|||
@@>>>>>>>>>=========<<<;;;75899:995 799:::9998- 1-9<<===>>>>>>>>>>>>? |
|||
@@?>>>>>>>>>>>=======<<<;:929:::::9,9:::::::99742 3/74:<<===>>>>>>>>>>>?? |
|||
@@?>>>>>>>>>>>>>>======<<:48:;;;;;;;;;;::::::9861 899;<<===>>>>>>>>>>>?? |
|||
@@??>>>>>>>>>>>>>>>>====<<:;;;;;;<<<<;;;;;;::98 % 369:;;<<==>>>>>>>>>>>??? |
|||
@@@?>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<<<;;;;;:9/#/2 058::;<<===>>>>>>>>>>>??? |
|||
@@@?>>>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<<;;;;;:97 62. /6:;;<<===>>>>>>>>>>>??? |
|||
@@@??>>>>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<;;;;;:9875* '29;;<<==>>>>>>>>>>>???? |
|||
@@@??>>>>>>>>>>>>>>>>>>>>>>>=====<<<<<<<<<<;;;;::98( / 36:;<<==>>>>>>>>>>>???? |
|||
@@@@??>>>>>>>>>>>>>>>>>>>>>>>======<<<<<<<<<;;;;:984+ . 4 + +39<<===>>>>>>>>>>????? |
|||
@@@@??>>>>>>>>>>>>>>>>>>>>>>>>>=======<<<<<<<;;;::#2( #*30+ 4674+55(*6<<==>>>>>>>>>>>????? |
|||
@@@@???>>>>>>>>>>>>>>>>>>>>>>>>>========<<<<<<;;::60"00465, . " 1 889887$9;<===>>>>>>>>>>?????? |
|||
@@@@@???>>>>>>>>>>>>>>>>>>>>>>>>>==========<<<<;;9242 6887/'5 31/% '/24-63 79::::929;<==>>>>>>>>>>??????? |
|||
@@@@@???>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<<:899*8999887764' 467888::;;;::3;<===>>>>>>>>>>??????? |
|||
@@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<;::::::::98862 3799::;;;;;;;<<===>>>>>>>>>>???????? |
|||
@@@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<;;;;;;:::983+ 79::;;;;<<<<<====>>>>>>>>>????????? |
|||
@@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<;;;;;:::97' 379:;;<<<<<<<====>>>>>>>>>?????????? |
|||
@@@@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<;;;;::970 ,+::;<<<<<<=====>>>>>>>>>>?????????? |
|||
@@@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<<<;;:821.- 3 7:;<<<<<<======>>>>>>>>>??????????? |
|||
@@@@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<<<;;:74441 3663;<<<<<=======>>>>>>>>>???????????? |
|||
@@@@@@@@??????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<<;:7871 ,489:;<<<<=======>>>>>>>>>????????????? |
|||
@@@@@@@@@??????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<;;:9964*469:;;<<<=======>>>>>>>>>?????????????? |
|||
@@@@@@@@@???????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<;::9861479:;<<<========>>>>>>>>??????????????? |
|||
@@@@@@@@@@????????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<<<;:984-047:;<<========>>>>>>>????????????????? |
|||
</pre> |
|||
=={{header|Ada}}== |
|||
{{libheader|Lumen}} |
|||
mandelbrot.adb: |
|||
<syntaxhighlight lang="ada">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;</syntaxhighlight> |
|||
mandelbrot.ads: |
|||
<syntaxhighlight lang="ada">with Lumen.Image; |
|||
package Mandelbrot is |
|||
function Create_Image (Width, Height : Natural) return Lumen.Image.Descriptor; |
|||
end Mandelbrot;</syntaxhighlight> |
|||
test_mandelbrot.adb: |
|||
<syntaxhighlight lang="ada">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;</syntaxhighlight> |
|||
{{out}} |
|||
[[File:Ada_Mandelbrot.gif]] |
|||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
Line 9: | Line 539: | ||
Plot part of the Mandelbrot set as a pseudo-gif image. |
Plot part of the Mandelbrot set as a pseudo-gif image. |
||
< |
<syntaxhighlight lang="algol68"> |
||
INT pix = 300, max iter = 256, REAL zoom = 0.33 / pix; |
INT pix = 300, max iter = 256, REAL zoom = 0.33 / pix; |
||
[-pix : pix, -pix : pix] INT plane; |
[-pix : pix, -pix : pix] INT plane; |
||
Line 16: | Line 546: | ||
# Compute the length of an orbit. # |
# Compute the length of an orbit. # |
||
PROC iterate = (COMPL z0) INT: |
PROC iterate = (COMPL z0) INT: |
||
BEGIN COMPL z := |
BEGIN COMPL z := 0, INT iter := 1; |
||
WHILE (iter +:= 1) < max iter # not converged # AND ABS z < 2 # not diverged # |
WHILE (iter +:= 1) < max iter # not converged # AND ABS z < 2 # not diverged # |
||
DO z := z * z + z0 |
DO z := z * z + z0 |
||
Line 48: | Line 578: | ||
OD; |
OD; |
||
close (plot) |
close (plot) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|ALGOL W}}== |
|||
Generates an ASCII Mandelbrot Set. Translated from the sample program in the Compiler/AST Interpreter task. |
|||
<syntaxhighlight lang="ada">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. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 |
|||
1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 |
|||
1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 |
|||
1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 |
|||
1111111111111112222222222222333333333333333333333333333333333333222222222222222222222222222222222222222 |
|||
1111111111111222222222233333333333333333333333344444456655544443333332222222222222222222222222222222222 |
|||
1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 |
|||
11111111111222222333333333333333333333334444444445555679@@@@7654444443333333222222222222222222222222222 |
|||
1111111112222223333333333333333333333444444444455556789@@@@98755544444433333332222222222222222222222222 |
|||
1111111122223333333333333333333333344444444445556668@@@ @@@76555544444333333322222222222222222222222 |
|||
1111111222233333333333333333333344444444455566667778@@ @987666555544433333333222222222222222222222 |
|||
111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@877779@5443333333322222222222222222222 |
|||
1111112233333333333333333334444455555556679@ @@@ @@@@@@ 8544333333333222222222222222222 |
|||
1111122333333333333333334445555555556666789@@@ @86554433333333322222222222222222 |
|||
1111123333333333333444456666555556666778@@ @ @@87655443333333332222222222222222 |
|||
111123333333344444455568@887789@8777788@@@ @@@@65444333333332222222222222222 |
|||
111133334444444455555668@@@@@@@@@@@@99@@@ @@765444333333333222222222222222 |
|||
111133444444445555556778@@@ @@@@ @855444333333333222222222222222 |
|||
11124444444455555668@99@@ @ @655444433333333322222222222222 |
|||
11134555556666677789@@ @86655444433333333322222222222222 |
|||
111 @@876555444433333333322222222222222 |
|||
11134555556666677789@@ @86655444433333333322222222222222 |
|||
11124444444455555668@99@@ @ @655444433333333322222222222222 |
|||
111133444444445555556778@@@ @@@@ @855444333333333222222222222222 |
|||
111133334444444455555668@@@@@@@@@@@@99@@@ @@765444333333333222222222222222 |
|||
111123333333344444455568@887789@8777788@@@ @@@@65444333333332222222222222222 |
|||
1111123333333333333444456666555556666778@@ @ @@87655443333333332222222222222222 |
|||
1111122333333333333333334445555555556666789@@@ @86554433333333322222222222222222 |
|||
1111112233333333333333333334444455555556679@ @@@ @@@@@@ 8544333333333222222222222222222 |
|||
111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@877779@5443333333322222222222222222222 |
|||
1111111222233333333333333333333344444444455566667778@@ @987666555544433333333222222222222222222222 |
|||
1111111122223333333333333333333333344444444445556668@@@ @@@76555544444333333322222222222222222222222 |
|||
1111111112222223333333333333333333333444444444455556789@@@@98755544444433333332222222222222222222222222 |
|||
11111111111222222333333333333333333333334444444445555679@@@@7654444443333333222222222222222222222222222 |
|||
1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 |
|||
1111111111111222222222233333333333333333333333344444456655544443333332222222222222222222222222222222222 |
|||
1111111111111112222222222222333333333333333333333333333333333333222222222222222222222222222222222222222 |
|||
1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 |
|||
1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 |
|||
1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 |
|||
1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 |
|||
</pre> |
|||
[[#M4|The entry for m4]] also is based on Rosetta Code's "compiler" task suite. |
|||
=={{header|Amazing Hopper}}== |
|||
<p>El siguiente programa genera el conjunto de Mandelbrot directamente en pantalla. Ha sido adaptado desde Wikipedia.</p> |
|||
<p>Se ejecutó con:</p> |
|||
<p>rxvt -g 500x250 -fn "xft:FantasqueSansMono-Regular:pixelsize=1" -e hopper3 jm/mandel.jambo</p> |
|||
<syntaxhighlight lang="amazing hopper"> |
|||
#!/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 |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
[[File:Captura de pantalla de 2022-10-28 15-37-55.png]] |
|||
=={{header|Arturo}}== |
|||
{{trans|Nim}} |
|||
<syntaxhighlight lang="rebol">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 ]</syntaxhighlight> |
|||
{{out}} |
|||
<pre> ** |
|||
****** |
|||
******** |
|||
****** |
|||
******** ** * |
|||
*** ***************** |
|||
************************ *** |
|||
**************************** |
|||
****************************** |
|||
******************************* |
|||
************************************ |
|||
* ********************************** |
|||
** ***** * ********************************** |
|||
*********** ************************************ |
|||
************** ************************************ |
|||
*************************************************** |
|||
****************************************************** |
|||
************************************************************************ |
|||
****************************************************** |
|||
*************************************************** |
|||
************** ************************************ |
|||
*********** ************************************ |
|||
** ***** * ********************************** |
|||
* ********************************** |
|||
************************************ |
|||
******************************* |
|||
****************************** |
|||
**************************** |
|||
************************ *** |
|||
*** ***************** |
|||
******** ** * |
|||
****** |
|||
******** |
|||
****** |
|||
**</pre> |
|||
=={{header|ATS}}== |
|||
===A non-interactive program that writes a PPM image=== |
|||
{{trans|JavaScript}} |
|||
<syntaxhighlight lang="ATS"> |
|||
(* 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 |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
[[File:Mandelbrot task ATS.png|thumb||none|alt=The Mandelbrot set, displayed in colors.]] |
|||
===An interactive program that can write PAM images=== |
|||
{{trans|ObjectIcon}} |
|||
{{trans|Scheme}} |
|||
{{libheader|SDL2}} |
|||
{{libheader|ats2-xprelude}} |
|||
<syntaxhighlight lang="ats"> |
|||
(*-*- 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 |
|||
(*------------------------------------------------------------------*) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
A snapshot image of part of the set: |
|||
[[File:Mantelbrot task interactive dats sampleimage.png|thumb|none|alt=A portion of the Mandelbrot set, in shades of gray and black.]] |
|||
=={{header|AutoHotkey}}== |
|||
<syntaxhighlight lang="autohotkey">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 |
|||
}</syntaxhighlight> |
|||
=={{header|AWK}}== |
|||
<syntaxhighlight lang="awk">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; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<========== |
|||
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======= |
|||
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== |
|||
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== |
|||
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== |
|||
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== |
|||
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= |
|||
><<<<;;;;;:::972456-567763 +9;;<<<<<<< |
|||
><;;;;;;::::9875& .3 *9;;;<<<<<< |
|||
>;;;;;;::997564' ' 8:;;;<<<<<< |
|||
>::988897735/ &89:;;;<<<<<< |
|||
>::988897735/ &89:;;;<<<<<< |
|||
>;;;;;;::997564' ' 8:;;;<<<<<< |
|||
><;;;;;;::::9875& .3 *9;;;<<<<<< |
|||
><<<<;;;;;:::972456-567763 +9;;<<<<<<< |
|||
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= |
|||
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== |
|||
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== |
|||
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== |
|||
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== |
|||
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======= |
|||
</pre> |
|||
=={{header|B}}== |
|||
This implements a 16bit fixed point arithmetic Mandelbrot set calculation. |
|||
{{works with|The Amsterdam Compiler Kit - B|V6.1pre1}} |
|||
<syntaxhighlight lang="b">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); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" |
|||
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'+)%%%$$$$$#####""""""""""" |
|||
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(+,)++&%$$$$$$######"""""" |
|||
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*5:/+('&%%$$$$$$#######""" |
|||
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@,'&%%%%%$$$$######## |
|||
!!!!!!!"""####################$$$$$$$$%%%&'())((())*,@@@@@@/+))('&&&&)'%$$###### |
|||
!!!!!!""###################$$$$$%%%%%%&&&'+.@@=/<@@@@@@@@@@@@@@@/++@..93%%$##### |
|||
!!!!!"################$$$%%%%%%%%%%&&&&'),+2@@@@@@@@@@@@@@@@@@@@@@@@@1(&&%$$#### |
|||
!!!!"##########$$$$$%%&(-(''''''''''''(*,5@@@@@@@@@@@@@@@@@@@@@@@@@@@@+)-&%$$### |
|||
!!!!####$$$$$$$$%%%%%&'(*-@1.+.@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4-(&%$$$## |
|||
!!!!#$$$$$$$$$%%%%%%'''++.6@@@@@@@@@8/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3(%%$$$$# |
|||
!!!#$$$$$$$%&&&&''()/-5.5@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?'&%%$$$$# |
|||
!!!(**+/+<523/80/46@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+)'&&%%$$$$# |
|||
!!!#$$$$$$$%&&&&''().-2.@@@@@@@@@@@@@@?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$# |
|||
!!!!#$$$$$$$$$%%%%%&'''/,.7@@@@@@@@@;/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@0'%%$$$$# |
|||
!!!!####$$$$$$$$%%%%%&'(*-:2.,/?-5+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+(&%$$$## |
|||
!!!!"##########$$$$$%%&(-(''''(''''''((*,4@@@@@@@@@@@@@@@@@@@@@@@@@@@4+).&%$$### |
|||
!!!!!"################$$$%%%%%%%%%%&&&&')<,4@@@@@@@@@@@@@@@@@@@@@@@@@/('&%%$#### |
|||
!!!!!!""##################$$$$$$%%%%%%&&&'*.@@@0@@@@@@@@@@@@@@@@1,,@//9)%%$##### |
|||
!!!!!!!"""####################$$$$$$$$%%%&(())((()**-@@@@@@/+)))'&&&')'%$$###### |
|||
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''(,@@@@@@@+'&&%%%%%$$$######## |
|||
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*7@0+('&%%%$$$$$#######""" |
|||
!!!!!!!!!!!"""""""######################$$$$$$$$$%%%&&(+-).*&%$$$$$$######"""""" |
|||
!!!!!!!!!!!!!"""""""""#######################$$$$$$%%'3(%%%$$$$$######"""""""""" |
|||
!!!!!!!!!!!!!!!""""""""""""#####################################"""""""""""""""" |
|||
</pre> |
|||
=={{header|bc}}== |
|||
[[File:Mandelbrot-bc.jpg|thumb|right]] |
|||
Producing a [https://fr.wikipedia.org/wiki/Portable_pixmap PGM] image. |
|||
To work properly, this needs to run with the environment variable BC_LINE_LENGTH set to 0. |
|||
<syntaxhighlight lang=bc>max_iter = 50 |
|||
width = 400; height = 401 |
|||
scale = 10 |
|||
xmin = -2; xmax = 1/2 |
|||
ymin = -5/4; ymax = 5/4 |
|||
define mandelbrot(c_re, c_im) { |
|||
auto i |
|||
# z = 0 |
|||
z_re = 0; z_im = 0 |
|||
z2_re = 0; z2_im = 0 |
|||
for (i=0; i<max_iter; i++) { |
|||
# z *= z |
|||
z_im = 2*z_re*z_im |
|||
z_re = z2_re - z2_im |
|||
# z += c |
|||
z_re += c_re |
|||
z_im += c_im |
|||
# z2 = z.*z |
|||
z2_re = z_re*z_re |
|||
z2_im = z_im*z_im |
|||
if (z2_re + z2_im > 4) return i |
|||
} |
|||
return 0 |
|||
} |
|||
print "P2\n", width, " ", height, "\n255\n" |
|||
for (i = 0; i < height; i++) { |
|||
y = ymin + (ymax - ymin) / height * i |
|||
for (j = 0; j < width; j++) { |
|||
x = xmin + (xmax - xmin) / width * j |
|||
tmp_scale = scale |
|||
scale = 0 |
|||
m = (255 * mandelbrot(x, y) + max_iter + 1) / max_iter |
|||
print m |
|||
if ( j < width - 1 ) print " " |
|||
scale = tmp_scale |
|||
} |
|||
print "\n" |
|||
} |
|||
quit</syntaxhighlight> |
|||
=={{header|BASIC}}== |
=={{header|BASIC}}== |
||
{{works with|QBasic}} |
|||
==={{header|AmigaBASIC}}=== |
|||
{{trans|QBasic}} |
|||
[[File:Amigabasic mandelbrot.png|thumb|Output]] |
|||
<syntaxhighlight lang="qbasic">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</syntaxhighlight> |
|||
==={{header|Applesoft BASIC}}=== |
|||
This version takes into account the Apple II's funky 280×192 6-color display, which has an effective resolution of only 140×192 in color. |
|||
<syntaxhighlight lang="basic"> |
|||
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 |
|||
</syntaxhighlight> |
|||
By making the following modifications, the same code will render the Mandelbrot set in monochrome at full 280×192 resolution. |
|||
<syntaxhighlight lang="basic"> |
|||
150 FOR XS = 0 TO 279 |
|||
301 C = (C - INT(C/2)*2)*3 |
|||
310 HCOLOR = C: HPLOT XS, YS |
|||
</syntaxhighlight> |
|||
==={{header|ARM BBC BASIC}}=== |
|||
{{works with|ARM BBC BASIC V v1.0}} |
|||
The ARM development second processor for the BBC series of microcomputers came with ARM BBC Basic V. In version 1.0 this included a built-in MANDEL function that uses D% (depth) to update C% (colour) at given coordinates x and y. Presumably this was for benchmarking/demo purposes; it was removed from later versions. |
|||
This can be run in BeebEm. Select BBC model as Master 128 with ARM Second Processor. Load disc armdisc3.adl and switch to ADFS. At the prompt load ARM Basic by running the AB command. |
|||
<syntaxhighlight lang="bbcbasic"> |
|||
10MODE5:VDU5 |
|||
20D%=100 : REM adjust for speed/precision |
|||
30FORX%=0 TO 1279 STEP8 |
|||
40FORY%=0 TO 1023 STEP4 |
|||
50MANDEL (Y%-512)/256, (X%-640)/256 |
|||
51REM (not sure why X and Y need to be swapped to correct orientation) |
|||
60GCOL0,C% |
|||
70PLOT69,X%,Y% |
|||
80NEXT |
|||
90NEXT</syntaxhighlight> |
|||
[[File:Mandelbrot_armbasic.png]] |
|||
==={{header|BASIC256}}=== |
|||
<syntaxhighlight lang="basic-256">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" |
|||
</syntaxhighlight> |
|||
{{out|Image generated by the script}} |
|||
[[File:Mandelbrot BASIC-256.jpg|220px]] |
|||
==={{header|BBC BASIC}}=== |
|||
{{works with|BBC BASIC for Windows}} |
|||
<syntaxhighlight lang="bbcbasic"> 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%</syntaxhighlight> |
|||
[[File:Mandelbrot_bbc.gif]] |
|||
==={{header|Commander X16 BASIC}}=== |
|||
<syntaxhighlight lang="x16basic"> |
|||
10 CLS |
|||
20 SCREEN $80 |
|||
30 FOR X=1 TO 199: |
|||
40 FOR Y=1 TO 99: |
|||
50 LET I=0 |
|||
60 LET CX=(X-100)/50 |
|||
70 LET CY=(Y-100)/50 |
|||
80 LET VX=0 |
|||
90 LET VY=0 |
|||
100 REM START OF THE CALCULATION LOOP |
|||
110 LET I=I+1 |
|||
120 LET X2 = VX*VX |
|||
130 LET Y2 = VY*VY |
|||
140 LET VY = CY + (VX+VX)*VY |
|||
150 LET VX = CX + X2-Y2 |
|||
160 IF I<32 AND (X2+Y2)<4 THEN GOTO 100 |
|||
170 LET YR = 199-Y |
|||
180 PSET X,Y,I |
|||
190 PSET X,YR,I |
|||
200 :NEXT:NEXT |
|||
</syntaxhighlight> |
|||
==={{header|Commodore BASIC}}=== |
|||
The standard version 2.0 of BASIC that came with the VIC-20 and C-64 had no built-in support for graphics (though you could use POKE statements to put values in the VIC chip's registers and the RAM being used for video). However, Commodore sold add-on cartridges that provided such support, which was also included in later versions of BASIC (3.5 on the C-16 and Plus/4, 7.0 on the C-128). In all of these cases the programs are very slow; rendering the Mandelbrot set even with the escape threshold set to just 20 iterations takes hours. The fastest is the VIC-20, because it has only a 160x160-pixel bitmap display. |
|||
===={{header|VIC-20 with Super Expander cartridge}}==== |
|||
Runs in about 90 minutes. |
|||
<syntaxhighlight lang="basic">100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS |
|||
110 COLOR 1,3,0,0:GRAPHIC 2:TH=20 |
|||
120 FOR PY=0 TO 80 |
|||
130 : SY=INT(PY*6.4) |
|||
140 : IM=1.12-PY/160*2.24 |
|||
150 : FOR PX=0 TO 160 |
|||
160 : SX=INT(PX*6.4) |
|||
170 : RE=PX/160*2.47-2 |
|||
180 : X=0:Y=0:IT=0 |
|||
190 : XT=X*X-Y*Y+RE |
|||
200 : Y = 2*X*Y+IM |
|||
210 : X=XT |
|||
220 : IT=IT+1 |
|||
230 : IF(X*X+Y*Y<=4)AND(IT<TH) THEN 190 |
|||
240 : IF IT<TH THEN 270 |
|||
250 : DRAW 1,SX,SY TO SX,SY |
|||
260 : DRAW 1,SX,1024-SY TO SX,1024-SY |
|||
270 : NEXT PX |
|||
280 NEXT PY |
|||
290 GET K$:IF K$="" THEN 290 |
|||
300 GRAPHIC 4</syntaxhighlight> |
|||
===={{header|C-64 with Super Expander 64}}==== |
|||
Runs in about 4.5 hours. |
|||
<syntaxhighlight lang="basic">100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS |
|||
110 COLOR 6,0,0,0,6:GRAPHIC 2,1 |
|||
120 FOR PY=0 TO 100 |
|||
140 : IM=1.12-PY/200*2.24 |
|||
150 : FOR PX=0 TO 319 |
|||
170 : RE=PX/320*2.47-2 |
|||
180 : X=0:Y=0:IT=0 |
|||
190 : XT=X*X-Y*Y+RE |
|||
200 : Y = 2*X*Y+IM |
|||
210 : X=XT |
|||
220 : IT=IT+1 |
|||
230 : IF(X*X+Y*Y<=4)AND(IT<TH) THEN 190 |
|||
240 : IF IT<TH THEN 270 |
|||
250 : DRAW 1,PX,PY |
|||
260 : DRAW 1,PX,200-PY |
|||
270 : NEXT PX |
|||
280 NEXT PY |
|||
290 GET K$:IF K$="" THEN 290 |
|||
300 GRAPHIC 0</syntaxhighlight> |
|||
===={{header|Commodore-16 / 116 / Plus/4}}==== |
|||
{{works with|Commodore BASIC|3.5}} |
|||
Despite the faster clock on the TED systems compared to the C-64, this takes almost six hours to run. |
|||
<syntaxhighlight lang="basic">100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS |
|||
110 COLOR 0,2:COLOR 1,1:GRAPHIC 1,1 |
|||
120 FOR PY=0 TO 100 |
|||
130 : IM = 1.12-PY*2.24/200 |
|||
140 : FOR PX=0 TO 319 |
|||
150 : RE=PX/320*2.47-2 |
|||
160 : X=0:Y=0:IT=0 |
|||
170 : DO WHILE (X*X+Y*Y<=4) AND (IT<TH) |
|||
180 : XT = X*X-Y*Y+RE |
|||
190 : Y = 2*X*Y+IM |
|||
200 : X = XT |
|||
210 : IT = IT +1 |
|||
220 : LOOP |
|||
230 : IF IT=TH THEN DRAW 1,PX,PY:DRAW 1,PX,199-PY |
|||
240 : NEXT PX |
|||
250 NEXT PY |
|||
260 GETKEY K$ |
|||
270 GRAPHIC 0</syntaxhighlight> |
|||
===={{header|Commodore 128 (40-column display)}}==== |
|||
{{works with|Commodore BASIC|7.0}} |
|||
With the switch to FAST (2MHz) mode, this runs in about 2.5 hours, but you |
|||
get to stare at a blank screen until it's done rendering. Without that switch |
|||
it takes about 5.5 hours, splitting the difference between the Super Expander |
|||
64 and Plus/4 versions. |
|||
<syntaxhighlight lang="basic">100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS |
|||
110 COLOR 0,12:GRAPHIC 1,1:COLOR 1,1:GRAPHIC0:FAST |
|||
120 FOR PY=0 TO 100 |
|||
130 : IM = 1.12-PY*2.24/200 |
|||
140 : FOR PX=0 TO 319 |
|||
150 : RE=PX/320*2.47-2 |
|||
160 : X=0:Y=0:IT=0 |
|||
170 : DO WHILE (X*X+Y*Y<=4) AND (IT<TH) |
|||
180 : XT = X*X-Y*Y+RE |
|||
190 : Y = 2*X*Y+IM |
|||
200 : X = XT |
|||
210 : IT = IT +1 |
|||
220 : LOOP |
|||
230 : IF IT=TH THEN DRAW 1,PX,PY:DRAW 1,PX,199-PY |
|||
240 : NEXT PX |
|||
250 NEXT PY |
|||
260 SLOW:GRAPHIC 1 |
|||
270 GETKEY K$ |
|||
280 GRAPHIC 0</syntaxhighlight> |
|||
===={{header|Commodore 128 (80-column display)}}==== |
|||
{{works with|Commodore BASIC|8.0}} |
|||
This uses BASIC 8 to create a 640x200 render on the C-128's 80-column display. The doubled resolution comes with a commensurate increase in run time; this takes about 5h20m using FAST 2MHz mode. |
|||
<syntaxhighlight lang="basic">100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS |
|||
110 @MODE,0:@COLOR,15,0,0:@SCREEN,0,0:@CLEAR,0:FAST |
|||
120 FOR PY=0 TO 100 |
|||
130 : IM = 1.12-PY*2.24/200 |
|||
140 : FOR PX=0 TO 639 |
|||
150 : RE=PX/640*2.47-2 |
|||
160 : X=0:Y=0:IT=0 |
|||
170 : DO WHILE (X*X+Y*Y<=4) AND (IT<20) |
|||
180 : XT = X*X-Y*Y+RE |
|||
190 : Y = 2*X*Y+IM |
|||
200 : X = XT |
|||
210 : IT = IT +1 |
|||
220 : LOOP |
|||
230 : IF IT=20 THEN @DOT,PX,PY,0:@DOT,PX,199-PY,0 |
|||
240 : NEXT PX |
|||
250 NEXT PY |
|||
260 GETKEY K$ |
|||
270 @TEXT</syntaxhighlight> |
|||
{{Out}} |
|||
Screen shots of all of the above running in the VICE emulator can be found [https://imgur.com/a/8oqlcpy here]. |
|||
===={{header|Commodore PET}}==== |
|||
Here's a version using mostly ASCII and some PETSCII (could probably improve the tile set for PETSCII) inspired by the Perl solution. Designed for a PET with an 80-column display. |
|||
<syntaxhighlight lang="basic">100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS |
|||
110 CH$=" .:-=+*#@"+CHR$(255) |
|||
120 FOR Y=1 TO -1 STEP -0.08 |
|||
130 : FOR X = -2 TO 0.5 STEP 0.0315 |
|||
140 : GOSUB 200:IF I=20 THEN PRINT CHR$(18);" ";CHR$(146);:GOTO 160 |
|||
150 : PRINT MID$(CH$,I/2+1,1); |
|||
160 : NEXT X:IF PEEK(198) THEN PRINT |
|||
170 NEXT Y |
|||
180 GET K$:IF K$=""THEN 180 |
|||
190 END |
|||
200 CX=X:CY=Y:ZX=X:ZY=Y |
|||
210 FOR I=1 TO TH |
|||
220 : TX=ZX*ZX-ZY*ZY |
|||
230 : TY=ZX*ZY*2 |
|||
240 : ZX = TX + CX |
|||
250 : ZY = TY + CY |
|||
260 : IF ZX*ZX+ZY*ZY > 4 THEN 280 |
|||
270 NEXT I |
|||
280 IF I>TH THEN I=TH |
|||
290 RETURN</syntaxhighlight> |
|||
{{Out}} VICE screenshot [https://i.imgur.com/y4zYmyD.png here]. |
|||
==={{header|DEC BASIC-PLUS}}=== |
|||
Works under RSTS/E v7.0 on the [[wp:SIMH|simh]] PDP-11 emulator. For installation procedures for RSTS/E, see [http://www.eecis.udel.edu/~mader/delta/downloadrsts.html here]. |
|||
<syntaxhighlight lang="basic">10 X1=59\Y1=21 |
|||
20 I1=-1.0\I2=1.0\R1=-2.0\R2=1.0 |
|||
30 S1=(R2-R1)/X1\S2=(I2-I1)/Y1 |
|||
40 FOR Y=0 TO Y1 |
|||
50 I3=I1+S2*Y |
|||
60 FOR X=0 TO X1 |
|||
70 R3=R1+S1*X\Z1=R3\Z2=I3 |
|||
80 FOR N=0 TO 30 |
|||
90 A=Z1*Z1\B=Z2*Z2 |
|||
100 IF A+B>4.0 THEN GOTO 130 |
|||
110 Z2=2*Z1*Z2+I3\Z1=A-B+R3 |
|||
120 NEXT N |
|||
130 PRINT STRING$(1%,62%-N); |
|||
140 NEXT X |
|||
150 PRINT |
|||
160 NEXT Y |
|||
170 END |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<=========== |
|||
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== |
|||
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= |
|||
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== |
|||
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== |
|||
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== |
|||
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== |
|||
><<<<;;;;;:::972456-567763 +9;;<<<<<<<= |
|||
><;;;;;;::::9875& .3 *9;;;<<<<<<= |
|||
>;;;;;;::997564' ' 8:;;;<<<<<<= |
|||
>::988897735/ &89:;;;<<<<<<= |
|||
>::988897735/ &89:;;;<<<<<<= |
|||
>;;;;;;::997564' ' 8:;;;<<<<<<= |
|||
><;;;;;;::::9875& .3 *9;;;<<<<<<= |
|||
><<<<;;;;;:::972456-567763 +9;;<<<<<<<= |
|||
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== |
|||
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== |
|||
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== |
|||
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== |
|||
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= |
|||
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== |
|||
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<===========</pre> |
|||
==={{header|FreeBASIC}}=== |
|||
<syntaxhighlight lang="freebasic">#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</syntaxhighlight> |
|||
==={{header|GW-BASIC}}=== |
|||
<syntaxhighlight lang="gwbasic">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</syntaxhighlight> |
|||
==={{header|Liberty BASIC}}=== |
|||
Any words of description go outside of lang tags. |
|||
<syntaxhighlight lang="lb">nomainwin |
|||
WindowWidth =440 |
|||
WindowHeight =460 |
|||
open "Mandelbrot Set" for graphics_nsb_nf as #w |
|||
#w "trapclose [quit]" |
|||
#w "down" |
|||
for x0 = -2 to 1 step .0033 |
|||
for y0 = -1.5 to 1.5 step .0075 |
|||
x = 0 |
|||
y = 0 |
|||
iteration = 0 |
|||
maxIteration = 255 |
|||
while ( ( x *x +y *y) <=4) 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 |
|||
call pSet x0, y0, c |
|||
scan |
|||
next |
|||
next |
|||
#w "flush" |
|||
wait |
|||
sub pSet x, y, c |
|||
xScreen = 10 +( x +2) /3 *400 |
|||
yScreen = 10 +( y +1.5) /3 *400 |
|||
if c =0 then |
|||
col$ ="red" |
|||
else |
|||
if c mod 2 =1 then col$ ="lightgray" else col$ ="white" |
|||
end if |
|||
#w "color "; col$ |
|||
#w "set "; xScreen; " "; yScreen |
|||
end sub |
|||
[quit] |
|||
close #w |
|||
end |
|||
</syntaxhighlight> |
|||
==={{header|Locomotive Basic}}=== |
|||
{{trans|QBasic}} |
|||
[[File:Cpcbasic mandelbrot.png|thumb|CPCBasic output]] |
|||
This program is meant for use in [https://benchmarko.github.io/CPCBasic/cpcbasic.html CPCBasic] specifically, where it draws a 16-color 640x400 image in less than a minute. (Real CPC hardware would take far longer than that and has lower resolution.) |
|||
<syntaxhighlight lang="basic">1 MODE 3 ' Note the CPCBasic-only screen mode! |
|||
2 FOR xp = 0 TO 639 |
|||
3 FOR yp = 0 TO 399 |
|||
4 x = 0 : y = 0 |
|||
5 x0 = xp / 213 - 2 : y0 = yp / 200 - 1 |
|||
6 iteration = 0 |
|||
7 maxIteration = 100 |
|||
8 WHILE (x * x + y * y <= (2 * 2) AND iteration < maxIteration) |
|||
9 xtemp = x * x - y * y + x0 |
|||
10 y = 2 * x * y + y0 |
|||
11 x = xtemp |
|||
12 iteration = iteration + 1 |
|||
13 WEND |
|||
14 IF iteration <> maxIteration THEN c = iteration ELSE c = 0 |
|||
15 PLOT xp, yp, c MOD 16 |
|||
16 NEXT |
|||
17 NEXT</syntaxhighlight> |
|||
==={{header|Microsoft Small Basic}}=== |
|||
<syntaxhighlight lang="small basic"> |
|||
GraphicsWindow.Show() |
|||
size = 500 |
|||
half = 250 |
|||
GraphicsWindow.Width = size * 1.5 |
|||
GraphicsWindow.Height = size |
|||
GraphicsWindow.Title = "Mandelbrot" |
|||
For px = 1 To size * 1.5 |
|||
x_0 = px/half - 2 |
|||
For py = 1 To size |
|||
y_0 = py/half - 1 |
|||
x = x_0 |
|||
y = y_0 |
|||
i = 0 |
|||
While(c <= 2 AND i<100) |
|||
x_1 = Math.Power(x, 2) - Math.Power(y, 2) + x_0 |
|||
y_1 = 2 * x * y + y_0 |
|||
c = Math.Power(Math.Power(x_1, 2) + Math.Power(y_1, 2), 0.5) |
|||
x = x_1 |
|||
y = y_1 |
|||
i = i + 1 |
|||
EndWhile |
|||
If i < 99 Then |
|||
GraphicsWindow.SetPixel(px, py, GraphicsWindow.GetColorFromRGB((255/25)*i, (255/25)*i, (255/5)*i)) |
|||
Else |
|||
GraphicsWindow.SetPixel(px, py, "black") |
|||
EndIf |
|||
c=0 |
|||
EndFor |
|||
EndFor |
|||
</syntaxhighlight> |
|||
==={{header|Microsoft Super Extended Color BASIC (Tandy Color Computer 3)}}=== |
|||
<syntaxhighlight lang="coco3basic"> |
|||
1 REM MANDELBROT SET - TANDY COCO 3 |
|||
2 POKE 65497,1 |
|||
10 HSCREEN 2 |
|||
20 HCLS |
|||
30 X1=319:Y1=191 |
|||
40 I1=-1.0:I2=1.0:R1=-2:R2=1.0 |
|||
50 S1=(R2-R1)/X1:S2=(I2-I1)/Y1 |
|||
60 FOR Y=0 TO Y1 |
|||
70 I3=I1+S2*Y |
|||
80 FOR X=0 TO X1 |
|||
90 R3=R1+S1*X:Z1=R3:Z2=I3 |
|||
100 FOR N=0 TO 30 |
|||
110 A=Z1*Z1:B=Z2*Z2 |
|||
120 IF A+B>4.0 GOTO 150 |
|||
130 Z2=2*Z1*Z2+I3:Z1=A-B+R3 |
|||
140 NEXT N |
|||
150 HSET(X,Y,N-16*INT(N/16)) |
|||
160 NEXT X |
|||
170 NEXT Y |
|||
180 GOTO 180 |
|||
</syntaxhighlight> |
|||
==={{header|MSX Basic}}=== |
|||
{{works with|MSX BASIC|any}} |
|||
{{trans|Microsoft Super Extended Color BASIC}} |
|||
<syntaxhighlight lang="qbasic">100 SCREEN 2 |
|||
110 CLS |
|||
120 x1 = 256 : y1 = 192 |
|||
130 i1 = -1 : i2 = 1 |
|||
140 r1 = -2 : r2 = 1 |
|||
150 s1 = (r2-r1)/x1 : s2 = (i2-i1)/y1 |
|||
160 FOR y = 0 TO y1 |
|||
170 i3 = i1+s2*y |
|||
180 FOR x = 0 TO x1 |
|||
190 r3 = r1+s1*x |
|||
200 z1 = r3 : z2 = i3 |
|||
210 FOR n = 0 TO 30 |
|||
220 a = z1*z1 : b = z2*z2 |
|||
230 IF a+b > 4 GOTO 270 |
|||
240 z2 = 2*z1*z2+i3 |
|||
250 z1 = a-b+r3 |
|||
260 NEXT n |
|||
270 PSET (x,y),n-16*INT(n/16) |
|||
280 NEXT x |
|||
290 NEXT y |
|||
300 GOTO 300</syntaxhighlight> |
|||
{{out}} |
|||
[[File:Mandelbrot-MS-BASIC.png]] |
|||
==={{header|Nascom BASIC}}=== |
|||
{{trans|Sinclair ZX81 BASIC}} |
|||
In fact, it is based on the ZX81 version, but some optimizations are done to shorten the execution time (though they lengthen the code): |
|||
* The variables <code>X2</code> and <code>Y2</code> for <code>XA*XA</code> and <code>YA*YA</code> respectively are introduced in order to calculate the squares only once. |
|||
* The value of <code>X</code> does not depend on <code>J</code>, so it is calculated before the <code>FOR J</code> loop. |
|||
* The symmetry of the shape is taken into account in order to calculate symmetric values only once. It is the most significant optimization. The case <code>X=0</code> (corresponding to the line 22 on the screen grid) is treated separately. |
|||
Only a fragment of the shape is drawn because of low resolution of block graphics. Like in the ZX81 version, you can adjust the constants in lines 40 and 70 to zoom in on a particular area, if you like. |
|||
{{works with|Nascom ROM BASIC|4.7}} |
|||
<syntaxhighlight lang="basic"> |
|||
10 REM Mandelbrot set |
|||
20 CLS |
|||
30 FOR I=0 TO 95 |
|||
40 LET X=(I-78)/48 |
|||
50 REM ** When X<>0 |
|||
60 FOR J=1 TO 22 |
|||
70 LET Y=(22-J)/30 |
|||
80 LET XA=0:X2=0 |
|||
90 LET YA=0:Y2=0 |
|||
100 LET ITER=0 |
|||
110 LET XTEMP=X2-Y2+X |
|||
120 LET YA=2*XA*YA+Y:Y2=YA*YA |
|||
130 LET XA=XTEMP:X2=XA*XA |
|||
140 LET ITER=ITER+1 |
|||
150 IF X2+Y2<=4 AND ITER<200 THEN 110 |
|||
160 IF ITER=200 THEN SET(I,J):SET(I,44-J) |
|||
170 NEXT J |
|||
180 REM ** When X=0 |
|||
190 LET XA=0:X2=0 |
|||
200 LET ITER=0 |
|||
210 LET XA=X2+X:X2=XA*XA |
|||
220 LET ITER=ITER+1 |
|||
230 IF X2<=4 AND ITER<200 THEN 210 |
|||
240 IF ITER=200 THEN SET(I,22) |
|||
250 NEXT I |
|||
290 REM ** Set up machine code INKEY$ command |
|||
300 IF PEEK(1)<>0 THEN RESTORE 510 |
|||
310 DOKE 4100,3328:FOR A=3328 TO 3342 STEP 2 |
|||
320 READ B:DOKE A,B:NEXT A |
|||
400 SCREEN 1,15 |
|||
410 PRINT "Hit any key to exit."; |
|||
420 A=USR(0):IF A<0 THEN 420 |
|||
430 CLS |
|||
440 END |
|||
490 REM ** Data for machine code INKEY$ |
|||
500 DATA 25055,1080,-53,536,-20665,3370,-5664,0 |
|||
510 DATA 27085,14336,-13564,6399,18178,10927 |
|||
520 DATA -8179,233 |
|||
</syntaxhighlight> |
|||
==={{header|OS/8 BASIC}}=== |
|||
Works under BASIC on a PDP-8 running OS/8. Various emulators exist including simh's PDP-8 emulator and the [http://www.bernhard-baehr.de/pdp8e/pdp8e.html PDP-8/E Simulator] for Classic Macintosh and OS X. |
|||
<syntaxhighlight lang="qbasic">10 X1=59\Y1=21 |
|||
20 I1=-1.0\I2=1.0\R1=-2.0\R2=1.0 |
|||
30 S1=(R2-R1)/X1\S2=(I2-I1)/Y1 |
|||
40 FOR Y=0 TO Y1 |
|||
50 I3=I1+S2*Y |
|||
60 FOR X=0 TO X1 |
|||
70 R3=R1+S1*X\Z1=R3\Z2=I3 |
|||
80 FOR N=0 TO 30 |
|||
90 A=Z1*Z1\B=Z2*Z2 |
|||
100 IF A+B>4.0 GOTO 130 |
|||
110 Z2=2*Z1*Z2+I3\Z1=A-B+R3 |
|||
120 NEXT N |
|||
130 PRINT CHR$(62-N); |
|||
140 NEXT X |
|||
150 PRINT |
|||
160 NEXT Y |
|||
170 END</syntaxhighlight> |
|||
{{out}} |
|||
<pre>>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<=========== |
|||
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== |
|||
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= |
|||
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== |
|||
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== |
|||
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== |
|||
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== |
|||
><<<<;;;;;:::972456-567763 +9;;<<<<<<<= |
|||
><;;;;;;::::9875& .3 *9;;;<<<<<<= |
|||
>;;;;;;::997564' ' 8:;;;<<<<<<= |
|||
>::988897735/ &89:;;;<<<<<<= |
|||
>::988897735/ &89:;;;<<<<<<= |
|||
>;;;;;;::997564' ' 8:;;;<<<<<<= |
|||
><;;;;;;::::9875& .3 *9;;;<<<<<<= |
|||
><<<<;;;;;:::972456-567763 +9;;<<<<<<<= |
|||
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== |
|||
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== |
|||
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== |
|||
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== |
|||
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= |
|||
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== |
|||
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<===========</pre> |
|||
==={{header|PureBasic}}=== |
|||
PureBasic forum: [http://www.purebasic.fr/german/viewtopic.php?f=4&t=22107 discussion] |
|||
<syntaxhighlight lang="purebasic">EnableExplicit |
|||
#Window1 = 0 |
|||
#Image1 = 0 |
|||
#ImgGadget = 0 |
|||
#max_iteration = 64 |
|||
#width = 800 |
|||
#height = 600 |
|||
Define.d x0 ,y0 ,xtemp ,cr, ci |
|||
Define.i i, n, x, y ,Event ,color |
|||
Dim Color.l (255) |
|||
For n = 0 To 63 |
|||
Color( 0 + n ) = RGB( n*4+128, 4 * n, 0 ) |
|||
Color( 64 + n ) = RGB( 64, 255, 4 * n ) |
|||
Color( 128 + n ) = RGB( 64, 255 - 4 * n , 255 ) |
|||
Color( 192 + n ) = RGB( 64, 0, 255 - 4 * n ) |
|||
Next |
|||
If OpenWindow(#Window1, 0, 0, #width, #height, "'Mandelbrot set' PureBasic Example", #PB_Window_SystemMenu ) |
|||
If CreateImage(#Image1, #width, #height) |
|||
ImageGadget(#ImgGadget, 0, 0, #width, #height, ImageID(#Image1)) |
|||
For y.i = 1 To #height -1 |
|||
StartDrawing(ImageOutput(#Image1)) |
|||
For x.i = 1 To #width -1 |
|||
x0 = 0 |
|||
y0 = 0; |
|||
cr = (x / #width)*2.5 -2 |
|||
ci = (y / #height)*2.5 -1.25 |
|||
i = 0 |
|||
While (x0*x0 + y0*y0 <= 4.0) And i < #max_iteration |
|||
i +1 |
|||
xtemp = x0*x0 - y0*y0 + cr |
|||
y0 = 2*x0*y0 + ci |
|||
x0 = xtemp |
|||
Wend |
|||
If i >= #max_iteration |
|||
Plot(x, y, 0 ) |
|||
Else |
|||
Plot(x, y, Color(i & 255)) |
|||
EndIf |
|||
Next |
|||
StopDrawing() |
|||
SetGadgetState(#ImgGadget, ImageID(#Image1)) |
|||
Repeat |
|||
Event = WindowEvent() |
|||
If Event = #PB_Event_CloseWindow |
|||
End |
|||
EndIf |
|||
Until Event = 0 |
|||
Next |
|||
EndIf |
|||
Repeat |
|||
Event = WaitWindowEvent() |
|||
Until Event = #PB_Event_CloseWindow |
|||
EndIf</syntaxhighlight>Example:<br> |
|||
[[File:Mandelbrot-PureBasic.png]] |
|||
==={{header|QBasic}}=== |
|||
This is almost exactly the same as the pseudocode from [[wp:Mandelbrot set#For_programmers|the Wikipedia entry's "For programmers" section]] (which it's closely based on, of course). The image generated is very blocky ("low-res") due to the selected video mode, but it's fairly accurate. |
This is almost exactly the same as the pseudocode from [[wp:Mandelbrot set#For_programmers|the Wikipedia entry's "For programmers" section]] (which it's closely based on, of course). The image generated is very blocky ("low-res") due to the selected video mode, but it's fairly accurate. |
||
< |
<syntaxhighlight lang="qbasic">SCREEN 13 |
||
WINDOW (-2, 1.5)-(2, -1.5) |
WINDOW (-2, 1.5)-(2, -1.5) |
||
FOR x0 = -2 TO 2 STEP .01 |
FOR x0 = -2 TO 2 STEP .01 |
||
Line 82: | Line 2,977: | ||
PSET (x0, y0), c + 32 |
PSET (x0, y0), c + 32 |
||
NEXT |
NEXT |
||
NEXT</ |
NEXT</syntaxhighlight> |
||
==={{header|Quite BASIC}}=== |
|||
<syntaxhighlight lang="quite basic"> |
|||
1000 REM Mandelbrot Set Project |
|||
1010 REM Quite BASIC Math Project |
|||
1015 REM 'http://www.quitebasic.com/prj/math/mandelbrot/ |
|||
1020 REM ------------------------ |
|||
1030 CLS |
|||
1040 PRINT "This program plots a graphical representation of the famous Mandelbrot set. It takes a while to finish so have patience and don't have too high expectations; the graphics resolution is not very high on our canvas." |
|||
2000 REM Initialize the color palette |
|||
2010 GOSUB 3000 |
|||
2020 REM L is the maximum iterations to try |
|||
2030 LET L = 100 |
|||
2040 FOR I = 0 TO 100 |
|||
2050 FOR J = 0 TO 100 |
|||
2060 REM Map from pixel coordinates (I,J) to math (U,V) |
|||
2060 LET U = I / 50 - 1.5 |
|||
2070 LET V = J / 50 - 1 |
|||
2080 LET X = U |
|||
2090 LET Y = V |
|||
2100 LET N = 0 |
|||
2110 REM Inner iteration loop starts here |
|||
2120 LET R = X * X |
|||
2130 LET Q = Y * Y |
|||
2140 IF R + Q > 4 OR N >= L THEN GOTO 2190 |
|||
2150 LET Y = 2 * X * Y + V |
|||
2160 LET X = R - Q + U |
|||
2170 LET N = N + 1 |
|||
2180 GOTO 2120 |
|||
2190 REM Compute the color to plot |
|||
2200 IF N < 10 THEN LET C = "black" ELSE LET C = P[ROUND(8 * (N-10) / (L-10))] |
|||
2210 PLOT I, J, C |
|||
2220 NEXT J |
|||
2230 NEXT I |
|||
2240 END |
|||
3000 REM Subroutine -- Set up Palette |
|||
3010 ARRAY P |
|||
3020 LET P[0] = "black" |
|||
3030 LET P[1] = "magenta" |
|||
3040 LET P[2] = "blue" |
|||
3050 LET P[3] = "green" |
|||
3060 LET P[4] = "cyan" |
|||
3070 LET P[5] = "red" |
|||
3080 LET P[6] = "orange" |
|||
3090 LET P[7] = "yellow" |
|||
3090 LET P[8] = "white" |
|||
3100 RETURN |
|||
</syntaxhighlight> |
|||
==={{header|Run BASIC}}=== |
|||
<syntaxhighlight lang="runbasic">'Mandelbrot V4 for RunBasic |
|||
'Based on LibertyBasic solution |
|||
'copy the code and go to runbasic.com |
|||
'http://rosettacode.org/wiki/Mandelbrot_set#Liberty_BASIC |
|||
'May 2015 (updated 29 Apr 2018) |
|||
' |
|||
'Note - we only get so much processing time on the server, so the |
|||
'graph is computed in three or four pieces |
|||
' |
|||
WindowWidth = 320 'RunBasic max size 800 x 600 |
|||
WindowHeight = 320 |
|||
'print zone -2 to 1 (X) |
|||
'print zone -1.5 to 1.5 (Y) |
|||
a = -1.5 'graph -1.5 to -0.75, first "loop" |
|||
b = -0.75 'adjust for max processor time (y0 for loop below) |
|||
'open "Mandelbrot Set" for graphics_nsb_nf as #w not used in RunBasic |
|||
graphic #w, WindowWidth, WindowHeight |
|||
'#w "trapclose [quit]" not used in RunBasic |
|||
'#w "down" not used in RunBasic |
|||
cls |
|||
'#w flush() |
|||
#w cls("black") |
|||
render #w |
|||
'#w flush() |
|||
input "OK, hit enter to continue"; guess |
|||
cls |
|||
[man_calc] |
|||
'3/screen size 3/800 = 0.00375 ** 3/790 = 0.0037974 |
|||
'3/screen size (y) 3/600 = .005 ** 3/590 = 0.0050847 |
|||
'3/215 = .0139 .0068 = 3/440 |
|||
cc = 3/299 |
|||
' |
|||
for x0 = -2 to 1 step cc |
|||
for y0 = a to b step cc |
|||
x = 0 |
|||
y = 0 |
|||
iteration = 0 |
|||
maxIteration = 255 |
|||
while ( ( x *x +y *y) <=4) 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 |
|||
call pSet x0, y0, c |
|||
'scan why scan? (wait for user input) with RunBasic ? |
|||
next |
|||
next |
|||
'#w flush() 'what is flush? RunBasic uses the render command. |
|||
render #w |
|||
input "OK, hit enter to continue"; guess |
|||
cls |
|||
a = a + 0.75 |
|||
b = b + 0.75 |
|||
if b > 1.6 then goto[quit] else goto[man_calc] |
|||
sub pSet x, y, c |
|||
xScreen = 5+(x +2) /3 * 300 'need positive screen number |
|||
yScreen = 5+(y +1.5) /3 * 300 'and 5x5 boarder |
|||
if c =0 then |
|||
col$ ="red" |
|||
else |
|||
if c mod 2 =1 then col$ ="lightgray" else col$ ="white" |
|||
end if |
|||
#w "color "; col$ |
|||
#w "set "; xScreen; " "; yScreen |
|||
end sub |
|||
[quit] |
|||
'cls |
|||
print |
|||
print "This is a Mandelbrot Graph output from www.runbasic.com" |
|||
render #w |
|||
print "All done, good bye." |
|||
end |
|||
</syntaxhighlight> |
|||
==={{header|Sinclair ZX81 BASIC}}=== |
|||
{{trans|QBasic}} |
|||
Requires at least 2k of RAM. |
|||
Glacially slow, but does eventually produce a tolerable low-resolution image (screenshot [http://edmundgriffiths.com/zxmandelbrot.jpg here]). You can adjust the constants in lines 30 and 40 to zoom in on a particular area, if you like. |
|||
<syntaxhighlight lang="zxbasic"> 10 FOR I=0 TO 63 |
|||
20 FOR J=43 TO 0 STEP -1 |
|||
30 LET X=(I-52)/31 |
|||
40 LET Y=(J-22)/31 |
|||
50 LET XA=0 |
|||
60 LET YA=0 |
|||
70 LET ITER=0 |
|||
80 LET XTEMP=XA*XA-YA*YA+X |
|||
90 LET YA=2*XA*YA+Y |
|||
100 LET XA=XTEMP |
|||
110 LET ITER=ITER+1 |
|||
120 IF XA*XA+YA*YA<=4 AND ITER<200 THEN GOTO 80 |
|||
130 IF ITER=200 THEN PLOT I, J |
|||
140 NEXT J |
|||
150 NEXT I</syntaxhighlight> |
|||
==={{Header|SmileBASIC}}=== |
|||
Generates the points at random, gradually building up the image. |
|||
<syntaxhighlight lang="smilebasic">X = RNDF()*4-2 |
|||
Y = RNDF()*4-2@N |
|||
N = N+16 |
|||
I = X+S*S-T*T |
|||
T = Y+S*T*2 |
|||
S = I |
|||
IF N < #L&&S*S+T*T < 4 GOTO @N |
|||
GPSET X*50+99, Y*50+99, RGB(99 XOR N,N,N) |
|||
EXEC.</syntaxhighlight> |
|||
Alternative, based on the QBasic and other BASIC samples. |
|||
<br> |
|||
The 3DS screen is 400 x 240 pixels. SmileBASIC doesn't have +=, -=, etc. but there are INC and DEC statements. |
|||
<syntaxhighlight lang="basic">OPTION STRICT |
|||
VAR XP, YP, X, Y, X0, Y0, X2, Y2 |
|||
VAR NEXT_X, IT, C |
|||
FOR XP = -200 TO 199 |
|||
FOR YP = -120 TO 119 |
|||
X = 0: Y = 0 |
|||
X0 = XP / 100: Y0 = YP / 100 |
|||
IT = 0 |
|||
X2 = X * X: Y2 = Y * Y |
|||
WHILE X2 + Y2 <= 4 AND IT < 100 |
|||
NEXT_X = X2 - Y2 + X0 |
|||
Y = 2 * X * Y + Y0 |
|||
X = NEXT_X |
|||
X2 = X * X: Y2 = Y * Y |
|||
INC IT |
|||
WEND |
|||
IF IT == 100 THEN C = 0 ELSE C = IT |
|||
GPSET XP + 200, YP + 120, RGB((C * 3) MOD 200 + 50, FLOOR(C * 1.2) + 20, C) |
|||
NEXT |
|||
NEXT</syntaxhighlight> |
|||
==={{header|TI-Basic Color}}=== |
|||
{{works with|TI-84 Plus CSE, TI-83 Premium CE, TI-84 Plus CE}} |
|||
<syntaxhighlight lang="ti-basic"> |
|||
ClrDraw |
|||
~2->Xmin:1->Xmax:~1->Ymin:1->Ymax |
|||
AxesOff |
|||
FnOff |
|||
For(A,~2,1,.034 |
|||
For(B,~1,1,.036 |
|||
A+B[i]->C |
|||
DelVar Z9->N |
|||
While abs(Z)<=2 and N<24 |
|||
Z^^2+C->Z |
|||
N+1->N |
|||
End |
|||
Pt-On(real(C),imag(C),N |
|||
End |
|||
End</syntaxhighlight> |
|||
==={{header|True BASIC}}=== |
|||
{{trans|Microsoft Super Extended Color BASIC}} |
|||
<syntaxhighlight lang="qbasic">SET WINDOW 0, 256, 0, 192 |
|||
LET x1 = 256/2 |
|||
LET y1 = 192/2 |
|||
LET i1 = -1 |
|||
LET i2 = 1 |
|||
LET r1 = -2 |
|||
LET r2 = 1 |
|||
LET s1 = (r2-r1) / x1 |
|||
LET s2 = (i2-i1) / y1 |
|||
FOR y = 0 TO y1 STEP .05 |
|||
LET i3 = i1 + s2 * y |
|||
FOR x = 0 TO x1 STEP .05 |
|||
LET r3 = r1 + s1 * x |
|||
LET z1 = r3 |
|||
LET z2 = i3 |
|||
FOR n = 0 TO 30 |
|||
LET a = z1 * z1 |
|||
LET b = z2 * z2 |
|||
IF a+b > 4 THEN EXIT FOR |
|||
LET z2 = 2 * z1 * z2 + i3 |
|||
LET z1 = a - b + r3 |
|||
NEXT n |
|||
SET COLOR n - 16*INT(n/16) |
|||
PLOT POINTS: x,y |
|||
NEXT x |
|||
NEXT y |
|||
END</syntaxhighlight> |
|||
==={{header|Visual BASIC for Applications on Excel}}=== |
|||
{{works with|Excel 2013}} |
|||
Based on the BBC BASIC version. Create a spreadsheet with -2 to 2 in row 1 and -2 to 2 in the A column (in steps of your choosing). In the cell B2, call the function with =mandel(B$1,$A2) and copy the cell to all others in the range. Conditionally format the cells to make the colours pleasing (eg based on values, 3-color scale, min value 2 [colour red], midpoint number 10 [green] and highest value black. Then format the cells with the custom type "";"";"" to remove the numbers. |
|||
<syntaxhighlight lang="vba">Function mandel(xi As Double, yi As Double) |
|||
maxiter = 256 |
|||
x = 0 |
|||
y = 0 |
|||
For i = 1 To maxiter |
|||
If ((x * x) + (y * y)) > 4 Then Exit For |
|||
xt = xi + ((x * x) - (y * y)) |
|||
y = yi + (2 * x * y) |
|||
x = xt |
|||
Next |
|||
mandel = i |
|||
End Function</syntaxhighlight> |
|||
[[File:vbamandel.png]] |
|||
Edit: I don't seem to be able to upload the screenshot, so I've shared it here: https://goo.gl/photos/LkezpuQziJPAtdnd9 |
|||
==={{header|Yabasic}}=== |
|||
<syntaxhighlight lang="yabasic">open window 640, 320 |
|||
wid = 4 |
|||
xcenter = -1: ycenter = 0 |
|||
ms = 0 |
|||
for xcoord = 0 to 639 |
|||
for ycoord = 0 to 160 |
|||
ms = 0 |
|||
ca =(xcoord-320)/640*wid+xcenter |
|||
cb =(ycoord-160)/640*wid+ycenter |
|||
x = 0: y=0 |
|||
for t = 1 to 20 |
|||
xnew = x*x-y*y+ca |
|||
ynew = 2*x*y+cb |
|||
x=xnew:y=ynew |
|||
magnitudesquared=x*x+y*y |
|||
ms = magnitudesquared |
|||
if (magnitudesquared > 100) break |
|||
//if(magnitudesquared < 100) then : color 0,0,0 : dot xcoord, ycoord : end if |
|||
next t |
|||
ms = ms+1 |
|||
if(ms > 250) then |
|||
color 32,64,mod(ms,255) |
|||
dot xcoord, ycoord |
|||
dot xcoord, 320- ycoord |
|||
elseif (ms > 150) then |
|||
color mod(ms,255),64,32 |
|||
dot xcoord, ycoord |
|||
dot xcoord, 320-ycoord |
|||
else |
|||
color 0,0,0 |
|||
dot xcoord, ycoord |
|||
dot xcoord, 320-ycoord |
|||
end if |
|||
next ycoord |
|||
next xcoord |
|||
</syntaxhighlight> |
|||
=={{header|Befunge}}== |
|||
Using 14-bit fixed point arithmetic for simplicity and portability. It should work in most interpreters, but the exact output is implementation dependent, and some will be unbearably slow. |
|||
X scale is (-2.0, 0.5); Y scale is (-1, 1); Max iterations 94 with the ASCII character set as the "palette". |
|||
<syntaxhighlight lang="befunge">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<^ |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>}}}}}}}}}|||||||{{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzyyyyxwusjuthwyzzzzzzz{{{{{{{ |
|||
}}}}}}}}|||||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzyyyyxwwvtqptvwxyyzzzzzzz{{{{{ |
|||
}}}}}}}||||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyyxwvuqaZlnvwxyyyzzzzzzz{{{{ |
|||
}}}}}}|||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyyxxvqXp^g Ynslvxyyyyyzzzzz{{{ |
|||
}}}}}}||||{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyxxxxwvtp 6puwxyyyyyyzzzz{{ |
|||
}}}}}||||{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzyyyxxxxxwwvvqc &8uvwxxxyyyyyzzz{ |
|||
}}}}|||{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzyyyywwvtvvvvuutsp Hrtuuvwxxxxwqxyzz |
|||
}}}}||{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzyyyyyxwvqemrttj m id+ PRUiPp_rvvvvudwxyz |
|||
}}}||{{{{{{{{{{{{{{{{{{{{{zzzzzzyyyyyyyxxxwurf ZnW 4nrslnobgwyy |
|||
}}}||{{{{{{{{{{{{{{{{{{{zzzzyyyyyyyyyyxxxwvusg N Uquxyy |
|||
}}||{{{{{{{{{{{{{{{{{zzzzyyyyyyyyyyyxxxxwvrrrkC grwxxy |
|||
}}|{{{{{{{{{{{{{{{zzzzyxxxxxyyyyyxxxxxwwukM!f ptvwxy |
|||
}}|{{{{{{{{{{zzzzzzyyxwsuwwwwwwwwwwwwwvvurn[ ptuox |
|||
}|{{{{{{{zzzzzzzzyyyxxvptuuvvumsuvvvvvvu` hjx |
|||
}|{{{{zzzzzzzzzyyyyyxxwusogoqsqg]pptuuttlc ntwx |
|||
}{{{zzzzzzzzzyyyyyyxxwwuto - O jpssrO nsvx |
|||
}{{zzzzzzzzzyyyyyyxwwwvrrT4 TonR Ufwy |
|||
}{zzzzzzzzyyyyyxxwttuutqe Dj $uxy |
|||
}zzzzzzzzyxxxxxwwvuppnpn ` twxy |
|||
}yyyxxwvwwwxwvvvrtppc Y auwxxy |
|||
dqtvwxyy |
|||
}yyyxxwvwwwxwvvvrtppc Y auwxxy |
|||
}zzzzzzzzyxxxxxwwvuppnpn ` twxy |
|||
}{zzzzzzzzyyyyyxxwttuutqe Dj $uxy |
|||
}{{zzzzzzzzzyyyyyyxwwwvrrT4 TonR Ufwy |
|||
}{{{zzzzzzzzzyyyyyyxxwwuto - O jpssrO nsvx |
|||
}|{{{{zzzzzzzzzyyyyyxxwusogoqsqg]pptuuttlc ntwx |
|||
}|{{{{{{{zzzzzzzzyyyxxvptuuvvumsuvvvvvvu` hjx |
|||
}}|{{{{{{{{{{zzzzzzyyxwsuwwwwwwwwwwwwwvvurn[ ptuox |
|||
}}|{{{{{{{{{{{{{{{zzzzyxxxxxyyyyyxxxxxwwukM!f ptvwxy |
|||
}}||{{{{{{{{{{{{{{{{{zzzzyyyyyyyyyyyxxxxwvrrrkC grwxxy |
|||
}}}||{{{{{{{{{{{{{{{{{{{zzzzyyyyyyyyyyxxxwvusg N Uquxyy |
|||
}}}||{{{{{{{{{{{{{{{{{{{{{zzzzzzyyyyyyyxxxwurf ZnW 4nrslnobgwyy |
|||
}}}}||{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzyyyyyxwvqemrttj m id+ PRUiPp_rvvvvudwxyz |
|||
}}}}|||{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzyyyywwvtvvvvuutsp Hrtuuvwxxxxwqxyzz |
|||
}}}}}||||{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzyyyxxxxxwwvvqc &8uvwxxxyyyyyzzz{ |
|||
}}}}}}||||{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyxxxxwvtp 6puwxyyyyyyzzzz{{ |
|||
}}}}}}|||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyyxxvqXp^g Ynslvxyyyyyzzzzz{{{ |
|||
}}}}}}}||||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyyxwvuqaZlnvwxyyyzzzzzzz{{{{ |
|||
}}}}}}}}|||||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzyyyyxwwvtqptvwxyyzzzzzzz{{{{{ |
|||
}}}}}}}}}|||||||{{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzyyyyxwusjuthwyzzzzzzz{{{{{{{</pre> |
|||
=={{header|Brace}}== |
|||
This is a simple Mandelbrot plotter. A longer version based on this smooths colors, and avoids calculating the time-consuming black pixels: http://sam.ai.ki/brace/examples/mandelbrot.d/1 |
|||
<syntaxhighlight lang="brace">#!/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</syntaxhighlight> |
|||
An example plot from the longer version: |
|||
[[File:brace-mandelbrot-small.png]] |
|||
=={{header|Brainf***}}== |
|||
<syntaxhighlight lang="brainf***"> |
|||
A mandelbrot set fractal viewer in brainf*ck written by Erik Bosman |
|||
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[ |
|||
>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+ |
|||
<<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>> |
|||
>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+[>>>>>>[>>>>>>>[-]>>]<<<<<<<<<[<<<<<<<<<]>> |
|||
>>>>>[-]+<<<<<<++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<+++++++[-[->>> |
|||
>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[[-]>>>>>>[>>>>> |
|||
>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>> |
|||
[>>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<< |
|||
<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>+++++++++++++++[[ |
|||
>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[ |
|||
>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[ |
|||
-<<+>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<< |
|||
<<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<< |
|||
[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>> |
|||
>>>>[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+ |
|||
<<<<<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>> |
|||
>>>>>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<< |
|||
+>>>>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<< |
|||
<]<+<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>> |
|||
>>>>>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>> |
|||
>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<< |
|||
<<<]>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<< |
|||
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[-> |
|||
>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<< |
|||
<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++++++++++++++++ |
|||
+++++++>>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>[<<<<<<<+<[-<+>>>>+<<[-]]>[-<<[->+>>>- |
|||
<<<<]>>>]>>>>>>>>>>>>>[>>[-]>[-]>[-]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>>>>>>[>>>>> |
|||
[-<<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>[-<<<<<<<< |
|||
<+>>>>>>>>>]>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>>]+>[- |
|||
]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>>>>>>>]<<< |
|||
<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+>>]< |
|||
<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[->>>> |
|||
>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-]<->>> |
|||
[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-< |
|||
<<<<+>>>>>]<<<<<[->>>>>+<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+>>>>>>>> |
|||
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+ |
|||
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[> |
|||
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[- |
|||
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>> |
|||
[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> |
|||
]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+> |
|||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++ |
|||
+++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-<<<<<<<+ |
|||
>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[ |
|||
-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>>]>[-<<<<<<[->>>>>+<++<<<<]>>>>>[-< |
|||
<<<<+>>>>>]<->+>]<[->+<]<<<<<[->>>>>+<<<<<]>>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<< |
|||
[->>>>->>>>>[>>[-<<->>]+<<[->>->[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-] |
|||
+>>>>>>[>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<<<<<<<<<<[<<<<< |
|||
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<< |
|||
[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<< |
|||
<<<+<[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<< |
|||
<<<<<+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<< |
|||
<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+<]>>>>>>>>]<<< |
|||
<<<<<+<[>[->>>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>[->>>>+<<<<]>]<[->>>>-<<<<<<< |
|||
<<<<<<<+>>>>>>>>>>]<]>>[->>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>>+<<<< |
|||
]<<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>>>>>>>>>]<<<<<<<<< |
|||
[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<<<<<< |
|||
+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<<<<<< |
|||
<<<<<]]>[-]>>[-]>[-]>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-< |
|||
<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[ |
|||
[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+ |
|||
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->> |
|||
[-<<+>>]<<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<< |
|||
<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[ |
|||
>[-]<->>>[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[ |
|||
>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]> |
|||
>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>[-]>>>>+++++++++++++++[[>>>>>>>>>]<<<<<<<<<-<<<<< |
|||
<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<< |
|||
<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[- |
|||
<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>> |
|||
>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>>> |
|||
[-<<<->>>]<<<[->>>+<<<]>>>>>>>>]<<<<<<<<+<[>[->+>[-<-<<<<<<<<<<+>>>>>>>>>>>>[-<< |
|||
+>>]<]>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<<<]>>[-<+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<]> |
|||
[-<<+>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>> |
|||
>>>>>>]<<<<<<<<+<[>[->+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>[-<+>]>]<[-<-<<<<<<<<<<+>>>> |
|||
>>>>>>>]<<]>>>[-<<+>[-<-<<<<<<<<<<+>>>>>>>>>>>]>]<[-<+>]<<<<<<<<<<<<]>>>>>+<<<<< |
|||
]>>>>>>>>>[>>>[-]>[-]>[-]>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>>>[-<<<<< |
|||
<+>>>>>>]<<<<<<[->>>>>>+<<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>> |
|||
>]>>[-<<<<<<<[->>>>>+<++<<<<]>>>>>[-<<<<<+>>>>>]<->+>>]<<[->>+<<]<<<<<[->>>>>+<< |
|||
<<<]+>>>>[-<<<<->>>>]+<<<<[->>>>->>>>>[>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<< |
|||
<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>[-<<->>]+<<[->>->[-<<<+>>>]< |
|||
<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]< |
|||
<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+ |
|||
<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>[->>>+<<<]>]<[->>>- |
|||
<<<<<<<<<<<<<+>>>>>>>>>>]<]>>[->>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>+<<< |
|||
]<<<<<<<<<<<]>>>>>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]]>>>>[-<<<<+> |
|||
>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<<[->>>- |
|||
<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[ |
|||
->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>> |
|||
>>]<<<<[->>>>+>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>[>>>>>> |
|||
>>>]<<<<<<<<<[>[->>>>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<< |
|||
<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<< |
|||
<<<<]]>>>>>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>[-<<<<+ |
|||
>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<+>>>>> |
|||
]<<<<<[->>>>>+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>> |
|||
>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>> |
|||
>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[-<<+ |
|||
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[> |
|||
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[- |
|||
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>> |
|||
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<< |
|||
<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>> |
|||
>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<+>>> |
|||
>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+ |
|||
<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>> |
|||
>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>> |
|||
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<<<<] |
|||
>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<< |
|||
]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->>>+< |
|||
<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]> |
|||
>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>->>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>]<<+>>>>[-<<<< |
|||
->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[-<<<<<<<.>>>>>>>]<<<[-]>[-]>[-]>[-]>[-]>[-]>>>[ |
|||
>[-]>[-]>[-]>[-]>[-]>[-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]>>>>]<<<<<<<<< |
|||
[<<<<<<<<<]>+++++++++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+>>>>>>>>>+<<<<<<<< |
|||
<<<<<<[<<<<<<<<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+[-]>>[>>>>>>>>>]<<<<< |
|||
<<<<[>>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<[<<<<<<<<<]>>>>>>>[-]+>>>]<<<< |
|||
<<<<<<]]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+>>[>+>>>>[-<<<<->>>>]<<<<[->>> |
|||
>+<<<<]>>>>>>>>]<<+<<<<<<<[>>>>>[->>+<<]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<< |
|||
<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<<<<<[->>>>>>+<<<<<<]< |
|||
+<<<<<<<<<]>>>>>>>-<<<<[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>->>[>> |
|||
>>>[->>+<<]>>>>]<<<<<<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<< |
|||
<<<<[->>>>>>+<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+<<< |
|||
<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>->>[-<<<<<<<+>>>>>>>]<<<< |
|||
<<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>[-< |
|||
<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<< |
|||
<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<< |
|||
<<[<<<<<<<<<]>>>>[-]<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>-<<<<<[<<<<<<< |
|||
<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++[-[->>>>>>>> |
|||
>+<<<<<<<<<]>>>>>>>>>]>>>>>+>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<< |
|||
<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+[-]>[>>>>>>>>>]<<<<<<<<<[>>>>>>>>[-<<<<<<<+>>>>>> |
|||
>]<<<<<<<[->>>>>>>+<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+>>]<<<<<<<<<<]]>>>>>>>>[-<<<<< |
|||
<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+>[>+>>>>>[-<<<<<->>>>>]<<<<<[->>>>>+<<<<<]>>>>>> |
|||
>>]<+<<<<<<<<[>>>>>>[->>+<<]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<- |
|||
>>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]<+<<<<<< |
|||
<<<]>>>>>>>>-<<<<<[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>->[>>> |
|||
>>>[->>+<<]>>>]<<<<<<<<<[>[-]<->>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<< |
|||
<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>> |
|||
+>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<->>>>>>]+< |
|||
<<<<<[->>>>>>->>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<< |
|||
<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>> |
|||
-<<[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>> |
|||
>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<++++ |
|||
+[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>->>>>>>>>>>>>>>>>>>>>>>>>>>>-<<<<<<[<<<< |
|||
<<<<<]]>>>] |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDEGFFEEEEDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB |
|||
AAAAAAAAAAAAAAABBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDEEEFGIIGFFEEEDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBB |
|||
AAAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDEEEEFFFI KHGGGHGEDDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBB |
|||
AAAAAAAAAAAABBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEEFFGHIMTKLZOGFEEDDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBB |
|||
AAAAAAAAAAABBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEEEFGGHHIKPPKIHGFFEEEDDDDDDDDDCCCCCCCCCCBBBBBBBBBBBBBBBBBB |
|||
AAAAAAAAAABBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEEFFGHIJKS X KHHGFEEEEEDDDDDDDDDCCCCCCCCCCBBBBBBBBBBBBBBBB |
|||
AAAAAAAAABBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEEFFGQPUVOTY ZQL[MHFEEEEEEEDDDDDDDCCCCCCCCCCCBBBBBBBBBBBBBB |
|||
AAAAAAAABBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEFFFFFGGHJLZ UKHGFFEEEEEEEEDDDDDCCCCCCCCCCCCBBBBBBBBBBBB |
|||
AAAAAAABBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEFFFFFFGGGGHIKP KHHGGFFFFEEEEEEDDDDDCCCCCCCCCCCBBBBBBBBBBB |
|||
AAAAAAABBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDEEEEEFGGHIIHHHHHIIIJKMR VMKJIHHHGFFFFFFGSGEDDDDCCCCCCCCCCCCBBBBBBBBB |
|||
AAAAAABBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDEEEEEEFFGHK MKJIJO N R X YUSR PLV LHHHGGHIOJGFEDDDCCCCCCCCCCCCBBBBBBBB |
|||
AAAAABBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDEEEEEEEEEFFFFGH O TN S NKJKR LLQMNHEEDDDCCCCCCCCCCCCBBBBBBB |
|||
AAAAABBCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDEEEEEEEEEEEEFFFFFGHHIN Q UMWGEEEDDDCCCCCCCCCCCCBBBBBB |
|||
AAAABBCCCCCCCCCCCCCCCCCCCCCCCCCDDDDEEEEEEEEEEEEEEEFFFFFFGHIJKLOT [JGFFEEEDDCCCCCCCCCCCCCBBBBB |
|||
AAAABCCCCCCCCCCCCCCCCCCCCCCDDDDEEEEEEEEEEEEEEEEFFFFFFGGHYV RQU QMJHGGFEEEDDDCCCCCCCCCCCCCBBBB |
|||
AAABCCCCCCCCCCCCCCCCCDDDDDDDEEFJIHFFFFFFFFFFFFFFGGGGGGHIJN JHHGFEEDDDDCCCCCCCCCCCCCBBB |
|||
AAABCCCCCCCCCCCDDDDDDDDDDEEEEFFHLKHHGGGGHHMJHGGGGGGHHHIKRR UQ L HFEDDDDCCCCCCCCCCCCCCBB |
|||
AABCCCCCCCCDDDDDDDDDDDEEEEEEFFFHKQMRKNJIJLVS JJKIIIIIIJLR YNHFEDDDDDCCCCCCCCCCCCCBB |
|||
AABCCCCCDDDDDDDDDDDDEEEEEEEFFGGHIJKOU O O PR LLJJJKL OIHFFEDDDDDCCCCCCCCCCCCCCB |
|||
AACCCDDDDDDDDDDDDDEEEEEEEEEFGGGHIJMR RMLMN NTFEEDDDDDDCCCCCCCCCCCCCB |
|||
AACCDDDDDDDDDDDDEEEEEEEEEFGGGHHKONSZ QPR NJGFEEDDDDDDCCCCCCCCCCCCCC |
|||
ABCDDDDDDDDDDDEEEEEFFFFFGIPJIIJKMQ VX HFFEEDDDDDDCCCCCCCCCCCCCC |
|||
ACDDDDDDDDDDEFFFFFFFGGGGHIKZOOPPS HGFEEEDDDDDDCCCCCCCCCCCCCC |
|||
ADEEEEFFFGHIGGGGGGHHHHIJJLNY TJHGFFEEEDDDDDDDCCCCCCCCCCCCC |
|||
A PLJHGGFFEEEDDDDDDDCCCCCCCCCCCCC |
|||
ADEEEEFFFGHIGGGGGGHHHHIJJLNY TJHGFFEEEDDDDDDDCCCCCCCCCCCCC |
|||
ACDDDDDDDDDDEFFFFFFFGGGGHIKZOOPPS HGFEEEDDDDDDCCCCCCCCCCCCCC |
|||
ABCDDDDDDDDDDDEEEEEFFFFFGIPJIIJKMQ VX HFFEEDDDDDDCCCCCCCCCCCCCC |
|||
AACCDDDDDDDDDDDDEEEEEEEEEFGGGHHKONSZ QPR NJGFEEDDDDDDCCCCCCCCCCCCCC |
|||
AACCCDDDDDDDDDDDDDEEEEEEEEEFGGGHIJMR RMLMN NTFEEDDDDDDCCCCCCCCCCCCCB |
|||
AABCCCCCDDDDDDDDDDDDEEEEEEEFFGGHIJKOU O O PR LLJJJKL OIHFFEDDDDDCCCCCCCCCCCCCCB |
|||
AABCCCCCCCCDDDDDDDDDDDEEEEEEFFFHKQMRKNJIJLVS JJKIIIIIIJLR YNHFEDDDDDCCCCCCCCCCCCCBB |
|||
AAABCCCCCCCCCCCDDDDDDDDDDEEEEFFHLKHHGGGGHHMJHGGGGGGHHHIKRR UQ L HFEDDDDCCCCCCCCCCCCCCBB |
|||
AAABCCCCCCCCCCCCCCCCCDDDDDDDEEFJIHFFFFFFFFFFFFFFGGGGGGHIJN JHHGFEEDDDDCCCCCCCCCCCCCBBB |
|||
AAAABCCCCCCCCCCCCCCCCCCCCCCDDDDEEEEEEEEEEEEEEEEFFFFFFGGHYV RQU QMJHGGFEEEDDDCCCCCCCCCCCCCBBBB |
|||
AAAABBCCCCCCCCCCCCCCCCCCCCCCCCCDDDDEEEEEEEEEEEEEEEFFFFFFGHIJKLOT [JGFFEEEDDCCCCCCCCCCCCCBBBBB |
|||
AAAAABBCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDEEEEEEEEEEEEFFFFFGHHIN Q UMWGEEEDDDCCCCCCCCCCCCBBBBBB |
|||
AAAAABBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDEEEEEEEEEFFFFGH O TN S NKJKR LLQMNHEEDDDCCCCCCCCCCCCBBBBBBB |
|||
AAAAAABBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDEEEEEEFFGHK MKJIJO N R X YUSR PLV LHHHGGHIOJGFEDDDCCCCCCCCCCCCBBBBBBBB |
|||
AAAAAAABBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDEEEEEFGGHIIHHHHHIIIJKMR VMKJIHHHGFFFFFFGSGEDDDDCCCCCCCCCCCCBBBBBBBBB |
|||
AAAAAAABBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEFFFFFFGGGGHIKP KHHGGFFFFEEEEEEDDDDDCCCCCCCCCCCBBBBBBBBBBB |
|||
AAAAAAAABBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEFFFFFGGHJLZ UKHGFFEEEEEEEEDDDDDCCCCCCCCCCCCBBBBBBBBBBBB |
|||
AAAAAAAAABBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEEFFGQPUVOTY ZQL[MHFEEEEEEEDDDDDDDCCCCCCCCCCCBBBBBBBBBBBBBB |
|||
AAAAAAAAAABBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEEFFGHIJKS X KHHGFEEEEEDDDDDDDDDCCCCCCCCCCBBBBBBBBBBBBBBBB |
|||
AAAAAAAAAAABBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEEEFGGHHIKPPKIHGFFEEEDDDDDDDDDCCCCCCCCCCBBBBBBBBBBBBBBBBBB |
|||
AAAAAAAAAAAABBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEEFFGHIMTKLZOGFEEDDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBB |
|||
AAAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDEEEEFFFI KHGGGHGEDDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBB |
|||
AAAAAAAAAAAAAAABBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDEEEFGIIGFFEEEDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBB</pre> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
This code uses functions from category [[:Category:Raster graphics operations| Raster graphics operations]]. |
|||
===PPM non interactive=== |
|||
<lang c>#include <stdio.h> |
|||
Here is one file program. It directly creates ppm file. |
|||
#include "imglib.h" |
|||
<syntaxhighlight lang="c"> /* |
|||
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; |
|||
}</syntaxhighlight> |
|||
===PPM Interactive=== |
|||
#define MAX_ITERATIONS 500 |
|||
[[file:mandel-C-GL.png|center|400px]] |
|||
Infinitely zoomable OpenGL program. Adjustable colors, max iteration, black and white, screen dump, etc. Compile with <code>gcc mandelbrot.c -lglut -lGLU -lGL -lm</code> |
|||
* [[OpenBSD]] users, install freeglut package, and compile with <code>make mandelbrot CPPFLAGS='-I/usr/local/include `pkg-config glu --cflags`' LDLIBS='-L/usr/local/lib -lglut `pkg-config glu --libs` -lm'</code> |
|||
{{libheader|GLUT}} |
|||
The following version should work on architectures (such as x86/x86-64) that allow unaligned pointers. |
|||
<syntaxhighlight lang="c">#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <math.h> |
|||
#include <GL/glut.h> |
|||
#include <GL/gl.h> |
|||
#include <GL/glu.h> |
|||
void |
void set_texture(); |
||
unsigned int x, y; |
|||
unsigned int width, height; |
|||
color_component colour; |
|||
double x0, y0, xtemp, cr, ci; |
|||
unsigned int i; |
|||
typedef struct {unsigned char r, g, b;} rgb_t; |
|||
width = img->width; |
|||
rgb_t **tex = 0; |
|||
height = img->height; |
|||
int gwin; |
|||
GLuint texture; |
|||
for (x = 0; x < width; x++) { |
|||
int width, height; |
|||
int tex_w, tex_h; |
|||
x0 = y0 = 0; |
|||
double scale = 1./256; |
|||
cr = ((double)x / (double)width - 0.5); |
|||
double cx = -.6, cy = 0; |
|||
ci = ((double)y / (double)height - 0.5); |
|||
int color_rotate = 0; |
|||
int saturation = 1; |
|||
int invert = 0; |
|||
int max_iter = 256; |
|||
void render() |
|||
for (i = 0; x0*x0 + y0*y0 <= 4.0 && i < MAX_ITERATIONS; i++){ |
|||
{ |
|||
xtemp = x0*x0 - y0*y0 + cr; |
|||
double x = (double)width /tex_w, |
|||
y0 = 2*x0*y0 + ci; |
|||
y = (double)height/tex_h; |
|||
x0 = xtemp; |
|||
} |
|||
glClear(GL_COLOR_BUFFER_BIT); |
|||
/* points in the set are coloured as white, others are coloured black. */ |
|||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
|||
colour = (i == MAX_ITERATIONS ? 255 : 0); |
|||
glBindTexture(GL_TEXTURE_2D, texture); |
|||
put_pixel_clip(img, x, y, colour, colour, colour); |
|||
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; |
|||
}</syntaxhighlight> |
|||
Here is a variant that hopefully will work on a broader range of architectures, although it has been tested only on x86-64. |
|||
<syntaxhighlight lang="c"> |
|||
#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]] |
|||
#define W 640 |
|||
int x,[[maybe_unused]] |
|||
#define H 480 |
|||
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) |
|||
int main() |
|||
{ |
{ |
||
unsigned char r; |
|||
image img; |
|||
unsigned char g; |
|||
FILE *o; |
|||
unsigned char b; |
|||
if (min == max) |
|||
max = min + 1; |
|||
draw_mandel(img); |
|||
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; |
|||
o = fopen("mandel.ppm", "w"); |
|||
g = 0; |
|||
output_ppm(o, img); |
|||
b = 0; |
|||
free_img(img); |
|||
}</lang> |
|||
switch ((int) h) { |
|||
Or, using complex numbers, the above draw_mandel() function could be written as follows: |
|||
case 0: |
|||
{{works with|C99}} |
|||
r = c; |
|||
<lang c>#include <complex.h> |
|||
g = X; |
|||
break; |
|||
void draw_mandel(image img){ |
|||
case 1: |
|||
unsigned int x, y; |
|||
r = X; |
|||
unsigned int width, height; |
|||
g = c; |
|||
color_component colour; |
|||
break; |
|||
double complex z, c; |
|||
case 2: |
|||
unsigned int i; |
|||
g = c; |
|||
b = X; |
|||
break; |
|||
height = img->height; |
|||
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 |
|||
for (x = 0; x < width; x++) { |
|||
* rows on 4-byte boundaries (at the expense of memory, of |
|||
for (y = 0; y < height; y++) { |
|||
* course). */ |
|||
px[0] = r; |
|||
c = ((double)x / (double)width - 0.5) + ((double)y / (double)height - 0.5)I; |
|||
px[1] = g; |
|||
px[2] = b; |
|||
for (i = 0; cabs(z) <= 2.0 && i < MAX_ITERATIONS; i++){ |
|||
px[3] = 255; /* Alpha channel. */ |
|||
} |
|||
} |
|||
void calc_mandel() |
|||
/* points in the set are coloured as white, others are coloured black. */ |
|||
{ |
|||
colour = (i == MAX_ITERATIONS ? 255 : 0); |
|||
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; |
|||
} |
|||
} |
} |
||
} |
|||
}</lang> |
|||
for (i = 0; i < height; i += 1) { |
|||
=={{header|C++}}== |
|||
for (j = 0; j < width; j += 1) { |
|||
This generic function assumes that the image can be accessed like a two-dimensional array of colors. It may be passed a true array (in which case the Mandelbrot set will simply be drawn into that array, which then might be saved as image file), or a class which maps the subscript operator to the pixel drawing routine of some graphics library. In the latter case, there must be functions get_first_dimension and get_second_dimension defined for that type, to be found by argument dependent lookup. The code provides those functions for built-in arrays. |
|||
unsigned char *px = tex + (((i * width) + j) * 4); |
|||
<lang cpp>#include <cstdlib> |
|||
hsv_to_rgba(hsv[(i * width) + j], min, max, px); |
|||
#include <complex> |
|||
} |
|||
} |
|||
free(hsv); |
|||
// 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]) |
|||
void alloc_tex() |
|||
{ |
{ |
||
if (tex == NULL || width != old_width || height != old_height) { |
|||
return dim1; |
|||
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() |
|||
template<typename ElementType, std::size_t dim1, std::size_t dim2> |
|||
std::size_t get_second_dimension(ElementType (&a)[dim1][dim2]) |
|||
{ |
{ |
||
alloc_tex(); |
|||
return dim2; |
|||
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; |
|||
template<typename ColorType, typename ImageType> |
|||
cy -= (y - height / 2) * scale; |
|||
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 |
|||
switch (button) { |
|||
double cxmin, double cxmax, double cymin, double cymax,//the rect to draw in the complex plane |
|||
case GLUT_LEFT_BUTTON: /* zoom in */ |
|||
unsigned int max_iterations) //the maximum number of iterations |
|||
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); |
|||
std::size_t const ixsize = get_first_dimension(ImageType); |
|||
std::size_t const iysize = get_first_dimension(ImageType); |
|||
for (std::size_t ix = 0; ix < ixsize; ++ix) |
|||
for (std::size_t iy = 0; iy < iysize; ++iy) |
|||
{ |
|||
std::complex c(cxmin + ix/(ixsize-1.0)*(cxmax-cxmin), cymin + iy/(iysize-1.0)*(cymax-cymin)); |
|||
std::complex z = 0; |
|||
unsigned int iterations; |
|||
width = w; |
|||
for (iterations = 0; iterations < max_iterations && std::abs(z) < 2.0; ++iterations) |
|||
height = h; |
|||
glViewport(0, 0, w, h); |
|||
image[ix][iy] = (iterations == max_iterations) ? set_color : non_set_color; |
|||
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: |
|||
</syntaxhighlight> |
|||
''(PLEASE FIXME: Does resizing work correctly, in either version?)'' |
|||
===ASCII=== |
|||
Not mine, found it on Ken Perlin's homepage, this deserves a place here to illustrate how awesome C can be: |
|||
<syntaxhighlight lang="c"> |
|||
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);} |
|||
</syntaxhighlight> |
|||
There may be warnings on compiling but disregard them, the output will be produced nevertheless. Such programs are called obfuscated and C excels when it comes to writing such cryptic programs. Google IOCCC for more. |
|||
<pre> |
|||
.............::::::::::::::::::::::::::::::::::::::::::::::::....................... |
|||
.........::::::::::::::::::::::::::::::::::::::::::::::::::::::::................... |
|||
.....::::::::::::::::::::::::::::::::::-----------:::::::::::::::::::............... |
|||
...:::::::::::::::::::::::::::::------------------------:::::::::::::::............. |
|||
:::::::::::::::::::::::::::-------------;;;!:H!!;;;--------:::::::::::::::.......... |
|||
::::::::::::::::::::::::-------------;;;;!!/>&*|I !;;;--------::::::::::::::........ |
|||
::::::::::::::::::::-------------;;;;;;!!/>)|.*#|>/!!;;;;-------::::::::::::::...... |
|||
::::::::::::::::-------------;;;;;;!!!!//>|: !:|//!!!;;;;-----::::::::::::::..... |
|||
::::::::::::------------;;;;;;;!!/>)I>>)||I# H&))>////*!;;-----:::::::::::::.... |
|||
::::::::----------;;;;;;;;;;!!!//)H: #| IH&*I#/;;-----:::::::::::::... |
|||
:::::---------;;;;!!!!!!!!!!!//>|.H: #I>/!;;-----:::::::::::::.. |
|||
:----------;;;;!/||>//>>>>//>>)|% %|&/!;;----::::::::::::::. |
|||
--------;;;;;!!//)& .;I*-H#&||&/ *)/!;;-----:::::::::::::: |
|||
-----;;;;;!!!//>)IH:- ## #&!!;;-----:::::::::::::: |
|||
;;;;!!!!!///>)H%.** * )/!;;;------::::::::::::: |
|||
&)/!!;;;------::::::::::::: |
|||
;;;;!!!!!///>)H%.** * )/!;;;------::::::::::::: |
|||
-----;;;;;!!!//>)IH:- ## #&!!;;-----:::::::::::::: |
|||
--------;;;;;!!//)& .;I*-H#&||&/ *)/!;;-----:::::::::::::: |
|||
:----------;;;;!/||>//>>>>//>>)|% %|&/!;;----::::::::::::::. |
|||
:::::---------;;;;!!!!!!!!!!!//>|.H: #I>/!;;-----:::::::::::::.. |
|||
::::::::----------;;;;;;;;;;!!!//)H: #| IH&*I#/;;-----:::::::::::::... |
|||
::::::::::::------------;;;;;;;!!/>)I>>)||I# H&))>////*!;;-----:::::::::::::.... |
|||
::::::::::::::::-------------;;;;;;!!!!//>|: !:|//!!!;;;;-----::::::::::::::..... |
|||
::::::::::::::::::::-------------;;;;;;!!/>)|.*#|>/!!;;;;-------::::::::::::::...... |
|||
::::::::::::::::::::::::-------------;;;;!!/>&*|I !;;;--------::::::::::::::........ |
|||
:::::::::::::::::::::::::::-------------;;;!:H!!;;;--------:::::::::::::::.......... |
|||
...:::::::::::::::::::::::::::::------------------------:::::::::::::::............. |
|||
.....::::::::::::::::::::::::::::::::::-----------:::::::::::::::::::............... |
|||
.........::::::::::::::::::::::::::::::::::::::::::::::::::::::::................... |
|||
.............::::::::::::::::::::::::::::::::::::::::::::::::....................... |
|||
</pre> |
|||
===Fixed point 16 bit arithmetic=== |
|||
<syntaxhighlight lang="c"> |
|||
/** |
|||
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; |
|||
} |
} |
||
}</lang> |
|||
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; |
|||
} |
|||
</syntaxhighlight> |
|||
<pre> |
|||
$ gcc fixedPoint.c -lm && ./a.out |
|||
PRECISION=6 |
|||
aaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcdcccbbbbbb |
|||
aaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccddcbbbbb |
|||
aaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbegfcdbbb |
|||
aaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdccedbb |
|||
aaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdcccb |
|||
aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbcfdddcccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdded |
|||
aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbcccccddfcccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccc |
|||
aaaaaaaaaaaaaaaaaabbbbbbbbbbbbbcccccdeccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbcc |
|||
aaaaaaaaaaaaaaaaabbbbbbbbbbfcccccddeccccccccccccccccdddddeeeddddccccccbbbbbbbbbbbbbbbbbbbbbbbbbe |
|||
aaaaaaaaaaaaaaaabbbbbbbbbbcccccdddccccccccccccccdeddddeefigeeeddddecccccbbbbbbbbbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaaaaabbbbbbbecccccdddcccccccccccccdddddddddeefhmgfffddddedcccccbbbbbbbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaaaabbbbbbbcccccccdcccccccccccccccdgddddddfeefgjpijjfdddddedccccccbbbbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaaaabbbbbccccccdedccccccccccccccdddddddddeeefgkj ojgfedddddeccccccbbbbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaaabbbbbcccccegeccccccccccccccdeedddddddeeeeghhkp hgheefddddecccccccbbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaabbbbccccceddcccccccccccccccfddddddddeeeeefmlkr ihheeeedddddgccccccbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaabbbccccddfcccccccccccccccedddddddddeeegffhnp rpjffeeeiddddcccccccbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaabbbcccddecccccccccccccccddddddddddeeffffgghm jgffeeeegdddccccccccbbbbbbbbbbbbb |
|||
aaaaaaaaaaabbbccdedccccccccccccccccdddddddddeefffffgghil khggffffeeeddccccccccbbbbbbbbbbbb |
|||
aaaaaaaaaaabbccdeccccccccccccccccddddddddeeef ijjhhhkijlo qkihjhgffgngeddcccccccbbbbbbbbbbbb |
|||
aaaaaaaaaabbcddccccccccccccccccdddddddfeeeefgjq lkk p n khhhiqifedcccccccdbbbbbbbbbbb |
|||
aaaaaaaaaabbccccccccccccccccccddddddefeeeeffgilq plk rrqgeddcccccccdbbbbbbbbbb |
|||
aaaaaaaaaabdccccccccccccccccdddhegeeeeeefffghiq mfeeddcccccccdbbbbbbbbb |
|||
aaaaaaaaaaccccccccccccccccdddeeeeeeeeeeffffhjklp phfeeddcccccccdcbbbbbbbb |
|||
aaaaaaaaabcccccccccccccddddegeeeeeeeeeffffhppp jgggedddccccccccbbbbbbbb |
|||
aaaaaaaaabccccccccccddddeefpifffffffffggggik hgfedddcccccccdcbbbbbbb |
|||
aaaaaaaaaccccccceddddddeeifl hgggjrhggggghj p qjnfdddcccccccdcbbbbbbb |
|||
aaaaaaaabccccddedddddefeefghqnokkloqiqhhhik ifdddcccccccdcbbbbbbb |
|||
aaaaaaaaccceddddddddgfeeffghir o n qmjiijo igfedddcccccccccbbbbbb |
|||
aaaaaaaaccddedddddeeeeeefgghkq lll lgfddddcccccccdcbbbbbb |
|||
aaaaaaaacddddddddeeeeeefhgjol rn geddddcccccccdcbbbbbb |
|||
aaaaaaaaedddddddeeeffggojjll hfeddddeccccccdcbbbbbb |
|||
aaaaaaaaddddddefffffggmkopmop ngfefdddfccccccdcbbbbbb |
|||
aaaaaaaaeeffgihggiihikk hfeefdddeccccccddbbbbbb |
|||
aaaaaaaa kigfgefdddecccccceebbbbbb |
|||
aaaaaaaaeeffhgjggghhhklqm ligfhefdddeccccccddbbbbbb |
|||
aaaaaaaaddddddefffffgggirq hffefdddeccccccdebbbbbb |
|||
aaaaaaaahdddddddeefgfggilkjk hfeedddeccccccddbbbbbb |
|||
aaaaaaaacddddddddeeeeeefhhhkl lfefdddeccccccdcbbbbbb |
|||
aaaaaaaaccddedddddefeeeeffgijo on qfedddcccccccdcbbbbbb |
|||
aaaaaaaabcceddddddddegeeefggik r kko jhfedddcccccccdcbbbbbb |
|||
aaaaaaaabccccddddddddefeeefijmk jkp kmiijlq qhfedddcccccccccbbbbbb |
|||
aaaaaaaaacccccccdddddddeeefh hhghi kjggghil r geddcccccccdcbbbbbbb |
|||
aaaaaaaaabccccccccccdddddefgnfgffghggggggghjm lj feddcccccccdcbbbbbbb |
|||
aaaaaaaaabccccccccccccccdddeffggeeeefffffggm igfefddcccccccdbbbbbbbb |
|||
aaaaaaaaaaccccccccccccccccdddeeeeeeeeeeffffhjm kgfeddcccccccdcbbbbbbbb |
|||
aaaaaaaaaabdccccccccccccccccdddfeeeeeeeegffgiikq feeddcccccccebbbbbbbbb |
|||
aaaaaaaaaabbccccccccccccccccccdddddegeeeegffgho p nheeddcccccchfbbbbbbbbb |
|||
aaaaaaaaaabbbddcccccccccccccccccdddddeeeeeefhm l ki jlnjeddcccccccdbbbbbbbbbb |
|||
aaaaaaaaaaabbccecccccccccccccccccdddddddfeeefir jii npm k ohgggineedcccccccdbbbbbbbbbbb |
|||
aaaaaaaaaaabbbccdddccccccccccccccccddddddddeeefggggggiik mjhhgfffffedddcccccccbbbbbbbbbbbb |
|||
aaaaaaaaaaaabbbcccedfcccccccccccccccdddddddddeegffffgghp hgffgeeeedddccccccccbbbbbbbbbbbb |
|||
aaaaaaaaaaaabbbbccccdddcccccccccccccccgdddddddddeegffgil ggfeeeeddddcccccccbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaabbbbbccccdddccccccccccccccfeddddddddeeeefgi l nkqgeeegeddddcccccccbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaabbbbbbcccccdedccccccccccccccdedddddddeeeeeghik khhfeefdddddeccccccbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaaabbbbbbccccccdddcccccccccccccddedddddddeeefigil jggfedddddddcccccbbbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaaaabbbbbbbcccccccdccccccccccccccdefdddddeeeffhlliimfdddddedccccccbbbbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaaaaabbbbbbbccccccdddccccccccccccccdddddddeeefg jggheddddedccccccbbbbbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaaaaabbbbbbbbbccccccdddccccccccccccccdedddddefgiffeeddddeccccccbbbbbbbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaaaaaabbbbbbbbbbecccccdeeccccccccccccccceddddeffegddddgcccccbbbbbbbbbbbbbbbbbbbbbbbbb |
|||
aaaaaaaaaaaaaaaaaabbbbbbbbbbbbcccccdddcccccccccccccccccddddddddccccccbbbbbbbbbbbbbbbbbbbbbbbbbbc |
|||
aaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbccccddeccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbed |
|||
aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbccceddcccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccd |
|||
aaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbdcccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbecccc |
|||
aaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccdebb |
|||
aaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdfccbbb |
|||
aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcgdccbbbb |
|||
</pre> |
|||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Drawing; |
using System.Drawing; |
||
using System.Drawing.Imaging; |
using System.Drawing.Imaging; |
||
Line 350: | Line 4,622: | ||
return Re * Re + Im * Im; |
return Re * Re + Im * Im; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
|||
This generic function assumes that the image can be accessed like a two-dimensional array of colors. It may be passed a true array (in which case the Mandelbrot set will simply be drawn into that array, which then might be saved as image file), or a class which maps the subscript operator to the pixel drawing routine of some graphics library. In the latter case, there must be functions get_first_dimension and get_second_dimension defined for that type, to be found by argument dependent lookup. The code provides those functions for built-in arrays. |
|||
<syntaxhighlight lang="cpp">#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; |
|||
} |
|||
}</syntaxhighlight> |
|||
Note this code has not been executed. |
|||
---- |
|||
<br> |
|||
A Simple version in CPP. Definitely not as crazy good as the ASCII one in C above. |
|||
<syntaxhighlight lang="cpp">#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"); |
|||
}</syntaxhighlight> |
|||
=={{header|C3}}== |
|||
This program produces a BMP as output. |
|||
<syntaxhighlight lang="c3">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; |
|||
} |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
=={{header|Cixl}}== |
|||
Displays a zooming Mandelbrot using ANSI graphics. |
|||
<syntaxhighlight lang="cixl"> |
|||
use: cx; |
|||
define: max 4.0; |
|||
define: max-iter 570; |
|||
let: (max-x max-y) screen-size; |
|||
let: max-cx $max-x 2.0 /; |
|||
let: max-cy $max-y 2.0 /; |
|||
let: rows Stack<Str> new; |
|||
let: buf Buf new; |
|||
let: zoom 0 ref; |
|||
func: render()() |
|||
$rows clear |
|||
$max-y 2 / { |
|||
let: y; |
|||
$buf 0 seek |
|||
$max-x { |
|||
let: x; |
|||
let: (zx zy) 0.0 ref %%; |
|||
let: cx $x $max-cx - $zoom deref /; |
|||
let: cy $y $max-cy - $zoom deref /; |
|||
let: i #max-iter ref; |
|||
{ |
|||
let: nzx $zx deref ** $zy deref ** - $cx +; |
|||
$zy $zx deref *2 $zy deref * $cy + set |
|||
$zx $nzx set |
|||
$i &-- set-call |
|||
$nzx ** $zy deref ** + #max < $i deref and |
|||
} while |
|||
let: c $i deref % -7 bsh bor 256 mod; |
|||
$c {$x 256 mod $y 256 mod} {0 0} if-else $c new-rgb $buf set-bg |
|||
@@s $buf print |
|||
} for |
|||
$rows $buf str push |
|||
} for |
|||
1 1 #out move-to |
|||
$rows {#out print} for |
|||
$rows riter {#out print} for; |
|||
#out hide-cursor |
|||
raw-mode |
|||
let: poll Poll new; |
|||
let: is-done #f ref; |
|||
$poll #in { |
|||
#in read-char _ |
|||
$is-done #t set |
|||
} on-read |
|||
{ |
|||
$zoom &++ set-call |
|||
render |
|||
$poll 0 wait _ |
|||
$is-done deref ! |
|||
} while |
|||
#out reset-style |
|||
#out clear-screen |
|||
1 1 #out move-to |
|||
#out show-cursor |
|||
normal-mode |
|||
</syntaxhighlight> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
{{trans|Perl}} |
|||
<lang lisp>(ns mandelbrot |
|||
(:refer-clojure :exclude [+ * <]) |
|||
(:use (clojure.contrib complex-numbers) |
|||
(clojure.contrib.generic [arithmetic :only [+ *]] |
|||
[comparison :only [<]] |
|||
[math-functions :only [abs]]))) |
|||
(defn mandelbrot? [z] |
|||
(loop [c 1 |
|||
m (iterate #(+ z (* % %)) z)] |
|||
(if (and (> 20 c) |
|||
(< (abs (first m)) 2) ) |
|||
(recur (inc c) |
|||
(rest m)) |
|||
(if (= 20 c) true false)))) |
|||
Inspired by the Ruby and Perl below |
|||
(defn mandelbrot [] |
|||
(for [y (range 1 -1 -0.05) |
|||
x (range -2 0.5 0.0315)] |
|||
(if (mandelbrot? (complex x y)) "#" " "))) |
|||
<syntaxhighlight lang="lisp">(defn complex-add |
|||
(println (interpose \newline (map #(apply str %) (partition 80 (mandelbrot))))) |
|||
[[a0 b0] [a1 b1]] |
|||
</lang> |
|||
[(+ 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 "")) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
harold@freeside:~/src/mandelbrot$ clj -M mandelbrot.clj |
|||
* |
|||
* *** * |
|||
******** |
|||
********* |
|||
****** |
|||
** ** ************ * |
|||
*** ******************* * * |
|||
***************************** |
|||
**************************** |
|||
******************************** |
|||
******************************** |
|||
************************************ * |
|||
* * *********************************** |
|||
*********** *********************************** |
|||
************ ************************************** |
|||
************** ************************************ |
|||
**************************************************** |
|||
******************************************************* |
|||
************************************************************************ |
|||
******************************************************* |
|||
**************************************************** |
|||
************** ************************************ |
|||
************ ************************************** |
|||
*********** *********************************** |
|||
* * *********************************** |
|||
************************************ * |
|||
******************************** |
|||
******************************** |
|||
**************************** |
|||
***************************** |
|||
*** ******************* * * |
|||
** ** ************ * |
|||
****** |
|||
********* |
|||
******** |
|||
* *** * |
|||
* |
|||
=={{header|COBOL}}== |
|||
EBCDIC art. |
|||
<syntaxhighlight lang="cobol">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.</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
################################################################ |
|||
################################# ############################ |
|||
################################ ########################### |
|||
############################## ## ############################ |
|||
######################## # ###################### |
|||
######################## ################## |
|||
##################### ################# |
|||
#################### ############### |
|||
######## ## ##### ################ |
|||
####### # ################ |
|||
###### # ################# |
|||
#################### |
|||
###### # ################# |
|||
####### # ################ |
|||
######## ## ##### ################ |
|||
#################### ############### |
|||
##################### ################# |
|||
######################## ################## |
|||
######################## # ###################### |
|||
############################## ## ############################ |
|||
################################ ########################### |
|||
################################# ############################ |
|||
################################################################ |
|||
################################################################</pre> |
|||
=={{header|Common Lisp}}== |
|||
<syntaxhighlight lang="lisp">(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)))</syntaxhighlight> |
|||
=={{header|Cowgol}}== |
|||
{{trans|B}} |
|||
<syntaxhighlight lang="cowgol">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;</syntaxhighlight> |
|||
{{out}} |
|||
<pre>!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" |
|||
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'+)%%%$$$$$#####""""""""""" |
|||
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(+,)++&%$$$$$$######"""""" |
|||
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*5:/+('&%%$$$$$$#######""" |
|||
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@,'&%%%%%$$$$######## |
|||
!!!!!!!"""####################$$$$$$$$%%%&'())((())*,@@@@@@/+))('&&&&)'%$$###### |
|||
!!!!!!""###################$$$$$%%%%%%&&&'+.@@=/<@@@@@@@@@@@@@@@/++@..93%%$##### |
|||
!!!!!"################$$$%%%%%%%%%%&&&&'),+2@@@@@@@@@@@@@@@@@@@@@@@@@1(&&%$$#### |
|||
!!!!"##########$$$$$%%&(-(''''''''''''(*,5@@@@@@@@@@@@@@@@@@@@@@@@@@@@+)-&%$$### |
|||
!!!!####$$$$$$$$%%%%%&'(*-@1.+.@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4-(&%$$$## |
|||
!!!!#$$$$$$$$$%%%%%%'''++.6@@@@@@@@@8/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3(%%$$$$# |
|||
!!!#$$$$$$$%&&&&''()/-5.5@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?'&%%$$$$# |
|||
!!!(**+/+<523/80/46@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+)'&&%%$$$$# |
|||
!!!#$$$$$$$%&&&&''().-2.@@@@@@@@@@@@@@?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$# |
|||
!!!!#$$$$$$$$$%%%%%&'''/,.7@@@@@@@@@;/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@0'%%$$$$# |
|||
!!!!####$$$$$$$$%%%%%&'(*-:2.,/?-5+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+(&%$$$## |
|||
!!!!"##########$$$$$%%&(-(''''(''''''((*,4@@@@@@@@@@@@@@@@@@@@@@@@@@@4+).&%$$### |
|||
!!!!!"################$$$%%%%%%%%%%&&&&')<,4@@@@@@@@@@@@@@@@@@@@@@@@@/('&%%$#### |
|||
!!!!!!""##################$$$$$$%%%%%%&&&'*.@@@0@@@@@@@@@@@@@@@@1,,@//9)%%$##### |
|||
!!!!!!!"""####################$$$$$$$$%%%&(())((()**-@@@@@@/+)))'&&&')'%$$###### |
|||
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''(,@@@@@@@+'&&%%%%%$$$######## |
|||
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*7@0+('&%%%$$$$$#######""" |
|||
!!!!!!!!!!!"""""""######################$$$$$$$$$%%%&&(+-).*&%$$$$$$######"""""" |
|||
!!!!!!!!!!!!!"""""""""#######################$$$$$$%%'3(%%%$$$$$######"""""""""" |
|||
!!!!!!!!!!!!!!!""""""""""""#####################################""""""""""""""""</pre> |
|||
=={{header|Craft Basic}}== |
|||
<syntaxhighlight lang="basic">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</syntaxhighlight> |
|||
=={{header|D}}== |
=={{header|D}}== |
||
===Textual Version=== |
|||
{{libheader|qd}} |
|||
This uses <code>std.complex</code> because D built-in complex numbers are deprecated. |
|||
using {{libheader|SDL}} |
|||
<syntaxhighlight lang="d">void main() { |
|||
{{libheader|Phobos}} |
|||
import std.stdio, std.complex; |
|||
<lang D>module mandelbrot; |
|||
for (real y = -1.2; y < 1.2; y += 0.05) { |
|||
import qd; |
|||
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; |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
................................................................##..................... |
|||
.............................................................######.................... |
|||
.............................................................#######................... |
|||
..............................................................######................... |
|||
..........................................................#.#.###..#.#................. |
|||
...................................................##....################.............. |
|||
..................................................###.######################.###....... |
|||
...................................................############################........ |
|||
................................................###############################........ |
|||
................................................################################....... |
|||
.............................................#####################################..... |
|||
..............................................###################################...... |
|||
..............................##.####.#......####################################...... |
|||
..............................###########....####################################...... |
|||
............................###############.######################################..... |
|||
............................###############.#####################################...... |
|||
........................##.#####################################################....... |
|||
......#.#####################################################################.......... |
|||
........................##.#####################################################....... |
|||
............................###############.#####################################...... |
|||
............................###############.######################################..... |
|||
..............................###########....####################################...... |
|||
..............................##.####.#......####################################...... |
|||
..............................................###################################...... |
|||
.............................................#####################################..... |
|||
................................................################################....... |
|||
................................................###############################........ |
|||
...................................................############################........ |
|||
..................................................###.######################.###....... |
|||
...................................................##....################.............. |
|||
..........................................................#.#.###..#.#................. |
|||
..............................................................######................... |
|||
.............................................................#######................... |
|||
.............................................................######.................... |
|||
................................................................##..................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
.......................................................................................</pre> |
|||
===More Functional Textual Version=== |
|||
The output is similar. |
|||
<syntaxhighlight lang="d">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; |
|||
}</syntaxhighlight> |
|||
===Graphical Version=== |
|||
{{libheader|QD}} {{libheader|SDL}} {{libheader|Phobos}} |
|||
<syntaxhighlight lang="d">import qd; |
|||
double lensqr(cdouble c) { return c.re * c.re + c.im * c.im; } |
double lensqr(cdouble c) { return c.re * c.re + c.im * c.im; } |
||
Line 409: | Line 5,236: | ||
} |
} |
||
while (true) { flip; events; } |
while (true) { flip; events; } |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Dart}}== |
|||
Implementation in Dart, works on https://dartpad.dev |
|||
The implementation uses an incomplete Complex class supporting operator overloading. |
|||
<syntaxhighlight lang="dart"> |
|||
class Complex { |
|||
double _r, _i; |
|||
Complex(this._r, this._i); |
|||
get r => _r; |
|||
get i => _i; |
|||
toString() => "($r,$i)"; |
|||
operator +(Complex other) => Complex(r + other.r, i + other.i); |
|||
operator *(Complex other) => |
|||
Complex(r * other.r - i * other.i, r * other.i + other.r * i); |
|||
abs() => r * r + i * i; |
|||
} |
|||
void main() { |
|||
const startX = -1.5; |
|||
const startY = -1.0; |
|||
const stepX = 0.03; |
|||
const stepY = 0.1; |
|||
for (int y = 0; y < 20; y++) { |
|||
String line = ""; |
|||
for (int x = 0; x < 70; x++) { |
|||
var c = Complex(startX + stepX * x, startY + stepY * y); |
|||
var z = 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); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|Dc}}== |
|||
===ASCII output=== |
|||
{{works with|GNU dc}} |
|||
{{works with|OpenBSD dc}} |
|||
This can be done in a more Dc-ish way, e.g. by moving the loop macros' definitions to the initialisations in the top instead of saving the macro definition of inner loops over and over again in outer loops. |
|||
<syntaxhighlight lang="dc"> _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</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" |
|||
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'0(%%%$$$$$#####""""""""""" |
|||
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(++)++&$$$$$$$######"""""" |
|||
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*@;/*('&%%$$$$$$#######""" |
|||
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@+'&%%%%%$$$$######## |
|||
!!!!!!!"""####################$$$$$$$$%%%&'())((())*-@@@@@@.+))('&&&&+&%$$###### |
|||
!!!!!!""###################$$$$$%%%%%%&&&'+.@@@08@@@@@@@@@@@@@@@/+,@//@)%%$##### |
|||
!!!!!"################$$$%%%%%%%%%%&&&&')-+7@@@@@@@@@@@@@@@@@@@@@@@@@4(&&%$$#### |
|||
!!!!"##########$$$$$%%&(,('''''''''''((*-5@@@@@@@@@@@@@@@@@@@@@@@@@@@3+)4&%$$### |
|||
!!!!####$$$$$$$$%%%%%&'(*-@1.+/@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3+'&%$$$## |
|||
!!!!#$$$$$$$$$%%%%%%'''++.7@@@@@@@@@9/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<6'%%$$$$# |
|||
!!!#$$$$$$$%&&&&''().-2.6@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$# |
|||
!!!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2+)'&&%%$$$$# |
|||
!!!#$$$$$$$%&&&&''().-2.6@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$# |
|||
!!!!#$$$$$$$$$%%%%%%'''++.7@@@@@@@@@9/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<6'%%$$$$# |
|||
!!!!####$$$$$$$$%%%%%&'(*-@1.+/@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3+'&%$$$## |
|||
!!!!"##########$$$$$%%&(,('''''''''''((*-5@@@@@@@@@@@@@@@@@@@@@@@@@@@3+)4&%$$### |
|||
!!!!!"################$$$%%%%%%%%%%&&&&')-+7@@@@@@@@@@@@@@@@@@@@@@@@@4(&&%$$#### |
|||
!!!!!!""###################$$$$$%%%%%%&&&'+.@@@08@@@@@@@@@@@@@@@/+,@//@)%%$##### |
|||
!!!!!!!"""####################$$$$$$$$%%%&'())((())*-@@@@@@.+))('&&&&+&%$$###### |
|||
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@+'&%%%%%$$$$######## |
|||
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*@;/*('&%%$$$$$$#######""" |
|||
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(++)++&$$$$$$$######"""""" |
|||
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'0(%%%$$$$$#####""""""""""" |
|||
!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" |
|||
</pre> |
|||
===PGM (P5) output=== |
|||
This is a condensed version of the ASCII output variant modified to generate a PGM (P5) image. |
|||
<syntaxhighlight lang="dc">_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</syntaxhighlight> |
|||
=={{header|Delphi}}== |
|||
See [https://rosettacode.org/wiki/Mandelbrot_set#Pascal Pascal]. |
|||
=={{header|DWScript}}== |
|||
{{trans|D}} |
|||
<syntaxhighlight lang="delphi">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;</syntaxhighlight> |
|||
=={{header|EasyLang}}== |
|||
[https://easylang.online/apps/mandelbrot.html Run it] |
|||
<syntaxhighlight lang=text> |
|||
res = 4 |
|||
maxiter = 200 |
|||
# |
|||
# better but slower: |
|||
# res = 8 |
|||
# maxiter = 300 |
|||
# |
|||
# |
|||
mid = res * 50 |
|||
center_x = 3 * mid / 2 |
|||
center_y = mid |
|||
scale = mid |
|||
# |
|||
background 000 |
|||
textsize 2 |
|||
# |
|||
fastfunc iter cx cy maxiter . |
|||
while xx + yy < 4 and it < maxiter |
|||
y = 2 * x * y + cy |
|||
x = xx - yy + cx |
|||
xx = x * x |
|||
yy = y * y |
|||
it += 1 |
|||
. |
|||
return it |
|||
. |
|||
proc draw . . |
|||
clear |
|||
for scr_y = 0 to 2 * mid - 1 |
|||
cy = (scr_y - center_y) / scale |
|||
for scr_x = 0 to 2 * mid - 1 |
|||
cx = (scr_x - center_x) / scale |
|||
it = iter cx cy maxiter |
|||
if it < maxiter |
|||
color3 it / 20 it / 100 it / 150 |
|||
move scr_x / res scr_y / res |
|||
rect 1 / res 1 / res |
|||
. |
|||
. |
|||
. |
|||
color 990 |
|||
move 1 1 |
|||
text "Short press to zoom in, long to zoom out" |
|||
. |
|||
on mouse_down |
|||
time0 = systime |
|||
. |
|||
on mouse_up |
|||
center_x += mid - mouse_x * res |
|||
center_y += mid - mouse_y * res |
|||
if systime - time0 < 0.3 |
|||
center_x -= mid - center_x |
|||
center_y -= mid - center_y |
|||
scale *= 2 |
|||
else |
|||
center_x += (mid - center_x) * 3 / 4 |
|||
center_y += (mid - center_y) * 3 / 4 |
|||
scale /= 4 |
|||
. |
|||
draw |
|||
. |
|||
draw |
|||
</syntaxhighlight> |
|||
=={{header|eC}}== |
|||
[[File:Mandelbrot4.png]] |
|||
[http://ecere.com/apps/mandelbrot/ (Try it in a WebApp)] |
|||
Drawing code: |
|||
<syntaxhighlight lang="ec">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; |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
Interactive class with Rubberband Zoom: |
|||
<syntaxhighlight lang="ec">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 {};</syntaxhighlight> |
|||
=={{header|EchoLisp}}== |
|||
<syntaxhighlight lang="scheme"> |
|||
(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] |
|||
</syntaxhighlight> |
|||
=={{header|Elixir}}== |
|||
<syntaxhighlight lang="elixir">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</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
??????=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<=========== |
|||
?????===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== |
|||
????===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= |
|||
???==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== |
|||
??==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== |
|||
??=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== |
|||
?=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== |
|||
?<<<<;;;;;:::972456-567763 +9;;<<<<<<<= |
|||
?<;;;;;;::::9875& .3 *9;;;<<<<<<= |
|||
?;;;;;;::997564' ' 8:;;;<<<<<<= |
|||
?::988897735/ &89:;;;<<<<<<= |
|||
?::988897735/ &89:;;;<<<<<<= |
|||
?;;;;;;::997564' ' 8:;;;<<<<<<= |
|||
?<;;;;;;::::9875& .3 *9;;;<<<<<<= |
|||
?<<<<;;;;;:::972456-567763 +9;;<<<<<<<= |
|||
?=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== |
|||
??=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== |
|||
??==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== |
|||
???==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== |
|||
????===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= |
|||
?????===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== |
|||
??????=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<=========== |
|||
</pre> |
|||
=={{header|Emacs Lisp}}== |
|||
===Text mode=== |
|||
<syntaxhighlight lang="lisp">; === 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)</syntaxhighlight> |
|||
{{output}} |
|||
<pre>---------------------------------------------------------------------------- |
|||
---------------------------------------------------------------------------- |
|||
---------------------------------------------------------------------------- |
|||
---------------------------------------------------------*------------------ |
|||
---------------------------------------------------------------------------- |
|||
----------------------------------------------------**--***--*-------------- |
|||
-----------------------------------------------------********--------------- |
|||
------------------------------------------------------*******--------------- |
|||
--------------------------------------------*-*--******************--------- |
|||
--------------------------------------------****************************---- |
|||
-----------------------------------------*-****************************----- |
|||
-----------------------------------------*******************************---- |
|||
---------------------------------------************************************- |
|||
--------------------------**--**-*-----**********************************--- |
|||
-------------------------***********---************************************- |
|||
------------------*-----**************************************************-- |
|||
-------------------*****************************************************---- |
|||
-*********************************************************************------ |
|||
-------------------*****************************************************---- |
|||
------------------*-----**************************************************-- |
|||
-------------------------***********---************************************- |
|||
--------------------------**--**-*-----**********************************--- |
|||
---------------------------------------************************************- |
|||
-----------------------------------------*******************************---- |
|||
-----------------------------------------*-****************************----- |
|||
--------------------------------------------****************************---- |
|||
--------------------------------------------*-*--******************--------- |
|||
------------------------------------------------------*******--------------- |
|||
-----------------------------------------------------********--------------- |
|||
----------------------------------------------------**--***--*-------------- |
|||
---------------------------------------------------------------------------- |
|||
---------------------------------------------------------*------------------ |
|||
---------------------------------------------------------------------------- |
|||
----------------------------------------------------------------------------</pre> |
|||
===Graphical version=== |
|||
[[File:Mandelbrot emacs lisp.png|thumb|Output]] |
|||
With a few modifications (mandel-size, mandel-iter, string-to-image, mandel-pic), the code above can also render the Mandelbrot fractal to an XPM image and display it directly in the buffer. (You might have to scroll up in Emacs after the function has run to see its output.) |
|||
<syntaxhighlight lang="lisp">; === 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)</syntaxhighlight> |
|||
=={{header|Erlang}}== |
|||
{{trans|Haskell}} |
|||
Function ''seq_float/2'' is copied from [https://gist.github.com/andruby/241489 Andrew Fecheyr's GitHubGist]. |
|||
Using module complex from [https://github.com/ghulette/mandelbrot-erlang/blob/master/simple/complex.erl Geoff Hulette's GitHub repository] |
|||
[https://github.com/ghulette/mandelbrot-erlang Geoff Hulette's GitHub repository] provides two alternative implementations which are very interesting. |
|||
<syntaxhighlight lang="erlang"> |
|||
-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, []). |
|||
% ************************************************** |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
** |
|||
****** |
|||
******** |
|||
****** |
|||
******** ** * |
|||
*** ***************** |
|||
************************ *** |
|||
**************************** |
|||
****************************** |
|||
****************************** |
|||
************************************ |
|||
* ********************************** |
|||
** ***** * ********************************** |
|||
*********** ************************************ |
|||
************** ************************************ |
|||
*************************************************** |
|||
***************************************************** |
|||
***************************************************** |
|||
***************************************************** |
|||
*************************************************** |
|||
************** ************************************ |
|||
*********** ************************************ |
|||
** ***** * ********************************** |
|||
* ********************************** |
|||
************************************ |
|||
****************************** |
|||
****************************** |
|||
**************************** |
|||
************************ *** |
|||
*** ***************** |
|||
******** ** * |
|||
****** |
|||
******** |
|||
****** |
|||
** |
|||
</pre> |
|||
=={{header|ERRE}}== |
|||
<syntaxhighlight lang="erre"> |
|||
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 |
|||
</syntaxhighlight> |
|||
Note: This is a PC version which uses EGA 16-color 320x200. Graphic commands are taken from |
|||
PC.LIB library. |
|||
=={{header|F Sharp|F#}}== |
|||
<syntaxhighlight lang="fsharp">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)</syntaxhighlight> |
|||
=== Alternate version, applicable to text and GUI === |
|||
''' Basic generation code ''' |
|||
<syntaxhighlight lang="fsharp"> |
|||
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)) |
|||
</syntaxhighlight> |
|||
''' Text display ''' |
|||
<syntaxhighlight lang="fsharp"> |
|||
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") |
|||
</syntaxhighlight> |
|||
Results: |
|||
{{out}} |
|||
<pre> |
|||
................................................................................ |
|||
................................................................................ |
|||
................................................. ............................. |
|||
................................................ ........................... |
|||
................................................. ........................... |
|||
....................................... . ...................... |
|||
........................................ ................. |
|||
.................................... .................. |
|||
.................................... ................. |
|||
.......................... ...... ................ |
|||
....................... ... ................ |
|||
..................... . ................ |
|||
................. ................. |
|||
................. ................. |
|||
..................... . ................ |
|||
....................... ... ................ |
|||
.......................... ...... ................ |
|||
.................................... ................. |
|||
.................................... .................. |
|||
........................................ ................. |
|||
....................................... . ...................... |
|||
................................................. ........................... |
|||
................................................ ........................... |
|||
................................................. ............................. |
|||
................................................................................ |
|||
</pre> |
|||
''' Graphics display ''' |
|||
<syntaxhighlight lang="fsharp"> |
|||
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)) |
|||
</syntaxhighlight> |
|||
=={{header|Factor}}== |
|||
<syntaxhighlight lang="factor"> |
|||
! 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 |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>bbbbbbbcccccdddddddddddddddddddeeeeeeeffghjpjl feeeeedddddcccccccccccc |
|||
bbbbbbccccddddddddddddddddddeeeeeeeefffghikopjhgffeeeeedddddcccccccccc |
|||
bbbbbcccddddddddddddddddddeeeeeeeefffggjotx etiigfffeeeeddddddcccccccc |
|||
bbbbccddddddddddddddddddeeeeeeeffgggghhjq iihgggfffeedddddddcccccc |
|||
bbbccddddddddddddddddeeeeeefffghvasjjqqyqt upqlrjhhhkhfedddddddccccc |
|||
bbbcdddddddddddddddeeeeffffffgghks c qnbpfmgfedddddddcccc |
|||
bbcdddddddddddddeefffffffffgggipmt qhgfeedddddddccc |
|||
bbdddddddddeeeefhlggggggghhhhils ljigfeedddddddcc |
|||
bcddddeeeeeefffghmllkjiljjiijle yhfeedddddddcc |
|||
bddeeeeeeeffffghhjoj do clmq qlgfeeedddddddc |
|||
bdeeeeeefffffhiijpu sm ohffeeedddddddc |
|||
beffeefgggghhjocsu higffeeedddddddc |
|||
cmihgffeeedddddddd |
|||
beffeefgggghhjocsu higffeeedddddddc |
|||
bdeeeeeefffffhiijpu sd ohffeeedddddddc |
|||
bddeeeeeeeffffghhjoj do clmq qlgfeeedddddddc |
|||
bcddddeeeeeefffghmllkjiljjiijle yhfeedddddddcc |
|||
bbdddddddddeeeefhlggggggghhhhils ljigfeedddddddcc |
|||
bbcdddddddddddddeefffffffffgggipmt qhgfeedddddddccc |
|||
bbbcdddddddddddddddeeeeffffffgghks c qnbpfmgfedddddddcccc |
|||
bbbccddddddddddddddddeeeeeefffghvasjjqqyqt upqlrjhhhkhfedddddddccccc |
|||
bbbbccddddddddddddddddddeeeeeeeffgggghhjq iihgggfffeedddddddcccccc |
|||
bbbbbcccddddddddddddddddddeeeeeeeefffggjotx etiigfffeeeeddddddcccccccc |
|||
bbbbbbccccddddddddddddddddddeeeeeeeefffghikopjhgffeeeeedddddcccccccccc |
|||
bbbbbbbcccccdddddddddddddddddddeeeeeeeffghjpjl feeeeedddddcccccccccccc |
|||
</pre> |
|||
=={{header|Fennel}}== |
|||
<syntaxhighlight lang="fennel"> |
|||
#!/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)) |
|||
</syntaxhighlight> |
|||
=={{header|FOCAL}}== |
|||
<syntaxhighlight lang="focal">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</syntaxhighlight> |
|||
{{output}} |
|||
<pre> |
|||
********************************************************************** |
|||
********************************************************************** |
|||
**************************************************** ***************** |
|||
************************************************* *************** |
|||
************************************************* *************** |
|||
**************************************** * ********** |
|||
*************************************** * ****** |
|||
************************************* ***** |
|||
********************** **** ******* **** |
|||
*********************** ** ** |
|||
********************* **** |
|||
*** * ******* |
|||
********************* **** |
|||
*********************** ** ** |
|||
********************** **** ******* **** |
|||
************************************* ***** |
|||
*************************************** * ****** |
|||
**************************************** * ********** |
|||
************************************************* *************** |
|||
************************************************* *************** |
|||
**************************************************** ***************** |
|||
********************************************************************** |
|||
********************************************************************** |
|||
********************************************************************** |
|||
</pre> |
|||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
This uses [[grayscale image]] utilities. |
This uses [[grayscale image]] utilities. |
||
< |
<syntaxhighlight lang="forth">500 value max-iter |
||
: mandel ( gmp F: imin imax rmin rmax -- ) |
: mandel ( gmp F: imin imax rmin rmax -- ) |
||
Line 435: | Line 6,394: | ||
80 24 graymap |
80 24 graymap |
||
dup -1e 1e -2e 1e mandel |
dup -1e 1e -2e 1e mandel</syntaxhighlight> |
||
{{works with|4tH v3.64}} |
|||
This is a completely integer version without local variables, which uses 4tH's native graphics library. |
|||
<syntaxhighlight lang="forth">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 |
dup gshow |
||
free bye</ |
free bye</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{Works with|Fortran|90 and later}} |
{{Works with|Fortran|90 and later}} |
||
< |
<syntaxhighlight lang="fortran">program mandelbrot |
||
implicit none |
implicit none |
||
Line 495: | Line 6,499: | ||
close (10) |
close (10) |
||
end program mandelbrot</ |
end program mandelbrot</syntaxhighlight>bs |
||
=={{header|Frink}}== |
|||
This draws a graphical Mandelbrot set using Frink's built-in graphics and complex arithmetic. |
|||
<syntaxhighlight lang="frink"> |
|||
// 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[] |
|||
</syntaxhighlight> |
|||
=={{header|Furor}}== |
|||
<syntaxhighlight lang="furor"> |
|||
###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” } |
|||
</syntaxhighlight> |
|||
=={{header|Futhark}}== |
|||
{{incorrect|Futhark|Futhark's syntax has changed, so this example will not compile}} |
|||
Computes escapes for each pixel, but not the colour. |
|||
<syntaxhighlight lang="futhark"> |
|||
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)) |
|||
</syntaxhighlight> |
|||
=={{header|FutureBasic}}== |
|||
<syntaxhighlight lang="futurebasic"> |
|||
_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 |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
<pre> |
|||
!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" |
|||
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'+)%%%$$$$$#####""""""""""" |
|||
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(+,)++&%$$$$$$######"""""" |
|||
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*5:/+('&%%$$$$$$#######""" |
|||
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@,'&%%%%%$$$$######## |
|||
!!!!!!!"""####################$$$$$$$$%%%&'())((())*,@@@@@@/+))('&&&&)'%$$###### |
|||
!!!!!!""###################$$$$$%%%%%%&&&'+.@@=/<@@@@@@@@@@@@@@@/++@..93%%$##### |
|||
!!!!!"################$$$%%%%%%%%%%&&&&'),+2@@@@@@@@@@@@@@@@@@@@@@@@@1(&&%$$#### |
|||
!!!!"##########$$$$$%%&(-(''''''''''''(*,5@@@@@@@@@@@@@@@@@@@@@@@@@@@@+)-&%$$### |
|||
!!!!####$$$$$$$$%%%%%&'(*-@1.+.@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4-(&%$$$## |
|||
!!!!#$$$$$$$$$%%%%%%'''++.6@@@@@@@@@8/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3(%%$$$$# |
|||
!!!#$$$$$$$%&&&&''()/-5.5@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?'&%%$$$$# |
|||
!!!(**+/+<523/80/46@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+)'&&%%$$$$# |
|||
!!!#$$$$$$$%&&&&''().-2.@@@@@@@@@@@@@@?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$# |
|||
!!!!#$$$$$$$$$%%%%%&'''/,.7@@@@@@@@@;/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@0'%%$$$$# |
|||
!!!!####$$$$$$$$%%%%%&'(*-:2.,/?-5+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+(&%$$$## |
|||
!!!!"##########$$$$$%%&(-(''''(''''''((*,4@@@@@@@@@@@@@@@@@@@@@@@@@@@4+).&%$$### |
|||
!!!!!"################$$$%%%%%%%%%%&&&&')<,4@@@@@@@@@@@@@@@@@@@@@@@@@/('&%%$#### |
|||
!!!!!!""##################$$$$$$%%%%%%&&&'*.@@@0@@@@@@@@@@@@@@@@1,,@//9)%%$##### |
|||
!!!!!!!"""####################$$$$$$$$%%%&(())((()**-@@@@@@/+)))'&&&')'%$$###### |
|||
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''(,@@@@@@@+'&&%%%%%$$$######## |
|||
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*7@0+('&%%%$$$$$#######""" |
|||
!!!!!!!!!!!"""""""######################$$$$$$$$$%%%&&(+-).*&%$$$$$$######"""""" |
|||
!!!!!!!!!!!!!"""""""""#######################$$$$$$%%'3(%%%$$$$$######"""""""""" |
|||
!!!!!!!!!!!!!!!""""""""""""#####################################""""""""""""""" |
|||
</pre> |
|||
=={{header|Fōrmulæ}}== |
|||
{{FormulaeEntry|page=https://formulae.org/?script=examples/Mandelbrot_set}} |
|||
'''Solution''' |
|||
We need first to generate a color palette, this is, a list of colors: |
|||
[[File:Fōrmulæ - Julia set 01.png]] |
|||
[[File:Fōrmulæ - Julia set 02.png]] |
|||
[[File:Fōrmulæ - Julia set 03.png]] |
|||
The following function draw the Mandelbrot set: |
|||
[[File:Fōrmulæ - Mandelbrot set 01.png]] |
|||
'''Test Case 1. Grayscale palette''' |
|||
[[File:Fōrmulæ - Mandelbrot set 02.png]] |
|||
[[File:Fōrmulæ - Mandelbrot set 03.png]] |
|||
'''Test case 2. Black & white palette''' |
|||
[[File:Fōrmulæ - Mandelbrot set 04.png]] |
|||
[[File:Fōrmulæ - Mandelbrot set 05.png]] |
|||
=={{header|GLSL}}== |
|||
Uses smooth coloring. |
|||
<syntaxhighlight lang="glsl"> |
|||
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)); |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|gnuplot}}== |
=={{header|gnuplot}}== |
||
The output from gnuplot is controlled by setting the appropriate values for the options <code>terminal</code> and <code>output</code>. |
The output from gnuplot is controlled by setting the appropriate values for the options <code>terminal</code> and <code>output</code>. |
||
< |
<syntaxhighlight lang="gnuplot">set terminal png |
||
set output 'mandelbrot.png'</ |
set output 'mandelbrot.png'</syntaxhighlight> |
||
The following script draws an image of the number of iterations it takes to escape the circle with radius <code>rmax</code> with a maximum of <code>nmax</code>. |
The following script draws an image of the number of iterations it takes to escape the circle with radius <code>rmax</code> with a maximum of <code>nmax</code>. |
||
< |
<syntaxhighlight lang="gnuplot">rmax = 2 |
||
nmax = 100 |
nmax = 100 |
||
complex (x, y) = x * {1, 0} + y * {0, 1} |
complex (x, y) = x * {1, 0} + y * {0, 1} |
||
Line 509: | Line 6,813: | ||
set pm3d map |
set pm3d map |
||
set size square |
set size square |
||
splot [-2 : |
splot [-2 : .8] [-1.4 : 1.4] mandelbrot (complex (0, 0), complex (x, y), 0) notitle</syntaxhighlight> |
||
{{out}} |
|||
The output can be found [http://i46.tinypic.com/2ir5aah.png here]. |
|||
[[File:mandelbrot.png]] |
|||
=={{header|Go}}== |
|||
;Text |
|||
Prints an 80-char by 41-line depiction. |
|||
<syntaxhighlight lang="go">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("") |
|||
} |
|||
}</syntaxhighlight> |
|||
;Graphical |
|||
[[File:GoMandelbrot.png|thumb|right|.png image]] |
|||
<syntaxhighlight lang="go">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) |
|||
} |
|||
}</syntaxhighlight> |
|||
=={{header|Golfscript}}== |
|||
Código sacado de https://codegolf.stackexchange.com/ |
|||
<syntaxhighlight lang="golfscript">20{40{0.1{.{;..*2$.*\- |
|||
20/3$-@@*10/3$-..*2$.*+1600<}*}32*' |
|||
*'=\;\;@@(}60*;(n\}40*;]''+</syntaxhighlight> |
|||
{{out}} |
|||
<pre>000000000000000000000000000000000000000010000000000000000000 |
|||
000000000000000000000000000000000000000000000000000000000000 |
|||
000000000000000000000000000000000001000000000000000000000000 |
|||
000000000000000000000000000000000000001000000000000000000000 |
|||
000000000000000000000000000000000000111000000000000000000000 |
|||
000000000000000000000000000000000000111110000000000000000000 |
|||
000000000000000000000000000000000000011100000000000000000000 |
|||
000000000000000000000000000001000110111100010000000000000000 |
|||
000000000000000000000000000000100111111111110000000000000000 |
|||
000000000000000000000000000001011111111111110111000000000000 |
|||
000000000000000000000000000001111111111111111110000000000000 |
|||
000000000000000000000000000000111111111111111110000000000000 |
|||
000000000000001000000000000011111111111111111111000000000000 |
|||
000000000000000000000000000011111111111111111111000000000000 |
|||
000000000000000000000000000111111111111111111111000000000000 |
|||
000000000000000000000000001111111111111111111111100000000000 |
|||
000000000000000001111110001111111111111111111111100000000000 |
|||
000000000000000011111111101111111111111111111111100000000000 |
|||
000000000000100111111111111111111111111111111111000000000000 |
|||
000000000001101111111111111111111111111111111111000000000000 |
|||
011111111111111111111111111111111111111111111100000000000000 |
|||
000000000000001111111111111111111111111111111110000000000000 |
|||
000000000000000111111111111111111111111111111111000000000000 |
|||
000000000000000001111111111111111111111111111111100000000000 |
|||
000000000000000001111111101111111111111111111111000000000000 |
|||
000000000000000001011100000111111111111111111111100000000000 |
|||
000000000000000000000100000111111111111111111111000000000000 |
|||
000000000000000100000000001111111111111111111111100000000000 |
|||
000000000000000100000000000011111111111111111111000000000000 |
|||
000000000000000000000000000011111111111111111110000000000000 |
|||
000000000000000000000000000001111111111111111111000000000000 |
|||
000000000000000000000000000000111111111111111111000000000000 |
|||
000000000000000000000000000001101111111111111000000000000000 |
|||
000000000000000000000000000011000011111110100000000000000000 |
|||
000000000000000000000000000000000000111100000000000000000000 |
|||
000000000000000000000000000000000000111110000000000000000000 |
|||
000000000000000000000000000000000000111100000000000000000000 |
|||
000000000000000000000000000000000000011000000000000000000000 |
|||
000000000000000000000000000000000000001000000000000000000000 |
|||
000000000000000000000000000000000000000000000000000000000000</pre> |
|||
=={{header|Hare}}== |
|||
{{trans|D}} |
|||
<syntaxhighlight lang="hare">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); |
|||
};</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
................................................................##..................... |
|||
.............................................................######.................... |
|||
.............................................................#######................... |
|||
..............................................................######................... |
|||
..........................................................#.#.###..#.#................. |
|||
...................................................##....################.............. |
|||
..................................................###.######################.###....... |
|||
...................................................############################........ |
|||
................................................###############################........ |
|||
................................................################################....... |
|||
.............................................#####################################..... |
|||
..............................................###################################...... |
|||
..............................##.####.#......####################################...... |
|||
..............................###########....####################################...... |
|||
............................###############.######################################..... |
|||
............................###############.#####################################...... |
|||
........................##.#####################################################....... |
|||
......#.###...#.#############################################################.......... |
|||
........................##.#####################################################....... |
|||
............................###############.#####################################...... |
|||
............................###############.######################################..... |
|||
..............................###########....####################################...... |
|||
..............................##.####.#......####################################...... |
|||
..............................................###################################...... |
|||
.............................................#####################################..... |
|||
................................................################################....... |
|||
................................................###############################........ |
|||
...................................................############################........ |
|||
..................................................###.######################.###....... |
|||
...................................................##....################.............. |
|||
..........................................................#.#.###..#.#................. |
|||
..............................................................######................... |
|||
.............................................................#######................... |
|||
.............................................................######.................... |
|||
................................................................##..................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
....................................................................................... |
|||
</pre> |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
{{trans|Ruby}} |
{{trans|Ruby}} |
||
< |
<syntaxhighlight lang="haskell">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] |
|||
]</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
** |
|||
****** |
|||
******** |
|||
****** |
|||
******** ** * |
|||
*** ***************** |
|||
************************ *** |
|||
**************************** |
|||
****************************** |
|||
****************************** |
|||
************************************ |
|||
* ********************************** |
|||
** ***** * ********************************** |
|||
*********** ************************************ |
|||
************** ************************************ |
|||
*************************************************** |
|||
***************************************************** |
|||
*********************************************************************** |
|||
***************************************************** |
|||
*************************************************** |
|||
************** ************************************ |
|||
*********** ************************************ |
|||
** ***** * ********************************** |
|||
* ********************************** |
|||
************************************ |
|||
****************************** |
|||
****************************** |
|||
**************************** |
|||
************************ *** |
|||
*** ***************** |
|||
******** ** * |
|||
****** |
|||
******** |
|||
****** |
|||
** </pre> |
|||
'''haskell one-liners :''' |
|||
<syntaxhighlight lang="haskell"> |
|||
-- 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 |
|||
</syntaxhighlight> |
|||
A legible variant of the first of the "one-liner" contributions above: |
|||
<syntaxhighlight lang="haskell">main :: IO () |
|||
mandelbrot a = iterate (\z -> z^2 + a) a !! 50 |
|||
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] |
|||
) |
|||
[".", "\'", ":", "!", "|", "}", "#", " "] |
|||
)</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> # |
|||
## |
|||
# |
|||
}}}}}}} |
|||
#}}}}}}}} |
|||
}}}}}}}}} |
|||
}}}}}}}}} |
|||
}}}}}}}}}# |
|||
}}}}}}}}}} |
|||
}}}}}}}} |
|||
}}}}}}} |
|||
|||}} |
|||
} ||||||||||| |
|||
} ||||||||||||||||||| | |
|||
. ' ||||||||||||||||||||||||| |
|||
..' |||||||||||||||||||||||||||| |
|||
'... ||||||||||||||||||||||||||||||| '.': |
|||
'':|||||||||||||||||||||||||||||||||| :...' |
|||
||||||||||||||||||||||||||||||||||||:'..' |
|||
|||||||||||||||||||||||||||||||||||||||:'' |
|||
}||||||||||||||||||||||||||||||||||||||||| |
|||
||||||||||||||||||||||||||||||||||||||||||| |
|||
|| ||||||||||||||||||||||||||||||||||||||||||||! |
|||
||}||||||||||||||||||||||||||||||||||||||||||||| |
|||
||||||||||||||||||||||||||||||||||||||||||||||| |
|||
||||||||||||||||||||||||||||||||||||||||||||||||| |
|||
|||||||||||||||||||||||||||!!!!!|||||||||||||||||| : |
|||
|||||||||||||||||||||||||!!!!!!!!!!!!|||||||||||||||'.' |
|||
||||||||||||||||||||||!!!!!!!!!!!!!!!!||||||||||||| . |
|||
.||||||||||||||||||||!!!!!!!!!!!!!!!!!!!!|||||||||||| |
|||
| |||||||||||||||||||||!!!!!!!!!!!!!!!!!!!!!!||||||||||| |
|||
| | |||||||||||||||||||!!!!!!!!!!!!!!!!!!!!!!!!|||||||||| |
|||
||! .:::!!!!. ||||||||||||||||||||!!!!!!!!!!!!!:::!!!!!!!!!|||||||||| |
|||
!'::::::::!!! ||||||||||||||||||!!!!!!!!!!!:::::::::!!!!!!!||||||||||| |
|||
::::::::::::!!!| |||||||||||||||||||!!!!!!!!!:::::::::::::!!!!!!|||||||| |
|||
!::::::::::::::!!!! ||||||||||||||||||!!!!!!!!!:::::::::::::::!!!!!|||||||| |
|||
. ::::::''''::::::!!! |||||||||||||||||!!!!!!!!!:::::::''''::::::!!!!|||||||| |
|||
:::::'''''''''::::!!! |||||||||||||||||!!!!!!!!::::::'''''''''::::!!!!|||||||| |
|||
!::::''''''''''':::!!! ||||||||||||||||||!!!!!!!::::::''''''''''':::!!!!||||||! |
|||
::::''''''..''''':::!!! |||||||||||||||||!!!!!!!!:::::''''''..''''':::!!!||||||} |
|||
:::'''''......''':::!!! |||||||||||||||||!!!!!!!:::::'''''......''':::!!!|||||| |
|||
::::''''........'''::!!!||||||||||||||||||!!!!!!!:::::''''........'''::!!!||||| |
|||
.... ::::'''..........''::!!!||||||||||||||||||!!!!!!!:::::'''..........''::!!|||||| |
|||
.....':::''''..........''::!!|||||||||||||||||||!!!!!!!::::''''..........''::!!|||| |
|||
## | ::.....':::''''..........''::!!|||||||||||||||||||!!!!!!!::::''''..........''::!!|| |
|||
.....':::''''..........''::!!|||||||||||||||||||!!!!!!!::::''''..........''::!!|||| |
|||
.... ::::'''..........''::!!!||||||||||||||||||!!!!!!!:::::'''..........''::!!|||||| |
|||
::::''''........'''::!!!||||||||||||||||||!!!!!!!:::::''''........'''::!!!||||| |
|||
:::'''''......''':::!!! |||||||||||||||||!!!!!!!:::::'''''......''':::!!!|||||| |
|||
::::''''''..''''':::!!! |||||||||||||||||!!!!!!!!:::::''''''..''''':::!!!||||||} |
|||
!::::''''''''''':::!!! ||||||||||||||||||!!!!!!!::::::''''''''''':::!!!!||||||! |
|||
:::::'''''''''::::!!! |||||||||||||||||!!!!!!!!::::::'''''''''::::!!!!|||||||| |
|||
. ::::::''''::::::!!! |||||||||||||||||!!!!!!!!!:::::::''''::::::!!!!|||||||| |
|||
!::::::::::::::!!!! ||||||||||||||||||!!!!!!!!!:::::::::::::::!!!!!|||||||| |
|||
::::::::::::!!!| |||||||||||||||||||!!!!!!!!!:::::::::::::!!!!!!|||||||| |
|||
!'::::::::!!! ||||||||||||||||||!!!!!!!!!!!:::::::::!!!!!!!||||||||||| |
|||
||! .:::!!!!. ||||||||||||||||||||!!!!!!!!!!!!!:::!!!!!!!!!|||||||||| |
|||
| | |||||||||||||||||||!!!!!!!!!!!!!!!!!!!!!!!!|||||||||| |
|||
| |||||||||||||||||||||!!!!!!!!!!!!!!!!!!!!!!||||||||||| |
|||
.||||||||||||||||||||!!!!!!!!!!!!!!!!!!!!|||||||||||| |
|||
||||||||||||||||||||||!!!!!!!!!!!!!!!!||||||||||||| . |
|||
|||||||||||||||||||||||||!!!!!!!!!!!!|||||||||||||||'.' |
|||
|||||||||||||||||||||||||||!!!!||||||||||||||||||| : |
|||
||||||||||||||||||||||||||||||||||||||||||||||||| |
|||
||||||||||||||||||||||||||||||||||||||||||||||| |
|||
||}||||||||||||||||||||||||||||||||||||||||||||| |
|||
|| ||||||||||||||||||||||||||||||||||||||||||||! |
|||
||||||||||||||||||||||||||||||||||||||||||| |
|||
}||||||||||||||||||||||||||||||||||||||||| |
|||
|||||||||||||||||||||||||||||||||||||||:'' |
|||
||||||||||||||||||||||||||||||||||||:'..' |
|||
'':|||||||||||||||||||||||||||||||||| :...' |
|||
'... ||||||||||||||||||||||||||||||| '.': |
|||
..' |||||||||||||||||||||||||||| |
|||
. ' ||||||||||||||||||||||||| |
|||
} ||||||||||||||||||| | |
|||
} ||||||||||| |
|||
|||}} |
|||
}}}}}}} |
|||
}}}}}}}} |
|||
}}}}}}}}}} |
|||
}}}}}}}}}# |
|||
}}}}}}}}} |
|||
}}}}}}}}} |
|||
#}}}}}}}} |
|||
}}}}}}} |
|||
# |
|||
## |
|||
# </pre> |
|||
and a legible variant of the last of the "one-liner" contributions above: |
|||
main = mapM_ putStrLn [[if magnitude (mandelbrot (x :+ y)) < 2 then '*' else ' ' |
|||
<syntaxhighlight lang="haskell">main :: IO () |
|||
| x <- [-2, -1.9685 .. 0.5]] |
|||
main = |
|||
| y <- [1, 0.95 .. -1]]</lang> |
|||
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 ' ' |
|||
] |
|||
]</syntaxhighlight> |
|||
=={{header| |
=={{header|Haxe}}== |
||
This version compiles for flash version 9 or greater. |
This version compiles for flash version 9 or greater. |
||
The compilation command is |
The compilation command is |
||
< |
<syntaxhighlight lang="haxe">haxe -swf mandelbrot.swf -main Mandelbrot</syntaxhighlight> |
||
< |
<syntaxhighlight lang="haxe">class Mandelbrot extends flash.display.Sprite |
||
{ |
{ |
||
inline static var MAX_ITER = 255; |
inline static var MAX_ITER = 255; |
||
Line 575: | Line 7,312: | ||
image.setPixel(x, y, color); |
image.setPixel(x, y, color); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Huginn}}== |
|||
<syntaxhighlight lang="huginn">#! /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 ) ); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<small> |
|||
<pre> |
|||
........................:::::::::::::::::::------------------------------------------------------:::::::::::::::::::::::::::::::::::: |
|||
......................::::::::::::::::------------------------------------++++++++++++++++++++---------:::::::::::::::::::::::::::::: |
|||
....................:::::::::::::-----------------------------------+++++++++++++*******+++++++++++--------:::::::::::::::::::::::::: |
|||
...................:::::::::::----------------------------------++++++++++++++++****%%******++++++++++---------:::::::::::::::::::::: |
|||
.................:::::::::----------------------------------++++++++++++++++++++******% %****++++++++++++---------::::::::::::::::::: |
|||
................::::::::---------------------------------+++++++++++++++++++++******%%%%%*****+++++++++++++----------:::::::::::::::: |
|||
...............::::::---------------------------------++++++++++++++++++++*****%%%%% @%%%@***++++++++++++++----------:::::::::::::: |
|||
..............:::::--------------------------------++++++++++++++++++***********@% @%******+++++++++++++-----------::::::::::: |
|||
.............::::-------------------------------+++++++++++++++++****************@ %%***************+++++------------::::::::: |
|||
............:::------------------------------+++++++++++++++++****@%%%****%@@%@% %%@ @%%%% %*% ********%**++++------------:::::::: |
|||
...........:::----------------------------+++++++++++++++++********% @%@@ %%%**%@%%@@**+++++------------:::::: |
|||
..........:::-------------------------+++++++++++++++++++**********% @ %%***++++++------------::::: |
|||
..........:----------------------+++++++++++++++++++++*********%%%% %%******++++++------------:::: |
|||
.........:-----------------++++++++**************************** %*****+++++-------------::: |
|||
.........----------+++++++++++++++****%********%%*********** @%% % %%**++++++-------------:: |
|||
........:------++++++++++++++++++*******%@@%%**%% %%%*******%% %%***+++++++-------------: |
|||
........---+++++++++++++++++++++********%@ @%%%**% %%***+++++++-------------: |
|||
.......:-+++++++++++++++++++++*******%%%% @%% @****++++++++------------- |
|||
.......-+++++++++++++***********%**@*%@ % %***+++++++++------------- |
|||
.......++++++*******************%% @ %*****+++++++++------------- |
|||
....... %%******++++++++++------------- |
|||
.......++++++*******************%% @ %*****+++++++++------------- |
|||
.......-+++++++++++++***********%**@*%@ % %***+++++++++------------- |
|||
.......:-+++++++++++++++++++++*******%%%% @%% @****++++++++------------- |
|||
........---+++++++++++++++++++++********%@ @%%%**% %%***+++++++-------------: |
|||
........:------++++++++++++++++++*******%@@%%**%% %%%*******%% %%***+++++++-------------: |
|||
.........----------+++++++++++++++****%********%%*********** @%% % %%**++++++-------------:: |
|||
.........:-----------------++++++++**************************** %*****+++++-------------::: |
|||
..........:----------------------+++++++++++++++++++++*********%%%% %%******++++++------------:::: |
|||
..........:::-------------------------+++++++++++++++++++**********% @ %%***++++++------------::::: |
|||
...........:::----------------------------+++++++++++++++++********% @%@@ %%%**%@%%@@**+++++------------:::::: |
|||
............:::------------------------------+++++++++++++++++****@%%%****%@@%@% %%@ @%%%% %*% ********%**++++------------:::::::: |
|||
.............::::-------------------------------+++++++++++++++++****************@ %%***************+++++------------::::::::: |
|||
..............:::::--------------------------------++++++++++++++++++***********@% @%******+++++++++++++-----------::::::::::: |
|||
...............::::::---------------------------------++++++++++++++++++++*****%%%%% @%%%@***++++++++++++++----------:::::::::::::: |
|||
................::::::::---------------------------------+++++++++++++++++++++******%%%%%*****+++++++++++++----------:::::::::::::::: |
|||
.................:::::::::----------------------------------++++++++++++++++++++******% %****++++++++++++---------::::::::::::::::::: |
|||
...................:::::::::::----------------------------------++++++++++++++++****%%******++++++++++---------:::::::::::::::::::::: |
|||
....................:::::::::::::-----------------------------------+++++++++++++*******+++++++++++--------:::::::::::::::::::::::::: |
|||
......................::::::::::::::::------------------------------------++++++++++++++++++++---------:::::::::::::::::::::::::::::: |
|||
</pre> |
|||
</small> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
|||
<syntaxhighlight lang="icon">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</syntaxhighlight> |
|||
{{libheader|Icon Programming Library}} |
|||
[http://www.cs.arizona.edu/icon/library/src/gprocs/graphics.icn graphics is required ] |
|||
{{improve|Unicon|The example is correct; however, Unicon implemented additional graphical features and a better example may be possible.}} |
|||
=={{header|IDL}}== |
=={{header|IDL}}== |
||
Line 581: | Line 7,474: | ||
(free implementation: GDL - GNU Data Language |
(free implementation: GDL - GNU Data Language |
||
http://gnudatalanguage.sourceforge.net) |
http://gnudatalanguage.sourceforge.net) |
||
<syntaxhighlight lang="idl"> |
|||
<lang IDL> |
|||
PRO Mandelbrot,xRange,yRange,xPixels,yPixels,iterations |
PRO Mandelbrot,xRange,yRange,xPixels,yPixels,iterations |
||
Line 628: | Line 7,521: | ||
END |
END |
||
</syntaxhighlight> |
|||
</lang> |
|||
from the command line: |
from the command line: |
||
<syntaxhighlight lang="idl"> |
|||
<lang IDL> |
|||
GDL>.run mandelbrot |
GDL>.run mandelbrot |
||
</syntaxhighlight> |
|||
</lang> |
|||
or |
or |
||
<syntaxhighlight lang="idl"> |
|||
<lang IDL> |
|||
GDL> Mandelbrot,[-1.,2.3],[-1.3,1.3],640,512,200 |
GDL> Mandelbrot,[-1.,2.3],[-1.3,1.3],640,512,200 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Inform 7}}== |
|||
{{libheader|Glimmr Drawing Commands by Erik Temple}} |
|||
{{works with|Glulx virtual machine}} |
|||
<syntaxhighlight lang="inform7">"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; |
|||
-).</syntaxhighlight> |
|||
Newer Glulx interpreters provide 32-bit floating-point operations, but this solution also supports fixed-point math which is more widely supported and accurate enough for a zoomed-out view. Inform 6 inclusions are used for the low-level math functions in either case. The rendering process is extremely slow, since the graphics system is not optimized for pixel-by-pixel drawing, so this solution includes an optimization for vertical symmetry (as in the default view) and also includes extra logic to draw the lines in a more immediately useful order. |
|||
[[File:Mandelbrot-Inform7.png]] |
|||
=={{Header|Insitux}}== |
|||
<syntaxhighlight lang="insitux"> |
|||
(function mandelbrot width height depth |
|||
(.. str |
|||
(for yy (range height) |
|||
xx (range width) |
|||
(let c_re (/ (* (- xx (/ width 2)) 4) width) |
|||
c_im (/ (* (- yy (/ height 2)) 4) width) |
|||
x 0 y 0 i 0) |
|||
(while (and (<= (+ (** x) (** y)) 4) |
|||
(< i depth)) |
|||
(let x2 (+ c_re (- (** x) (** y))) |
|||
y (+ c_im (* 2 x y)) |
|||
x x2 |
|||
i (inc i))) |
|||
(strn ((zero? xx) "\n") (i "ABCDEFGHIJ "))))) |
|||
(mandelbrot 48 24 10) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
BBBBCCCDDDDDDDDDEEEEFGJJ EEEDDCCCCCCCCCCCCCCCBBB |
|||
BBBCCDDDDDDDDDDEEEEFFH HFEEEDDDCCCCCCCCCCCCCCBB |
|||
BBBCDDDDDDDDDDEEEEFFH GFFEEDDDCCCCCCCCCCCCCBB |
|||
BBCCDDDDDDDDDEEEEGGHI HGFFEDDDCCCCCCCCCCCCCCB |
|||
BBCDDDDDDDDEEEEFG HIGEDDDCCCCCCCCCCCCCB |
|||
BBDDDDDDDDEEFFFGH IEDDDDCCCCCCCCCCCCB |
|||
BCDDDDDDEEFFFFGG GFEDDDCCCCCCCCCCCCC |
|||
BDDDDDEEFJGGGHHI IFEDDDDCCCCCCCCCCCC |
|||
BDDEEEEFG J JI GEDDDDCCCCCCCCCCCC |
|||
BDEEEFFFHJ FEDDDDCCCCCCCCCCCC |
|||
BEEEFFFIJ FEEDDDCCCCCCCCCCCC |
|||
BEEFGGH HFEEDDDCCCCCCCCCCCC |
|||
JGFEEDDDDCCCCCCCCCCC |
|||
BEEFGGH HFEEDDDCCCCCCCCCCCC |
|||
BEEEFFFIJ FEEDDDCCCCCCCCCCCC |
|||
BDEEEFFFHJ FEDDDDCCCCCCCCCCCC |
|||
BDDEEEEFG J JI GEDDDDCCCCCCCCCCCC |
|||
BDDDDDEEFJGGGHHI IFEDDDDCCCCCCCCCCCC |
|||
BCDDDDDDEEFFFFGG GFEDDDCCCCCCCCCCCCC |
|||
BBDDDDDDDDEEFFFGH IEDDDDCCCCCCCCCCCCB |
|||
BBCDDDDDDDDEEEEFG HIGEDDDCCCCCCCCCCCCCB |
|||
BBCCDDDDDDDDDEEEEGGHI HGFFEDDDCCCCCCCCCCCCCCB |
|||
BBBCDDDDDDDDDDEEEEFFH GFFEEDDDCCCCCCCCCCCCCBB |
|||
BBBCCDDDDDDDDDDEEEEFFH HFEEEDDDCCCCCCCCCCCCCCBB |
|||
</pre> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
The characteristic function of the Mandelbrot can be defined as follows: |
The characteristic function of the Mandelbrot can be defined as follows: |
||
< |
<syntaxhighlight lang="j">mcf=. (<: 2:)@|@(] ((*:@] + [)^:((<: 2:)@|@])^:1000) 0:) NB. 1000 iterations test</syntaxhighlight> |
||
The Mandelbrot set can be drawn as follows: |
The Mandelbrot set can be drawn as follows: |
||
< |
<syntaxhighlight lang="j">domain=. |.@|:@({.@[ + ] *~ j./&i.&>/@+.@(1j1 + ] %~ -~/@[))&>/ |
||
load 'viewmat' |
|||
viewmat mcf "0 @ domain (_2j_1 1j1) ; 0.01 NB. Complex interval and resolution</syntaxhighlight> |
|||
A smaller version, based on a black&white implementation of viewmat (and paraphrased, from html markup to wiki markup), is shown [[Mandelbrot_set/J/Output|here]] (The output is HTML-heavy and was split out to make editing this page easier): |
|||
<syntaxhighlight lang="j"> viewmat mcf "0 @ domain (_2j_1 1j1) ; 0.1 NB. Complex interval and resolution</syntaxhighlight> |
|||
=={{header|Java}}== |
|||
{{libheader|Swing}} {{libheader|AWT}} |
|||
<syntaxhighlight lang="java">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); |
|||
} |
|||
}</syntaxhighlight> |
|||
=== Interactive === |
|||
{{libheader|AWT}} {{libheader|Swing}} |
|||
<syntaxhighlight lang="java">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) |
|||
; |
|||
} |
|||
}</syntaxhighlight> |
|||
=={{header|JavaScript}}== |
|||
{{works with|Firefox|3.5.11}} |
|||
This needs the canvas tag of HTML 5 (it will not run on IE8 and lower or old browsers). |
|||
The code can be run directly from the Javascript console in modern browsers by copying and pasting it. |
|||
<syntaxhighlight lang="javascript">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);</syntaxhighlight> |
|||
{{out}} with default parameters: |
|||
[[File:Mandelbrot-Javascript.png]] |
|||
=== ES6/WebAssembly === |
|||
With ES6 and WebAssembly, the program can run faster. Of course, this requires a compiled WASM file, but one can easily build |
|||
one for instance with the [https://mbebenita.github.io/WasmExplorer/ WebAssembly explorer] |
|||
<syntaxhighlight lang="javascript">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); |
|||
// ... |
|||
}</syntaxhighlight> |
|||
=={{header|jq}}== |
|||
[[Image:Mandelbrot-Javascript.png|thumb|Thumbnail of SVG produced by jq program]] |
|||
{{Works with|jq|1.4}} |
|||
The Mandelbrot function as defined here is similar to the JavaScript |
|||
implementation but generates SVG. The resulting picture is the same. |
|||
'''Preliminaries''' |
|||
<syntaxhighlight lang="jq"># 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; |
|||
</syntaxhighlight><syntaxhighlight lang="jq"> |
|||
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>";</syntaxhighlight> |
|||
'''Example''': |
|||
<syntaxhighlight lang="jq"> Mandelbrot( {"xmin": -2, "xmax": 1, "ymin": -1, "ymax":1}; 900; 600; 1000 ) </syntaxhighlight> |
|||
'''Execution:''' |
|||
<pre> |
|||
$ jq -n -r -f mandelbrot.jq > mandelbrot.svg |
|||
</pre> |
|||
The output can be viewed in a web browser such as Chrome, Firefox, or Safari. |
|||
=={{header|Julia}}== |
|||
Generates an ASCII representation: |
|||
<syntaxhighlight lang="julia">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</syntaxhighlight> |
|||
This generates a PNG image file: |
|||
<syntaxhighlight lang="julia">using Images |
|||
@inline function hsv2rgb(h, s, v) |
|||
c = v * s |
|||
x = c * (1 - abs(((h/60) % 2) - 1)) |
|||
m = v - c |
|||
r,g,b = if h < 60 (c, x, 0) |
|||
elseif h < 120 (x, c, 0) |
|||
elseif h < 180 (0, c, x) |
|||
elseif h < 240 (0, x, c) |
|||
elseif h < 300 (x, 0, c) |
|||
else (c, 0, x) end |
|||
(r + m), (b + m), (g + m) |
|||
end |
|||
function mandelbrot() |
|||
w = 1600 |
|||
h = 1200 |
|||
zoom = 0.5 |
|||
moveX = -0.5 |
|||
moveY = 0 |
|||
maxIter = 30 |
|||
img = Array{RGB{Float64},2}(undef,h,w) |
|||
for x in 1:w |
|||
for y in 1:h |
|||
i = maxIter |
|||
z = c = Complex( (2*x - w) / (w * zoom) + moveX, |
|||
(2*y - h) / (h * zoom) + moveY ) |
|||
while abs(z) < 2 && (i -= 1) > 0 |
|||
z = z^2 + c |
|||
end |
|||
r,g,b = hsv2rgb(i / maxIter * 360, 1, i / maxIter) |
|||
img[y,x] = RGB{Float64}(r, g, b) |
|||
end |
|||
end |
|||
return img |
|||
end |
|||
img = mandelbrot() |
|||
save("mandelbrot.png", img)</syntaxhighlight> |
|||
===Mandelbrot Set with Julia Animation=== |
|||
This is an extension of the corresponding R section: e^(-|z|)-smoothing was added. See Javier Barrallo & Damien M. Jones: Coloring Algorithms for Dynamical Systems in the Complex Plane ([http://www.mi.sanu.ac.rs/vismath/javier/b3.htm ''II. Distance Estimators'']). |
|||
<syntaxhighlight lang="julia">using Plots |
|||
gr(aspect_ratio=:equal, legend=false, axis=false, ticks=false, dpi=100) |
|||
d, h = 400, 300 # pixel density (= image width) and image height |
|||
n, r = 40, 1000 # number of iterations and escape radius (r > 2) |
|||
x = range(-1.0, 1.0, length=d+1) |
|||
y = range(-h/d, h/d, length=h+1) |
|||
C = 2.0 .* (x' .+ y .* im) .- 0.5 |
|||
Z, S = zero(C), zeros(size(C)) |
|||
animation = Animation() |
|||
smoothing = Animation() |
|||
for k in 1:n |
|||
M = abs.(Z) .< r |
|||
S[M] = S[M] .+ exp.(.-abs.(Z[M])) |
|||
Z[M] = Z[M] .^ 2 .+ C[M] |
|||
heatmap(exp.(.-abs.(Z)), c=:jet) |
|||
frame(animation) |
|||
heatmap(S .+ exp.(.-abs.(Z)), c=:jet) |
|||
frame(smoothing) |
|||
end |
|||
gif(animation, "Mandelbrot_animation.gif", fps=2) |
|||
gif(smoothing, "Mandelbrot_smoothing.gif", fps=2)</syntaxhighlight> |
|||
===Normal Map Effect, Mercator Projection and Perturbation Theory=== |
|||
'''Normalization, Distance Estimation and Boundary Detection''' |
|||
This is a translation of the corresponding Python section: see there for more explanations. The ''e^(-|z|)-smoothing'', ''normalized iteration count'' and ''exterior distance estimation'' algorithms are used. Partial antialiasing is used for boundary detection. |
|||
<syntaxhighlight lang="julia">using Plots |
|||
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200) |
|||
d, h = 800, 500 # pixel density (= image width) and image height |
|||
n, r = 200, 500 # number of iterations and escape radius (r > 2) |
|||
x = range(0, 2, length=d+1) |
|||
y = range(0, 2 * h / d, length=h+1) |
|||
A, B = collect(x) .- 1, collect(y) .- h / d |
|||
C = 2.0 .* (A' .+ B .* im) .- 0.5 |
|||
Z, dZ = zero(C), zero(C) |
|||
D, S, T = zeros(size(C)), zeros(size(C)), zeros(size(C)) |
|||
for k in 1:n |
|||
M = abs.(Z) .< r |
|||
S[M], T[M] = S[M] .+ exp.(.- abs.(Z[M])), T[M] .+ 1 |
|||
Z[M], dZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1 |
|||
end |
|||
heatmap(S .^ 0.1, c=:balance) |
|||
savefig("Mandelbrot_set_1.png") |
|||
N = abs.(Z) .>= r # normalized iteration count |
|||
T[N] = T[N] .- log2.(log.(abs.(Z[N])) ./ log(r)) |
|||
heatmap(T .^ 0.1, c=:balance) |
|||
savefig("Mandelbrot_set_2.png") |
|||
N = abs.(Z) .> 2 # exterior distance estimation |
|||
D[N] = log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N]) |
|||
heatmap(D .^ 0.1, c=:balance) |
|||
savefig("Mandelbrot_set_3.png") |
|||
N, thickness = D .> 0, 0.01 # boundary detection |
|||
D[N] = max.(1 .- D[N] ./ thickness, 0) |
|||
heatmap(D .^ 2.0, c=:binary) |
|||
savefig("Mandelbrot_set_4.png")</syntaxhighlight> |
|||
'''Normal Map Effect and Stripe Average Coloring''' |
|||
The Mandelbrot set is represented using Normal Maps and Stripe Average Coloring by Jussi Härkönen (cf. Arnaud Chéritat: [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Normal_map_effect ''Normal map effect'']). See also the picture in section [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Mixing_it_all ''Mixing it all''] and [https://www.shadertoy.com/view/wtscDX Julia Stripes] on Shadertoy. To get a stripe pattern similar to that of Arnaud Chéritat, one can increase the ''density'' of the stripes, use ''cos'' instead of ''sin'', and set the colormap to ''binary''. |
|||
<syntaxhighlight lang="julia">using Plots |
|||
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200) |
|||
d, h = 800, 500 # pixel density (= image width) and image height |
|||
n, r = 200, 500 # number of iterations and escape radius (r > 2) |
|||
direction, height = 45.0, 1.5 # direction and height of the light |
|||
density, intensity = 4.0, 0.5 # density and intensity of the stripes |
|||
x = range(0, 2, length=d+1) |
|||
y = range(0, 2 * h / d, length=h+1) |
|||
A, B = collect(x) .- 1, collect(y) .- h / d |
|||
C = (2.0 + 1.0im) .* (A' .+ B .* im) .- 0.5 |
|||
Z, dZ, ddZ = zero(C), zero(C), zero(C) |
|||
D, S, T = zeros(size(C)), zeros(size(C)), zeros(size(C)) |
|||
for k in 1:n |
|||
M = abs.(Z) .< r |
|||
S[M], T[M] = S[M] .+ sin.(density .* angle.(Z[M])), T[M] .+ 1 |
|||
Z[M], dZ[M], ddZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1, 2 .* (dZ[M] .^ 2 .+ Z[M] .* ddZ[M]) |
|||
end |
|||
N = abs.(Z) .>= r # basic normal map effect and stripe average coloring (potential function) |
|||
P, Q = S[N] ./ T[N], (S[N] .+ sin.(density .* angle.(Z[N]))) ./ (T[N] .+ 1) |
|||
U, V = Z[N] ./ dZ[N], 1 .+ (log2.(log.(abs.(Z[N])) ./ log(r)) .* (P .- Q) .+ Q) .* intensity |
|||
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit normal vectors and light vector |
|||
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ V .* height) ./ (1 + height), 0) |
|||
heatmap(D .^ 1.0, c=:bone_1) |
|||
savefig("Mandelbrot_normal_map_1.png") |
|||
N = abs.(Z) .> 2 # advanced normal map effect using higher derivatives (distance estimation) |
|||
U = Z[N] .* dZ[N] .* ((1 .+ log.(abs.(Z[N]))) .* conj.(dZ[N] .^ 2) .- log.(abs.(Z[N])) .* conj.(Z[N] .* ddZ[N])) |
|||
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit normal vectors and light vector |
|||
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ height) ./ (1 + height), 0) |
|||
heatmap(D .^ 1.0, c=:afmhot) |
|||
savefig("Mandelbrot_normal_map_2.png")</syntaxhighlight> |
|||
'''Mercator Mandelbrot Maps and Zoom Images''' |
|||
A small change in the code above creates Mercator maps and zoom images of the Mandelbrot set. See also the album [https://www.flickr.com/photos/arenamontanus/albums/72157615740829949 Mercator Mandelbrot Maps] by Anders Sandberg and [https://commons.wikimedia.org/wiki/File:Mandelbrot_sequence_new.gif ''Mandelbrot sequence new''] on Wikimedia for a zoom animation to the given coordinates. |
|||
<syntaxhighlight lang="julia">using Plots |
|||
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200) |
|||
d, h = 200, 1200 # pixel density (= image width) and image height |
|||
n, r = 8000, 10000 # number of iterations and escape radius (r > 2) |
|||
a = -.743643887037158704752191506114774 # https://mathr.co.uk/web/m-location-analysis.html |
|||
b = 0.131825904205311970493132056385139 # try: a, b, n = -1.748764520194788535, 3e-13, 800 |
|||
x = range(0, 2, length=d+1) |
|||
y = range(0, 2 * h / d, length=h+1) |
|||
A, B = collect(x) .* pi, collect(y) .* pi |
|||
C = 8.0 .* exp.((A' .+ B .* im) .* im) .+ (a + b * im) |
|||
Z, dZ = zero(C), zero(C) |
|||
D = zeros(size(C)) |
|||
for k in 1:n |
|||
M = abs2.(Z) .< abs2(r) |
|||
Z[M], dZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1 |
|||
end |
|||
N = abs.(Z) .> 2 # exterior distance estimation |
|||
D[N] = log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N]) |
|||
heatmap(D' .^ 0.05, c=:nipy_spectral) |
|||
savefig("Mercator_Mandelbrot_map.png") |
|||
X, Y = real(C), imag(C) # zoom images (adjust circle size 50 and zoom level 20 as needed) |
|||
R, c, z = 50 * (2 / d) * pi .* exp.(.- B), min(d, h) + 1, max(0, h - d) ÷ 20 |
|||
gr(c=:nipy_spectral, axis=true, ticks=true, legend=false, markerstrokewidth=0) |
|||
p1 = scatter(X[1z+1:1z+c,1:d], Y[1z+1:1z+c,1:d], markersize=R[1:c].^.5, marker_z=D[1z+1:1z+c,1:d].^.5) |
|||
p2 = scatter(X[2z+1:2z+c,1:d], Y[2z+1:2z+c,1:d], markersize=R[1:c].^.5, marker_z=D[2z+1:2z+c,1:d].^.4) |
|||
p3 = scatter(X[3z+1:3z+c,1:d], Y[3z+1:3z+c,1:d], markersize=R[1:c].^.5, marker_z=D[3z+1:3z+c,1:d].^.3) |
|||
p4 = scatter(X[4z+1:4z+c,1:d], Y[4z+1:4z+c,1:d], markersize=R[1:c].^.5, marker_z=D[4z+1:4z+c,1:d].^.2) |
|||
plot(p1, p2, p3, p4, layout=(2, 2)) |
|||
savefig("Mercator_Mandelbrot_zoom.png")</syntaxhighlight> |
|||
'''Perturbation Theory and Deep Mercator Maps''' |
|||
For deep zoom images it is sufficient to calculate a single point with high accuracy. A good approximation can then be found for all other points by means of a perturbation calculation with standard accuracy. Rebasing is used to reduce glitches. See [https://fractalforums.org/fractal-mathematics-and-new-theories/28/another-solution-to-perturbation-glitches/4360 Another solution to perturbation glitches] (Fractalforums) for details. See also the image [https://www.flickr.com/photos/arenamontanus/3430921497/in/album-72157615740829949/ Deeper Mercator Mandelbrot] by Anders Sandberg. |
|||
<syntaxhighlight lang="julia">using Plots |
|||
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200) |
|||
setprecision(BigFloat, 256) # set precision to 256 bits (default) |
|||
setrounding(BigFloat, RoundNearest) # set rounding mode (default) |
|||
d, h = 50, 1000 # pixel density (= image width) and image height |
|||
n, r = 80000, 100000 # number of iterations and escape radius (r > 2) |
|||
a = BigFloat("-1.256827152259138864846434197797294538253477389787308085590211144291") |
|||
b = BigFloat(".37933802890364143684096784819544060002129071484943239316486643285025") |
|||
S = zeros(Complex{Float64}, n+1) |
|||
let c = a + b * im, z = zero(c) |
|||
for k in 1:n+1 |
|||
S[k] = z |
|||
if abs2(z) < abs2(r) |
|||
z = z ^ 2 + c |
|||
else |
|||
println("The reference sequence diverges within $(k-1) iterations.") |
|||
break |
|||
end |
|||
end |
|||
end |
|||
x = range(0, 2, length=d+1) |
|||
y = range(0, 2 * h / d, length=h+1) |
|||
A, B = collect(x) .* pi, collect(y) .* pi |
|||
C = 8.0 .* exp.((A' .+ B .* im) .* im) |
|||
E, Z, dZ = zero(C), zero(C), zero(C) |
|||
D, I, J = zeros(size(C)), ones(Int64, size(C)), ones(Int64, size(C)) |
|||
for k in 1:n |
|||
M, R = abs2.(Z) .< abs2(r), abs2.(Z) .< abs2.(E) |
|||
E[R], I[R] = Z[R], J[R] # rebase when z is closer to zero |
|||
E[M], I[M] = (2 .* S[I[M]] .+ E[M]) .* E[M] .+ C[M], I[M] .+ 1 |
|||
Z[M], dZ[M] = S[I[M]] .+ E[M], 2 .* Z[M] .* dZ[M] .+ 1 |
|||
end |
|||
N = abs.(Z) .> 2 # exterior distance estimation |
|||
D[N] = log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N]) |
|||
heatmap(D' .^ 0.015, c=:nipy_spectral) |
|||
savefig("Mercator_Mandelbrot_deep_map.png")</syntaxhighlight> |
|||
=={{header|Kotlin}}== |
|||
{{trans|Java}} |
|||
<syntaxhighlight lang="scala">// version 1.1.2 |
|||
import java.awt.Graphics |
|||
import java.awt.image.BufferedImage |
|||
import javax.swing.JFrame |
|||
class Mandelbrot: JFrame("Mandelbrot Set") { |
|||
companion object { |
|||
private const val MAX_ITER = 570 |
|||
private const val ZOOM = 150.0 |
|||
} |
|||
private val img: BufferedImage |
|||
init { |
|||
setBounds(100, 100, 800, 600) |
|||
isResizable = false |
|||
defaultCloseOperation = EXIT_ON_CLOSE |
|||
img = BufferedImage(width, height, BufferedImage.TYPE_INT_RGB) |
|||
for (y in 0 until height) { |
|||
for (x in 0 until width) { |
|||
var zx = 0.0 |
|||
var zy = 0.0 |
|||
val cX = (x - 400) / ZOOM |
|||
val cY = (y - 300) / ZOOM |
|||
var iter = MAX_ITER |
|||
while (zx * zx + zy * zy < 4.0 && iter > 0) { |
|||
val tmp = zx * zx - zy * zy + cX |
|||
zy = 2.0 * zx * zy + cY |
|||
zx = tmp |
|||
iter-- |
|||
} |
|||
img.setRGB(x, y, iter or (iter shl 7)) |
|||
} |
|||
} |
|||
} |
|||
override fun paint(g: Graphics) { |
|||
g.drawImage(img, 0, 0, this) |
|||
} |
|||
} |
|||
fun main(args: Array<String>) { |
|||
Mandelbrot().isVisible = true |
|||
}</syntaxhighlight> |
|||
=={{header|LabVIEW}}== |
|||
{{works with|LabVIEW|8.0 Full Development Suite}}<br/><br/> |
|||
[[File:Mandelbrot_set_diagram.png|800px]] |
|||
[[File:Mandelbrot_set_panel.png|400px]] |
|||
=={{header|Lang5}}== |
|||
<syntaxhighlight lang="lang5"> |
|||
: d2c(*,*) 2 compress 'c dress ; # Make a complex number. |
|||
: iterate(c) [0 0](c) "dup * over +" steps reshape execute ; |
|||
: print_line(*) "#*+-. " "" split swap subscript "" join . "\n" . ; |
|||
75 iota 45 - 20 / # x coordinates |
|||
29 iota 14 - 10 / # y cordinates |
|||
'd2c outer # Make complex matrix. |
|||
10 'steps set # How many iterations? |
|||
iterate abs int 5 min 'print_line apply # Compute & print |
|||
</syntaxhighlight> |
|||
=={{header|Lambdatalk}}== |
|||
Lambdatalk working in any web browser has access to javascript and could draw the mandelbrot set very quickly in a canvas, for instance here: |
|||
- http: // lambdaway.free.fr/lambdawalks/?view=mandel_canvas |
|||
Here we show a pure lambdatalk code, a slow but minimalistic and easy to understand version without the burden of any canvas. We just compute if a point is inside or outside the mandelbrot set and just write "o" or "." directly in the wiki page. |
|||
<syntaxhighlight lang="scheme"> |
|||
{def mandel |
|||
{def mandel.r |
|||
{lambda {:iter :cx :cy :norm :x :y :count} |
|||
{if {> :count :iter} // then norm < 4 |
|||
then o // inside the set |
|||
else {if {> :norm 4} // then iter > max |
|||
then . // outside the set |
|||
else {let { {:cx :cx} {:cy :cy} {:iter :iter} |
|||
{:X {+ {* :x :x} -{* :y :y} :cx}} // compute |
|||
{:Y {+ {* 2 :x :y} :cy}} // z = z^2+c |
|||
{:count {+ :count 1}} |
|||
} {mandel.r :iter :cx :cy |
|||
{+ {* :X :X} {* :Y :Y}} // the norm |
|||
:X :Y :count} }}}}} |
|||
{lambda {:iter :cx :cy} |
|||
{mandel.r :iter |
|||
{+ {* :cx 0.05} -1.50} // centering the set |
|||
{+ {* :cy 0.05} -0.75} // inside the frame |
|||
0 0 0 0} }} |
|||
-> mandel |
|||
We call mandel directly in the wiki page |
|||
{S.map {lambda {:i} {br} // loop on y |
|||
{S.map {{lambda {:i :j} // loop on x |
|||
{mandel 20 :i :j}} :i} // compute |
|||
{S.serie 0 30}}} // x resolution |
|||
{S.serie 0 40}} // y resolution |
|||
</syntaxhighlight> |
|||
<pre> |
|||
. . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . |
|||
. . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . |
|||
. . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . |
|||
. . . . . . . . . . . . . . o o o . . . . . . . . . . . . . . |
|||
. . . . . . . . . . . . . . o o o . . . . . . . . . . . . . . |
|||
. . . . . . . . . . . . . o o o o o . . . . . . . . . . . . . |
|||
. . . . . . . . . . . . o o o o o o o . . . . . . . . . . . . |
|||
. . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . |
|||
. . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . |
|||
. . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . |
|||
. . . . . . . . . o o o o o o o o o o o o o . . . . . . . . . |
|||
. . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . |
|||
. . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . |
|||
. . . . . . . . . . . o o o o o o o o o . . . . . . . . . . . |
|||
. . . . . . . . . . . . o o o o o o o . . . . . . . . . . . . |
|||
. . . . . . . . . . . . o o o o o o o . . . . . . . . . . . . |
|||
. . . . . . o . o o o o o o o o o o o o o o o . o . . . . . . |
|||
. . . . . . o . o o o o o o o o o o o o o o o . o . . . . . . |
|||
. . . . . . o o o o o o o o o o o o o o o o o o o . . . . . . |
|||
. . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . |
|||
. . . o o o o o o o o o o o o o o o o o o o o o o o o o . . . |
|||
. . . . o o o o o o o o o o o o o o o o o o o o o o o . . . . |
|||
. . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . |
|||
. . . o o o o o o o o o o o o o o o o o o o o o o o o o . . . |
|||
. . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . |
|||
o . o o o o o o o o o o o o o o o o o o o o o o o o o o o . o |
|||
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o |
|||
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o |
|||
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o |
|||
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o |
|||
o . o o o o o o o o o o o o o o o o o o o o o o o o o o o . o |
|||
. . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . |
|||
. . . o o o o o o o o o o o o o o o o o o o o o o o o o . . . |
|||
. . o . o o o o o o o o o o o o o o o o o o o o o o o . o . . |
|||
. . . . o o o o o o o o o o o o o o o o o o o o o o o . . . . |
|||
. . . . o o o o o o o o o o o o o o o o o o o o o o o . . . . |
|||
. . . . o o o o o o o o o o o . o o o o o o o o o o o . . . . |
|||
. . . . o . . . o o o o o o . . . o o o o o o . . . o . . . . |
|||
. . . . . . . . o . . o o . . . . . o o . . o . . . . . . . . |
|||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
|||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
|||
</pre> |
|||
=={{header|Lasso}}== |
|||
<syntaxhighlight lang="lasso"> |
|||
define mandelbrotBailout => 16 |
|||
define mandelbrotMaxIterations => 1000 |
|||
define mandelbrotIterate(x, y) => { |
|||
local(cr = #y - 0.5, |
|||
ci = #x, |
|||
zi = 0.0, |
|||
zr = 0.0, |
|||
i = 0, |
|||
temp, zr2, zi2) |
|||
{ |
|||
++#i; |
|||
#temp = #zr * #zi |
|||
#zr2 = #zr * #zr |
|||
#zi2 = #zi * #zi |
|||
#zi2 + #zr2 > mandelbrotBailout? |
|||
return #i |
|||
#i > mandelbrotMaxIterations? |
|||
return 0 |
|||
#zr = #zr2 - #zi2 + #cr |
|||
#zi = #temp + #temp + #ci |
|||
currentCapture->restart |
|||
}() |
|||
} |
|||
define mandelbrotTest() => { |
|||
local(x, y = -39.0) |
|||
{ |
|||
stdout('\n') |
|||
#x = -39.0 |
|||
{ |
|||
mandelbrotIterate(#x / 40.0, #y / 40.0) == 0? |
|||
stdout('*') |
|||
| stdout(' '); |
|||
++#x |
|||
#x <= 39.0? |
|||
currentCapture->restart |
|||
}(); |
|||
++#y |
|||
#y <= 39.0? |
|||
currentCapture->restart |
|||
}() |
|||
stdout('\n') |
|||
} |
|||
mandelbrotTest |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<small> |
|||
<pre> |
|||
* |
|||
* |
|||
* |
|||
* |
|||
* |
|||
*** |
|||
***** |
|||
***** |
|||
*** |
|||
* |
|||
********* |
|||
************* |
|||
*************** |
|||
********************* |
|||
********************* |
|||
******************* |
|||
******************* |
|||
******************* |
|||
******************* |
|||
*********************** |
|||
******************* |
|||
******************* |
|||
********************* |
|||
******************* |
|||
******************* |
|||
***************** |
|||
*************** |
|||
************* |
|||
********* |
|||
* |
|||
*************** |
|||
*********************** |
|||
* ************************* * |
|||
***************************** |
|||
* ******************************* * |
|||
********************************* |
|||
*********************************** |
|||
*************************************** |
|||
*** ***************************************** *** |
|||
************************************************* |
|||
*********************************************** |
|||
********************************************* |
|||
********************************************* |
|||
*********************************************** |
|||
*********************************************** |
|||
*************************************************** |
|||
************************************************* |
|||
************************************************* |
|||
*************************************************** |
|||
*************************************************** |
|||
* *************************************************** * |
|||
***** *************************************************** ***** |
|||
****** *************************************************** ****** |
|||
******* *************************************************** ******* |
|||
*********************************************************************** |
|||
********* *************************************************** ********* |
|||
****** *************************************************** ****** |
|||
***** *************************************************** ***** |
|||
*************************************************** |
|||
*************************************************** |
|||
*************************************************** |
|||
*************************************************** |
|||
************************************************* |
|||
************************************************* |
|||
*************************************************** |
|||
*********************************************** |
|||
*********************************************** |
|||
******************************************* |
|||
***************************************** |
|||
********************************************* |
|||
**** ****************** ****************** **** |
|||
*** **************** **************** *** |
|||
* ************** ************** * |
|||
*********** *********** |
|||
** ***** ***** ** |
|||
* * * * |
|||
</pre> |
|||
</small> |
|||
=={{header|LIL}}== |
|||
From the source distribution. Produces a PBM, not shown here. |
|||
<syntaxhighlight lang="tcl"># |
|||
# A mandelbrot generator that outputs a PBM file. This can be used to measure |
|||
# performance differences between LIL versions and measure performance |
|||
# bottlenecks (although keep in mind that LIL is not supposed to be a fast |
|||
# language, but a small one which depends on C for the slow parts - in a real |
|||
# program where for some reason mandelbrots are required, the code below would |
|||
# be written in C). The code is based on the mandelbrot test for the Computer |
|||
# Language Benchmarks Game at http://shootout.alioth.debian.org/ |
|||
# |
|||
# In my current computer (Intel Core2Quad Q9550 @ 2.83GHz) running x86 Linux |
|||
# the results are (using the default 256x256 size): |
|||
# |
|||
# 2m3.634s - commit 1c41cdf89f4c1e039c9b3520c5229817bc6274d0 (Jan 10 2011) |
|||
# |
|||
# To test call |
|||
# |
|||
# time ./lil mandelbrot.lil > mandelbrot.pbm |
|||
# |
|||
# with an optimized version of lil (compiled with CFLAGS=-O3 make). |
|||
# |
|||
set width [expr $argv] |
|||
if not $width { set width 256 } |
|||
set height $width |
|||
set bit_num 0 |
|||
set byte_acc 0 |
|||
set iter 50 |
|||
set limit 2.0 |
|||
write "P4\n${width} ${height}\n" |
|||
for {set y 0} {$y < $height} {inc y} { |
|||
for {set x 0} {$x < $width} {inc x} { |
|||
set Zr 0.0 Zi 0.0 Tr 0.0 Ti 0.0 |
|||
set Cr [expr 2.0 * $x / $width - 1.5] |
|||
set Ci [expr 2.0 * $y / $height - 1.0] |
|||
for {set i 0} {$i < $iter && $Tr + $Ti <= $limit * $limit} {inc i} { |
|||
set Zi [expr 2.0 * $Zr * $Zi + $Ci] |
|||
set Zr [expr $Tr - $Ti + $Cr] |
|||
set Tr [expr $Zr * $Zr] |
|||
set Ti [expr $Zi * $Zi] |
|||
} |
|||
set byte_acc [expr $byte_acc << 1] |
|||
if [expr $Tr + $Ti <= $limit * $limit] { |
|||
set byte_acc [expr $byte_acc | 1] |
|||
} |
|||
inc bit_num |
|||
if [expr $bit_num == 8] { |
|||
writechar $byte_acc |
|||
set byte_acc 0 |
|||
set bit_num 0 |
|||
} {if [expr $x == $width - 1] { |
|||
set byte_acc [expr 8 - $width % 8] |
|||
writechar $byte_acc |
|||
set byte_acc 0 |
|||
set bit_num 0 |
|||
}} |
|||
} |
|||
}</syntaxhighlight> |
|||
=={{header|Logo}}== |
|||
{{works with|UCB Logo}} |
|||
<syntaxhighlight lang="logo">to mandelbrot :left :bottom :side :size |
|||
cs setpensize [1 1] |
|||
make "inc :side/:size |
|||
make "zr :left |
|||
repeat :size [ |
|||
make "zr :zr + :inc |
|||
make "zi :bottom |
|||
pu |
|||
setxy repcount - :size/2 minus :size/2 |
|||
pd |
|||
repeat :size [ |
|||
make "zi :zi + :inc |
|||
setpencolor count.color calc :zr :zi |
|||
fd 1 ] ] |
|||
end |
|||
to count.color :count |
|||
;op (list :count :count :count) |
|||
if :count > 256 [op 0] ; black |
|||
if :count > 128 [op 7] ; white |
|||
if :count > 64 [op 5] ; magenta |
|||
if :count > 32 [op 6] ; yellow |
|||
if :count > 16 [op 4] ; red |
|||
if :count > 8 [op 2] ; green |
|||
if :count > 4 [op 1] ; blue |
|||
op 3 ; cyan |
|||
end |
|||
to calc :zr :zi [:count 0] [:az 0] [:bz 0] |
|||
if :az*:az + :bz*:bz > 4 [op :count] |
|||
if :count > 256 [op :count] |
|||
op (calc :zr :zi (:count + 1) (:zr + :az*:az - :bz*:bz) (:zi + 2*:az*:bz)) |
|||
end |
|||
mandelbrot -2 -1.25 2.5 400</syntaxhighlight> |
|||
=={{header|Lua}}== |
|||
===Graphical=== |
|||
Needs LÖVE 2D Engine<br />Zoom in: drag the mouse; zoom out: right click |
|||
<syntaxhighlight lang="lua"> |
|||
local maxIterations = 250 |
|||
local minX, maxX, minY, maxY = -2.5, 2.5, -2.5, 2.5 |
|||
local miX, mxX, miY, mxY |
|||
function remap( x, t1, t2, s1, s2 ) |
|||
local f = ( x - t1 ) / ( t2 - t1 ) |
|||
local g = f * ( s2 - s1 ) + s1 |
|||
return g; |
|||
end |
|||
function drawMandelbrot() |
|||
local pts, a, as, za, b, bs, zb, cnt, clr = {} |
|||
for j = 0, hei - 1 do |
|||
for i = 0, wid - 1 do |
|||
a = remap( i, 0, wid, minX, maxX ) |
|||
b = remap( j, 0, hei, minY, maxY ) |
|||
cnt = 0; za = a; zb = b |
|||
while( cnt < maxIterations ) do |
|||
as = a * a - b * b; bs = 2 * a * b |
|||
a = za + as; b = zb + bs |
|||
if math.abs( a ) + math.abs( b ) > 16 then break end |
|||
cnt = cnt + 1 |
|||
end |
|||
if cnt == maxIterations then clr = 0 |
|||
else clr = remap( cnt, 0, maxIterations, 0, 255 ) |
|||
end |
|||
pts[1] = { i, j, clr, clr, 0, 255 } |
|||
love.graphics.points( pts ) |
|||
end |
|||
end |
|||
end |
|||
function startFractal() |
|||
love.graphics.setCanvas( canvas ); love.graphics.clear() |
|||
love.graphics.setColor( 255, 255, 255 ) |
|||
drawMandelbrot(); love.graphics.setCanvas() |
|||
end |
|||
function love.load() |
|||
wid, hei = love.graphics.getWidth(), love.graphics.getHeight() |
|||
canvas = love.graphics.newCanvas( wid, hei ) |
|||
startFractal() |
|||
end |
|||
function love.mousepressed( x, y, button, istouch ) |
|||
if button == 1 then |
|||
startDrag = true; miX = x; miY = y |
|||
else |
|||
minX = -2.5; maxX = 2.5; minY = minX; maxY = maxX |
|||
startFractal() |
|||
startDrag = false |
|||
end |
|||
end |
|||
function love.mousereleased( x, y, button, istouch ) |
|||
if startDrag then |
|||
local l |
|||
if x > miX then mxX = x |
|||
else l = x; mxX = miX; miX = l |
|||
end |
|||
if y > miY then mxY = y |
|||
else l = y; mxY = miY; miY = l |
|||
end |
|||
miX = remap( miX, 0, wid, minX, maxX ) |
|||
mxX = remap( mxX, 0, wid, minX, maxX ) |
|||
miY = remap( miY, 0, hei, minY, maxY ) |
|||
mxY = remap( mxY, 0, hei, minY, maxY ) |
|||
minX = miX; maxX = mxX; minY = miY; maxY = mxY |
|||
startFractal() |
|||
end |
|||
end |
|||
function love.draw() |
|||
love.graphics.draw( canvas ) |
|||
end |
|||
</syntaxhighlight> |
|||
===ASCII=== |
|||
<syntaxhighlight lang="lua">-- Mandelbrot set in Lua 6/15/2020 db |
|||
local charmap = { [0]=" ", ".", ":", "-", "=", "+", "*", "#", "%", "@" } |
|||
for y = -1.3, 1.3, 0.1 do |
|||
for x = -2.1, 1.1, 0.04 do |
|||
local zi, zr, i = 0, 0, 0 |
|||
while i < 100 do |
|||
if (zi*zi+zr*zr >= 4) then break end |
|||
zr, zi, i = zr*zr-zi*zi+x, 2*zr*zi+y, i+1 |
|||
end |
|||
io.write(charmap[i%10]) |
|||
end |
|||
print() |
|||
end</syntaxhighlight> |
|||
{{out}} |
|||
<pre>...............::::::::::::::::::---------------:::::::::::::::::::::::::::::::: |
|||
.............:::::::::::---------------------------------::::::::::::::::::::::: |
|||
...........::::::::---------------------======+#@#++=====-----:::::::::::::::::: |
|||
..........::::::--------------------=======+++**@+@.@*+=====-----::::::::::::::: |
|||
........:::::--------------------========++++*#@@#=:%#*++=====------:::::::::::: |
|||
.......:::--------------------========+++***#%: .:#*+++++===-------::::::::: |
|||
......:::------------------=======+++#%@%%%@@ :# %.@@%#***%*+==------:::::::: |
|||
.....::-----------------====++++++**# = =% %-.*+=#%+==-------:::::: |
|||
.....:--------------==+++++++++****%:.*+ *%*++==-------::::: |
|||
....:--------=====+*#=%##########%%.** .@ +===-------:::: |
|||
....---========++++*#@:=*:-@+ .@@ := @ #*===--------::: |
|||
...--=======+++++*##%.=: @+. @##+====--------:: |
|||
...=======****##% .-=% *#*+====--------:: |
|||
...@.:: :: % :@#*++====--------:: |
|||
...=======****##% .-=% *#*+====--------:: |
|||
...--=======+++++*##%.=: @+. @##+====--------:: |
|||
....---========++++*#@:=*:-@+ .@@ := @ #*===--------::: |
|||
....:--------=====+*#=%##########%%.** .@ +===-------:::: |
|||
.....:--------------==+++++++++****%:.*+ *%*++==-------::::: |
|||
.....::-----------------====++++++**# = =% %-.*+=#%+==-------:::::: |
|||
......:::------------------=======+++#%@%%%@@ :# %.@@%#***%*+==------:::::::: |
|||
.......:::--------------------========+++***#%: .:#*+++++===-------::::::::: |
|||
........:::::--------------------========++++*#@@#=:%#*++=====------:::::::::::: |
|||
..........::::::--------------------=======+++**@+@.@*+=====-----::::::::::::::: |
|||
...........::::::::---------------------======+#@#++=====-----:::::::::::::::::: |
|||
.............:::::::::::---------------------------------::::::::::::::::::::::: |
|||
...............::::::::::::::::::---------------::::::::::::::::::::::::::::::::</pre> |
|||
===ASCII (obfuscated)=== |
|||
Produces an 80x25 ASCII Mandelbrot set, using only two lines of code. The result isn't very high quality because there's only so many iterations you can cram into two lines of 80 columns. And this code cheats, because it starts the iteration count at -15 instead of 0, to avoid the need for an excessively long character lookup table. |
|||
<syntaxhighlight lang="lua">for y=-12,12 do l=""for x=-2,1,3/80 do a,b,n=0,0,-15 while n<9 and a*a+b*b<1e12 |
|||
do a,b,n=a*a-b*b+x,2*a*b+y/8,n+1 end l=l..(".,:;=$%# "):sub(n,n)end print(l)end</syntaxhighlight> |
|||
{{out}} |
|||
<pre>............................................,,,,,,,,............................ |
|||
.................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,................... |
|||
.........................,,,,,,,,,,,,,,,,,,,,,,::::,,,,,,,,,,,,,,,.............. |
|||
...................,,,,,,,,,,,,,,,,,,,,,::::::;=$=;;::::::,,,,,,,,,,,,.......... |
|||
..............,,,,,,,,,,,,,,,,,,,,:::::::::;;;==% :#=;;:::::,,,,,,,,,,,....... |
|||
.........,,,,,,,,,,,,,,,,,,,,:::::::::;;;;;==$%;; ,##==;;;::::::,,,,,,,,,..... |
|||
.....,,,,,,,,,,,,,,,,,:::::::::::;;;;====$$$%#: %$$===;;;;::::,,,,,,,,... |
|||
..,,,,,,,,,,,,,,::::::::::::;;;;;;==$ , .#% #=;:::,,,,,,,,,. |
|||
,,,,,,,,,,,,::::::;;;;;;;;;;=====$$#:. $=;;::::,,,,,,,, |
|||
,,,,,,,,:::::::;;;=%:%%%%%=%%%%%%# $ $;;:::,,,,,,,, |
|||
,,,,:::::::;;;;===$%#: ,.. :,=;;::::,,,,,,, |
|||
::::;;;;;;====$# ..# ;$=;;::::,,,,,,, |
|||
; %$=;;;::::,,,,,,, |
|||
::::;;;;;;====$# ..# ;$=;;::::,,,,,,, |
|||
,,,,:::::::;;;;===$%#: ,.. :,=;;::::,,,,,,, |
|||
,,,,,,,,:::::::;;;=%:%%%%%=%%%%%%# $ $;;:::,,,,,,,, |
|||
,,,,,,,,,,,,::::::;;;;;;;;;;=====$$#:. $=;;::::,,,,,,,, |
|||
..,,,,,,,,,,,,,,::::::::::::;;;;;;==$ , .#% #=;:::,,,,,,,,,. |
|||
.....,,,,,,,,,,,,,,,,,:::::::::::;;;;====$$$%#: %$$===;;;;::::,,,,,,,,... |
|||
.........,,,,,,,,,,,,,,,,,,,,:::::::::;;;;;==$%;; ,##==;;;::::::,,,,,,,,,..... |
|||
..............,,,,,,,,,,,,,,,,,,,,:::::::::;;;==% :#=;;:::::,,,,,,,,,,,....... |
|||
...................,,,,,,,,,,,,,,,,,,,,,::::::;=$=;;::::::,,,,,,,,,,,,.......... |
|||
.........................,,,,,,,,,,,,,,,,,,,,,,::::,,,,,,,,,,,,,,,.............. |
|||
.................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,................... |
|||
............................................,,,,,,,,............................</pre> |
|||
=={{header|M2000 Interpreter}}== |
|||
Console is a bitmap so we can plot on it. A subroutine plot different size of pixels so we get Mandelbrot image at final same size for 32X26 for a big pixel of 16x16 pixels to 512x416 for a 1:1 pixel. Iterations for each pixel set to 25. Module can get left top corner as twips, and the size factor from 1 to 16 (size of output is 512x416 pixels for any factor). |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
Module Mandelbrot(x=0&,y=0&,z=1&) { |
|||
If z<1 then z=1 |
|||
If z>16 then z=16 |
|||
Const iXmax=32*z |
|||
Const iYmax=26*z |
|||
Def single Cx, Cy, CxMin=-2.05, CxMax=0.85, CyMin=-1.2, CyMax=1.2 |
|||
Const PixelWidth=(CxMax-CxMin)/iXmax, iXm=(iXmax-1)*PixelWidth |
|||
Const PixelHeight=(CyMax-CyMin)/iYmax,Ph2=PixelHeight/2 |
|||
Const Iteration=25 |
|||
Const EscRadious=2.5, ER2=EscRadious**2 |
|||
Def single preview |
|||
preview=iXmax*twipsX*(z/16) |
|||
Def long yp, xp, dx, dy, dx1, dy1 |
|||
Let dx=twipsx*(16/z), dx1=dx-1 |
|||
Let dy=twipsy*(16/z), dy1=dy-1 |
|||
yp=y |
|||
For iY=0 to (iYmax-1)*PixelHeight step PixelHeight { |
|||
Cy=CyMin+iY |
|||
xp=x |
|||
if abs(Cy)<Ph2 Then Cy=0 |
|||
For iX=0 to iXm Step PixelWidth { |
|||
Let Cx=CxMin+iX,Zx=0,Zy=0,Zx2=0,Zy2=0 |
|||
For It=Iteration to 1 {Let Zy=2*Zx*Zy+Cy,Zx=Zx2-Zy2+Cx,Zx2=Zx**2,Zy2=Zy**2 :if Zx2+Zy2>ER2 Then exit |
|||
} |
|||
if it>13 then {it-=13} else.if it=0 then SetPixel(xp,yp,0): xp+=dx : continue |
|||
it*=10:SetPixel(xp,yp,color(it, it,255)) :xp+=dx |
|||
} : yp+=dy |
|||
} |
|||
Sub SetPixel() |
|||
move number, number: fill dx1, dy1, number |
|||
End Sub |
|||
} |
|||
Cls 1,0 |
|||
sz=(1,2,4,8,16) |
|||
i=each(sz) |
|||
While i { |
|||
Mandelbrot 250*twipsx,100*twipsy, array(i) |
|||
} |
|||
</syntaxhighlight> |
|||
Version 2 without Subroutine. Also there is a screen refresh every 2 seconds. |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
Module Mandelbrot(x=0&,y=0&,z=1&) { |
|||
If z<1 then z=1 |
|||
If z>16 then z=16 |
|||
Const iXmax=32*z |
|||
Const iYmax=26*z |
|||
Def single Cx, Cy, CxMin=-2.05, CxMax=0.85, CyMin=-1.2, CyMax=1.2 |
|||
Const PixelWidth=(CxMax-CxMin)/iXmax, iXm=(iXmax-1)*PixelWidth |
|||
Const PixelHeight=(CyMax-CyMin)/iYmax,Ph2=PixelHeight/2 |
|||
Const Iteration=25 |
|||
Const EscRadious=2.5, ER2=EscRadious**2 |
|||
Def single preview |
|||
preview=iXmax*twipsX*(z/16) |
|||
Def long yp, xp, dx, dy, dx1, dy1 |
|||
Let dx=twipsx*(16/z), dx1=dx-1 |
|||
Let dy=twipsy*(16/z), dy1=dy-1 |
|||
yp=y |
|||
Refresh 2000 |
|||
For iY=0 to (iYmax-1)*PixelHeight step PixelHeight { |
|||
Cy=CyMin+iY |
|||
xp=x |
|||
if abs(Cy)<Ph2 Then Cy=0 |
|||
move xp, yp |
|||
For iX=0 to iXm Step PixelWidth { |
|||
Let Cx=CxMin+iX,Zx=0,Zy=0,Zx2=0,Zy2=0 |
|||
For It=Iteration to 1 {Let Zy=2*Zx*Zy+Cy,Zx=Zx2-Zy2+Cx,Zx2=Zx**2,Zy2=Zy**2 :if Zx2+Zy2>ER2 Then exit |
|||
} |
|||
if it>13 then {it-=13} else.if it=0 then fill dx1, dy1, 0: Step 0,-dy1: continue |
|||
it*=10:fill dx1, dy1, color(it, it,255): Step 0,-dy1 |
|||
} : yp+=dy |
|||
} |
|||
} |
|||
Cls 1,0 |
|||
sz=(1,2,4,8,16) |
|||
i=each(sz) |
|||
While i { |
|||
Mandelbrot 250*twipsx,100*twipsy, array(i) |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|M4}}== |
|||
{{works with|GNU m4|1.4.19}} |
|||
{{works with|OpenBSD m4}} |
|||
{{works with|Heirloom Development Tools m4}} |
|||
The following m4 code is not optimized very well, but it works. It is actually output from [https://sourceforge.net/p/chemoelectric/rosettacode-contributions/ci/default/tree/vmc.dats a program I call '''vmc'''], which translates output from [[Compiler/code_generator|the code generator task]] to different languages. The Mandelbrot set algorithm from the test set for that task. The '''vmc''' program itself is written in [[ATS|ATS]], and the m4 it generates should run in any POSIX-compliant m4 (if not others as well). For very old m4 implementations, one might need to use an option such as <code>-S 1000</code> to set the stack size larger than the default. |
|||
There are two data structures employed: |
|||
* A FORTH-like data stack, an example of which would be <code>789:456:123:stack-bottom</code> |
|||
* A list of variables, such as <code>var0:123:var1:456:var2:789:</code> |
|||
There are macros to do calculations with the stack. There are also macros to <code>fetch</code> and <code>store</code> the values of variables, which are referenced by name. |
|||
One might enjoy even manually writing m4 code using such structures. However, the big mutual recursion that is the core of the program probably is not how one would write code manually. |
|||
(None of the above involves m4's notorious trickery with commas.) |
|||
<syntaxhighlight lang="m4"> |
|||
divert(-1) |
|||
changecom |
|||
define(`newline',` |
|||
') |
|||
define(`leftquote',`[') |
|||
define(`rightquote',`]') |
|||
changequote(`[',`]') |
|||
define([print_char], |
|||
[ifelse( |
|||
$1,0,[*], |
|||
$1,1,[*], |
|||
$1,2,[*], |
|||
$1,3,[*], |
|||
$1,4,[*], |
|||
$1,5,[*], |
|||
$1,6,[*], |
|||
$1,7,[*], |
|||
$1,8,[*], |
|||
$1,9,[*], |
|||
$1,10,[newline], |
|||
$1,11,[*], |
|||
$1,12,[*], |
|||
$1,13,[*], |
|||
$1,14,[*], |
|||
$1,15,[*], |
|||
$1,16,[*], |
|||
$1,17,[*], |
|||
$1,18,[*], |
|||
$1,19,[*], |
|||
$1,20,[*], |
|||
$1,21,[*], |
|||
$1,22,[*], |
|||
$1,23,[*], |
|||
$1,24,[*], |
|||
$1,25,[*], |
|||
$1,26,[*], |
|||
$1,27,[*], |
|||
$1,28,[*], |
|||
$1,29,[*], |
|||
$1,30,[*], |
|||
$1,31,[*], |
|||
$1,32,[ ], |
|||
$1,33,[!], |
|||
$1,34,["], |
|||
$1,35,[#], |
|||
$1,36,[$], |
|||
$1,37,[%], |
|||
$1,38,[&], |
|||
$1,39,['], |
|||
$1,40,[(], |
|||
$1,41,[)], |
|||
$1,42,[*], |
|||
$1,43,[+], |
|||
$1,44,[,], |
|||
$1,45,[-], |
|||
$1,46,[.], |
|||
$1,47,[/], |
|||
$1,48,[0], |
|||
$1,49,[1], |
|||
$1,50,[2], |
|||
$1,51,[3], |
|||
$1,52,[4], |
|||
$1,53,[5], |
|||
$1,54,[6], |
|||
$1,55,[7], |
|||
$1,56,[8], |
|||
$1,57,[9], |
|||
$1,58,[:], |
|||
$1,59,[;], |
|||
$1,60,[<], |
|||
$1,61,[=], |
|||
$1,62,[>], |
|||
$1,63,[?], |
|||
$1,64,[@], |
|||
$1,65,[A], |
|||
$1,66,[B], |
|||
$1,67,[C], |
|||
$1,68,[D], |
|||
$1,69,[E], |
|||
$1,70,[F], |
|||
$1,71,[G], |
|||
$1,72,[H], |
|||
$1,73,[I], |
|||
$1,74,[J], |
|||
$1,75,[K], |
|||
$1,76,[L], |
|||
$1,77,[M], |
|||
$1,78,[N], |
|||
$1,79,[O], |
|||
$1,80,[P], |
|||
$1,81,[Q], |
|||
$1,82,[R], |
|||
$1,83,[S], |
|||
$1,84,[T], |
|||
$1,85,[U], |
|||
$1,86,[V], |
|||
$1,87,[W], |
|||
$1,88,[X], |
|||
$1,89,[Y], |
|||
$1,90,[Z], |
|||
$1,91,[changequote([`],['])leftquote`'changequote(`[',`]')], |
|||
$1,92,[\], |
|||
$1,93,[rightquote], |
|||
$1,94,[^], |
|||
$1,95,[_], |
|||
$1,96,[`], |
|||
$1,97,[a], |
|||
$1,98,[b], |
|||
$1,99,[c], |
|||
$1,100,[d], |
|||
$1,101,[e], |
|||
$1,102,[f], |
|||
$1,103,[g], |
|||
$1,104,[h], |
|||
$1,105,[i], |
|||
$1,106,[j], |
|||
$1,107,[k], |
|||
$1,108,[l], |
|||
$1,109,[m], |
|||
$1,110,[n], |
|||
$1,111,[o], |
|||
$1,112,[p], |
|||
$1,113,[q], |
|||
$1,114,[r], |
|||
$1,115,[s], |
|||
$1,116,[t], |
|||
$1,117,[u], |
|||
$1,118,[v], |
|||
$1,119,[w], |
|||
$1,120,[x], |
|||
$1,121,[y], |
|||
$1,122,[z], |
|||
$1,123,[{], |
|||
$1,124,[|], |
|||
$1,125,[}], |
|||
$1,126,[~], |
|||
[*])]) |
|||
define([stack_1st],[substr([$1],0,index([$1],[:]))]) |
|||
define([stack_2nd],[stack_1st(stack_drop([$1]))]) |
|||
define([stack_drop],[substr([$1],eval(index([$1],[:]) [+ 1]))]) |
|||
define([stack_drop2],[stack_drop(stack_drop([$1]))]) |
|||
define([stack_not],[eval(stack_1st([$1]) [== 0]):stack_drop([$1])]) |
|||
define([stack_neg],[eval([-] stack_1st([$1])):stack_drop([$1])]) |
|||
define([stack_and],[eval(stack_2nd([$1] [!= 0]) [&&] stack_1st([$1] [!= 0])):stack_drop2([$1])]) |
|||
define([stack_or],[eval(stack_2nd([$1] [!= 0]) [||] stack_1st([$1] [!= 0])):stack_drop2([$1])]) |
|||
define([stack_lt],[eval(stack_2nd([$1]) [<] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([stack_le],[eval(stack_2nd([$1]) [<=] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([stack_gt],[eval(stack_2nd([$1]) [>] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([stack_ge],[eval(stack_2nd([$1]) [>=] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([stack_eq],[eval(stack_2nd([$1]) [==] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([stack_ne],[eval(stack_2nd([$1]) [!=] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([stack_add],[eval(stack_2nd([$1]) [+] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([stack_sub],[eval(stack_2nd([$1]) [-] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([stack_mul],[eval(stack_2nd([$1]) [*] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([stack_div],[eval(stack_2nd([$1]) [/] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([stack_mod],[eval(stack_2nd([$1]) [%] stack_1st([$1])):stack_drop2([$1])]) |
|||
define([prtc_1st],[print_char(stack_1st([$1]))]) |
|||
define([prti_1st],[stack_1st([$1])]) |
|||
define([prts_1st],[print_string(stack_1st([$1]))]) |
|||
define([store],[define([_tmp1],index([$2],[$1:]))[]substr([$2],0,_tmp1)[$1:$3]define([_tmp2],substr([$2],eval(_tmp1 + len([$1]) [+ 1])))substr(_tmp2,index(_tmp2,[:]))]) |
|||
define([fetch],[define([_tmp],substr([$2],eval(index([$2],[$1:]) [+] len([$1]) [+ 1])))[]substr(_tmp,0,index(_tmp,[:]))]) |
|||
define([initial_vars],[var0:0:var1:0:var2:0:var3:0:var4:0:var5:0:var6:0:var7:0:var8:0:var9:0:var10:0:var11:0:var12:0:var13:0:var14:0:]) |
|||
define([kont0],[kont5([420:$1],[$2])]) |
|||
define([kont5],[kont6(stack_neg([$1]),[$2])]) |
|||
define([kont6],[kont11(stack_drop([$1]),store([var0],[$2],stack_1st([$1])))]) |
|||
define([kont11],[kont16([300:$1],[$2])]) |
|||
define([kont16],[kont21(stack_drop([$1]),store([var1],[$2],stack_1st([$1])))]) |
|||
define([kont21],[kont26([300:$1],[$2])]) |
|||
define([kont26],[kont31(stack_drop([$1]),store([var2],[$2],stack_1st([$1])))]) |
|||
define([kont31],[kont36([300:$1],[$2])]) |
|||
define([kont36],[kont37(stack_neg([$1]),[$2])]) |
|||
define([kont37],[kont42(stack_drop([$1]),store([var3],[$2],stack_1st([$1])))]) |
|||
define([kont42],[kont47([7:$1],[$2])]) |
|||
define([kont47],[kont52(stack_drop([$1]),store([var4],[$2],stack_1st([$1])))]) |
|||
define([kont52],[kont57([15:$1],[$2])]) |
|||
define([kont57],[kont62(stack_drop([$1]),store([var5],[$2],stack_1st([$1])))]) |
|||
define([kont62],[kont67([200:$1],[$2])]) |
|||
define([kont67],[kont72(stack_drop([$1]),store([var6],[$2],stack_1st([$1])))]) |
|||
define([kont72],[kont77(fetch([var2],[$2])[:$1],[$2])]) |
|||
define([kont77],[kont82(stack_drop([$1]),store([var7],[$2],stack_1st([$1])))]) |
|||
define([kont82],[kont87(fetch([var7],[$2])[:$1],[$2])]) |
|||
define([kont87],[kont92(fetch([var3],[$2])[:$1],[$2])]) |
|||
define([kont92],[kont93(stack_gt([$1]),[$2])]) |
|||
define([kont93],[ifelse(eval(stack_1st([$1]) [== 0]),1,[kont423(stack_drop([$1]),[$2])],[kont98(stack_drop([$1]),[$2])])]) |
|||
define([kont98],[kont103(fetch([var0],[$2])[:$1],[$2])]) |
|||
define([kont103],[kont108(stack_drop([$1]),store([var8],[$2],stack_1st([$1])))]) |
|||
define([kont108],[kont113(fetch([var8],[$2])[:$1],[$2])]) |
|||
define([kont113],[kont118(fetch([var1],[$2])[:$1],[$2])]) |
|||
define([kont118],[kont119(stack_lt([$1]),[$2])]) |
|||
define([kont119],[ifelse(eval(stack_1st([$1]) [== 0]),1,[kont396(stack_drop([$1]),[$2])],[kont124(stack_drop([$1]),[$2])])]) |
|||
define([kont124],[kont129([0:$1],[$2])]) |
|||
define([kont129],[kont134(stack_drop([$1]),store([var9],[$2],stack_1st([$1])))]) |
|||
define([kont134],[kont139([0:$1],[$2])]) |
|||
define([kont139],[kont144(stack_drop([$1]),store([var10],[$2],stack_1st([$1])))]) |
|||
define([kont144],[kont149([32:$1],[$2])]) |
|||
define([kont149],[kont154(stack_drop([$1]),store([var11],[$2],stack_1st([$1])))]) |
|||
define([kont154],[kont159([0:$1],[$2])]) |
|||
define([kont159],[kont164(stack_drop([$1]),store([var12],[$2],stack_1st([$1])))]) |
|||
define([kont164],[kont169(fetch([var12],[$2])[:$1],[$2])]) |
|||
define([kont169],[kont174(fetch([var6],[$2])[:$1],[$2])]) |
|||
define([kont174],[kont175(stack_lt([$1]),[$2])]) |
|||
define([kont175],[ifelse(eval(stack_1st([$1]) [== 0]),1,[kont369(stack_drop([$1]),[$2])],[kont180(stack_drop([$1]),[$2])])]) |
|||
define([kont180],[kont185(fetch([var10],[$2])[:$1],[$2])]) |
|||
define([kont185],[kont190(fetch([var10],[$2])[:$1],[$2])]) |
|||
define([kont190],[kont191(stack_mul([$1]),[$2])]) |
|||
define([kont191],[kont196([200:$1],[$2])]) |
|||
define([kont196],[kont197(stack_div([$1]),[$2])]) |
|||
define([kont197],[kont202(stack_drop([$1]),store([var13],[$2],stack_1st([$1])))]) |
|||
define([kont202],[kont207(fetch([var9],[$2])[:$1],[$2])]) |
|||
define([kont207],[kont212(fetch([var9],[$2])[:$1],[$2])]) |
|||
define([kont212],[kont213(stack_mul([$1]),[$2])]) |
|||
define([kont213],[kont218([200:$1],[$2])]) |
|||
define([kont218],[kont219(stack_div([$1]),[$2])]) |
|||
define([kont219],[kont224(stack_drop([$1]),store([var14],[$2],stack_1st([$1])))]) |
|||
define([kont224],[kont229(fetch([var13],[$2])[:$1],[$2])]) |
|||
define([kont229],[kont234(fetch([var14],[$2])[:$1],[$2])]) |
|||
define([kont234],[kont235(stack_add([$1]),[$2])]) |
|||
define([kont235],[kont240([800:$1],[$2])]) |
|||
define([kont240],[kont241(stack_gt([$1]),[$2])]) |
|||
define([kont241],[ifelse(eval(stack_1st([$1]) [== 0]),1,[kont298(stack_drop([$1]),[$2])],[kont246(stack_drop([$1]),[$2])])]) |
|||
define([kont246],[kont251([48:$1],[$2])]) |
|||
define([kont251],[kont256(fetch([var12],[$2])[:$1],[$2])]) |
|||
define([kont256],[kont257(stack_add([$1]),[$2])]) |
|||
define([kont257],[kont262(stack_drop([$1]),store([var11],[$2],stack_1st([$1])))]) |
|||
define([kont262],[kont267(fetch([var12],[$2])[:$1],[$2])]) |
|||
define([kont267],[kont272([9:$1],[$2])]) |
|||
define([kont272],[kont273(stack_gt([$1]),[$2])]) |
|||
define([kont273],[ifelse(eval(stack_1st([$1]) [== 0]),1,[kont288(stack_drop([$1]),[$2])],[kont278(stack_drop([$1]),[$2])])]) |
|||
define([kont278],[kont283([64:$1],[$2])]) |
|||
define([kont283],[kont288(stack_drop([$1]),store([var11],[$2],stack_1st([$1])))]) |
|||
define([kont288],[kont293(fetch([var6],[$2])[:$1],[$2])]) |
|||
define([kont293],[kont298(stack_drop([$1]),store([var12],[$2],stack_1st([$1])))]) |
|||
define([kont298],[kont303(fetch([var10],[$2])[:$1],[$2])]) |
|||
define([kont303],[kont308(fetch([var9],[$2])[:$1],[$2])]) |
|||
define([kont308],[kont309(stack_mul([$1]),[$2])]) |
|||
define([kont309],[kont314([100:$1],[$2])]) |
|||
define([kont314],[kont315(stack_div([$1]),[$2])]) |
|||
define([kont315],[kont320(fetch([var7],[$2])[:$1],[$2])]) |
|||
define([kont320],[kont321(stack_add([$1]),[$2])]) |
|||
define([kont321],[kont326(stack_drop([$1]),store([var9],[$2],stack_1st([$1])))]) |
|||
define([kont326],[kont331(fetch([var13],[$2])[:$1],[$2])]) |
|||
define([kont331],[kont336(fetch([var14],[$2])[:$1],[$2])]) |
|||
define([kont336],[kont337(stack_sub([$1]),[$2])]) |
|||
define([kont337],[kont342(fetch([var8],[$2])[:$1],[$2])]) |
|||
define([kont342],[kont343(stack_add([$1]),[$2])]) |
|||
define([kont343],[kont348(stack_drop([$1]),store([var10],[$2],stack_1st([$1])))]) |
|||
define([kont348],[kont353(fetch([var12],[$2])[:$1],[$2])]) |
|||
define([kont353],[kont358([1:$1],[$2])]) |
|||
define([kont358],[kont359(stack_add([$1]),[$2])]) |
|||
define([kont359],[kont364(stack_drop([$1]),store([var12],[$2],stack_1st([$1])))]) |
|||
define([kont364],[kont164([$1],[$2])]) |
|||
define([kont369],[kont374(fetch([var11],[$2])[:$1],[$2])]) |
|||
define([kont374],[prtc_1st([$1])[]kont375(stack_drop([$1]),[$2])]) |
|||
define([kont375],[kont380(fetch([var8],[$2])[:$1],[$2])]) |
|||
define([kont380],[kont385(fetch([var4],[$2])[:$1],[$2])]) |
|||
define([kont385],[kont386(stack_add([$1]),[$2])]) |
|||
define([kont386],[kont391(stack_drop([$1]),store([var8],[$2],stack_1st([$1])))]) |
|||
define([kont391],[kont108([$1],[$2])]) |
|||
define([kont396],[kont401([10:$1],[$2])]) |
|||
define([kont401],[prtc_1st([$1])[]kont402(stack_drop([$1]),[$2])]) |
|||
define([kont402],[kont407(fetch([var7],[$2])[:$1],[$2])]) |
|||
define([kont407],[kont412(fetch([var5],[$2])[:$1],[$2])]) |
|||
define([kont412],[kont413(stack_sub([$1]),[$2])]) |
|||
define([kont413],[kont418(stack_drop([$1]),store([var7],[$2],stack_1st([$1])))]) |
|||
define([kont418],[kont82([$1],[$2])]) |
|||
define([kont423],[]) |
|||
divert[]dnl |
|||
kont0([stack-bottom],initial_vars)[]dnl |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>$ m4 mandel.m4 |
|||
1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 |
|||
1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 |
|||
1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 |
|||
1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 |
|||
1111111111111112222222222222333333333333333333333333333333333333222222222222222222222222222222222222222 |
|||
1111111111111222222222233333333333333333333333344444456655544443333332222222222222222222222222222222222 |
|||
1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 |
|||
11111111111222222333333333333333333333334444444445555679@@@@7654444443333333222222222222222222222222222 |
|||
1111111112222223333333333333333333333444444444455556789@@@@98755544444433333332222222222222222222222222 |
|||
1111111122223333333333333333333333344444444445556668@@@ @@@76555544444333333322222222222222222222222 |
|||
1111111222233333333333333333333344444444455566667778@@ @987666555544433333333222222222222222222222 |
|||
111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@877779@5443333333322222222222222222222 |
|||
1111112233333333333333333334444455555556679@ @@@ @@@@@@ 8544333333333222222222222222222 |
|||
1111122333333333333333334445555555556666789@@@ @86554433333333322222222222222222 |
|||
1111123333333333333444456666555556666778@@ @ @@87655443333333332222222222222222 |
|||
111123333333344444455568@887789@8777788@@@ @@@@65444333333332222222222222222 |
|||
111133334444444455555668@@@@@@@@@@@@99@@@ @@765444333333333222222222222222 |
|||
111133444444445555556778@@@ @@@@ @855444333333333222222222222222 |
|||
11124444444455555668@99@@ @ @655444433333333322222222222222 |
|||
11134555556666677789@@ @86655444433333333322222222222222 |
|||
111 @@876555444433333333322222222222222 |
|||
11134555556666677789@@ @86655444433333333322222222222222 |
|||
11124444444455555668@99@@ @ @655444433333333322222222222222 |
|||
111133444444445555556778@@@ @@@@ @855444333333333222222222222222 |
|||
111133334444444455555668@@@@@@@@@@@@99@@@ @@765444333333333222222222222222 |
|||
111123333333344444455568@887789@8777788@@@ @@@@65444333333332222222222222222 |
|||
1111123333333333333444456666555556666778@@ @ @@87655443333333332222222222222222 |
|||
1111122333333333333333334445555555556666789@@@ @86554433333333322222222222222222 |
|||
1111112233333333333333333334444455555556679@ @@@ @@@@@@ 8544333333333222222222222222222 |
|||
111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@877779@5443333333322222222222222222222 |
|||
1111111222233333333333333333333344444444455566667778@@ @987666555544433333333222222222222222222222 |
|||
1111111122223333333333333333333333344444444445556668@@@ @@@76555544444333333322222222222222222222222 |
|||
1111111112222223333333333333333333333444444444455556789@@@@98755544444433333332222222222222222222222222 |
|||
11111111111222222333333333333333333333334444444445555679@@@@7654444443333333222222222222222222222222222 |
|||
1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 |
|||
1111111111111222222222233333333333333333333333344444456655544443333332222222222222222222222222222222222 |
|||
1111111111111112222222222222333333333333333333333333333333333333222222222222222222222222222222222222222 |
|||
1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 |
|||
1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 |
|||
1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211</pre> |
|||
[[#ALGOL_W|The entry for ALGOL W]] also is based on Rosetta Code's "compiler" task suite. |
|||
=={{header|Maple}}== |
|||
<syntaxhighlight lang="maple">ImageTools:-Embed(Fractals[EscapeTime]:-Mandelbrot(500, -2.0-1.35*I, .7+1.35*I, output = layer1));</syntaxhighlight> |
|||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
|||
The implementation could be better. But this is a start... |
|||
<syntaxhighlight lang="mathematica">eTime[c_, maxIter_Integer: 100] := Length@NestWhileList[#^2 + c &, 0, Abs@# <= 2 &, 1, maxIter] - 1 |
|||
DistributeDefinitions[eTime]; |
|||
mesh = ParallelTable[eTime[x + I*y, 1000], {y, 1.2, -1.2, -0.01}, {x, -1.72, 1, 0.01}]; |
|||
ReliefPlot[mesh, Frame -> False]</syntaxhighlight> |
|||
Faster version: |
|||
<syntaxhighlight lang="mathematica">cf = With[{ |
|||
mandel = Block[{z = #, c = #}, |
|||
Catch@Do[If[Abs[z] > 2, Throw@i]; z = z^2 + c, {i, 100}]] & |
|||
}, |
|||
Compile[{},Table[mandel[y + x I], {x, -1, 1, 0.005}, {y, -2, 0.5, 0.005}]] |
|||
]; |
|||
ArrayPlot[cf[]] </syntaxhighlight> |
|||
Built-in function: |
|||
<syntaxhighlight lang="mathematica">MandelbrotSetPlot[]</syntaxhighlight> |
|||
==Mathmap == |
|||
filter mandelbrot (gradient coloration) |
|||
c=ri:(xy/xy:[X,X]*1.5-xy:[0.5,0]); |
|||
z=ri:[0,0]; # initial value z0 = 0 |
|||
# iteration of z |
|||
iter=0; |
|||
while abs(z)<2 && iter<31 |
|||
do |
|||
z=z*z+c; # z(n+1) = fc(zn) |
|||
iter=iter+1 |
|||
end; |
|||
coloration(iter/32) # color of pixel |
|||
end |
|||
=={{header|MATLAB}}== |
|||
This solution uses the escape time algorithm to determine the coloring of the coordinates on the complex plane. The code can be reduced to a single line via vectorization after the Escape Time Algorithm function definition, but the code becomes unnecessarily obfuscated. Also, this code uses a lot of memory. You will need a computer with a lot of memory to compute the set with high resolution. |
|||
<syntaxhighlight lang="matlab">function [theSet,realAxis,imaginaryAxis] = mandelbrotSet(start,gridSpacing,last,maxIteration) |
|||
%Define the escape time algorithm |
|||
function escapeTime = escapeTimeAlgorithm(z0) |
|||
escapeTime = 0; |
|||
z = 0; |
|||
while( (abs(z)<=2) && (escapeTime < maxIteration) ) |
|||
z = (z + z0)^2; |
|||
escapeTime = escapeTime + 1; |
|||
end |
|||
end |
|||
%Define the imaginary axis |
|||
imaginaryAxis = (imag(start):imag(gridSpacing):imag(last)); |
|||
%Define the real axis |
|||
realAxis = (real(start):real(gridSpacing):real(last)); |
|||
%Construct the complex plane from the real and imaginary axes |
|||
complexPlane = meshgrid(realAxis,imaginaryAxis) + meshgrid(imaginaryAxis(end:-1:1),realAxis)'.*i; |
|||
%Apply the escape time algorithm to each point in the complex plane |
|||
theSet = arrayfun(@escapeTimeAlgorithm, complexPlane); |
|||
%Draw the set |
|||
pcolor(realAxis,imaginaryAxis,theSet); |
|||
shading flat; |
|||
end</syntaxhighlight> |
|||
To use this function you must specify the: |
|||
<ol> |
|||
<li>lower left hand corner of the complex plane from which to start the image, |
|||
<li>the grid spacing in both the imaginary and real directions, |
|||
<li>the upper right hand corner of the complex plane at which to end the image and |
|||
<li>the maximum iterations for the escape time algorithm. |
|||
</ol> |
|||
For example: |
|||
<ol> |
|||
<li>Lower Left Corner: -2.05-1.2i |
|||
<li>Grid Spacing: 0.004+0.0004i |
|||
<li>Upper Right Corner: 0.45+1.2i |
|||
<li>Maximum Iterations: 500 |
|||
</ol> |
|||
Sample usage: |
|||
<syntaxhighlight lang="matlab">mandelbrotSet(-2.05-1.2i,0.004+0.0004i,0.45+1.2i,500);</syntaxhighlight> |
|||
=={{header|Maxima}}== |
|||
Using autoloded package plotdf |
|||
<syntaxhighlight lang="maxima"> |
|||
mandelbrot ([iterations, 30], [x, -2.4, 0.75], [y, -1.2, 1.2], |
|||
[grid,320,320])$ |
|||
</syntaxhighlight> |
|||
[[File:MandelbrotMaxima.png|thumb|center]] |
|||
=={{header|Metapost}}== |
|||
<syntaxhighlight lang="metapost">prologues:=3; |
|||
outputtemplate:="%j-%c.svg"; |
|||
outputformat:="svg"; |
|||
def mandelbrot(expr maxX, maxY) = |
|||
max_iteration := 500; |
|||
color col[]; |
|||
for i := 0 upto max_iteration: |
|||
t := i / max_iteration; |
|||
col[i] = (t,t,t); |
|||
endfor; |
|||
for px := 0 upto maxX: |
|||
for py := 0 upto maxY: |
|||
xz := px * 3.5 / maxX - 2.5; % (-2.5,1) |
|||
yz := py * 2 / maxY - 1; % (-1,1) |
|||
x := 0; |
|||
y := 0; |
|||
iteration := 0; |
|||
forever: exitunless ((x*x + y*y < 4) and (iteration < max_iteration)); |
|||
xtemp := x*x - y*y + xz; |
|||
y := 2*x*y + yz; |
|||
x := xtemp; |
|||
iteration := iteration + 1; |
|||
endfor; |
|||
draw (px,py) withpen pencircle withcolor col[iteration]; |
|||
endfor; |
|||
endfor; |
|||
enddef; |
|||
beginfig(1); |
|||
mandelbrot(200, 150); |
|||
endfig; |
|||
end</syntaxhighlight> |
|||
Sample usage: |
|||
<syntaxhighlight lang="bash">mpost -numbersystem="double" mandelbrot.mp</syntaxhighlight> |
|||
=={{header|MiniScript}}== |
|||
{{works with|Mini Micro}} |
|||
<syntaxhighlight lang="miniscript">ZOOM = 100 |
|||
MAX_ITER = 40 |
|||
gfx.clear color.black |
|||
for y in range(0,200) |
|||
for x in range(0,300) |
|||
zx = 0 |
|||
zy = 0 |
|||
cx = (x - 200) / ZOOM |
|||
cy = (y - 100) / ZOOM |
|||
for iter in range(MAX_ITER) |
|||
if zx*zx + zy*zy > 4 then break |
|||
tmp = zx * zx - zy * zy + cx |
|||
zy = 2 * zx * zy + cy |
|||
zx = tmp |
|||
end for |
|||
if iter then |
|||
gfx.setPixel x, y, rgb(255-iter*6, 0, iter*6) |
|||
end if |
|||
end for |
|||
end for</syntaxhighlight> |
|||
{{output}} |
|||
[[File:Mandelbrot-MiniScript.png|frameless]] |
|||
load'graph' |
|||
viewmat mcf "0 @ domain (_2j_1 1j1) ; 0.01 NB. Complex interval and resolution</lang> |
|||
=={{header|Modula-3}}== |
=={{header|Modula-3}}== |
||
< |
<syntaxhighlight lang="modula3">MODULE Mandelbrot EXPORTS Main; |
||
IMPORT Wr, Stdio, Fmt, Word; |
IMPORT Wr, Stdio, Fmt, Word; |
||
Line 703: | Line 9,783: | ||
END; |
END; |
||
END; |
END; |
||
END Mandelbrot.</ |
END Mandelbrot.</syntaxhighlight> |
||
=={{header|MySQL}}== |
|||
See http://arbitraryscrawl.blogspot.co.uk/2012/06/fractsql.html for an explanation. |
|||
<syntaxhighlight lang="mysql"> |
|||
-- Table to contain all the data points |
|||
CREATE TABLE points ( |
|||
c_re DOUBLE, |
|||
c_im DOUBLE, |
|||
z_re DOUBLE DEFAULT 0, |
|||
z_im DOUBLE DEFAULT 0, |
|||
znew_re DOUBLE DEFAULT 0, |
|||
znew_im DOUBLE DEFAULT 0, |
|||
steps INT DEFAULT 0, |
|||
active CHAR DEFAULT 1 |
|||
); |
|||
DELIMITER | |
|||
-- Iterate over all the points in the table 'points' |
|||
CREATE PROCEDURE itrt (IN n INT) |
|||
BEGIN |
|||
label: LOOP |
|||
UPDATE points |
|||
SET |
|||
znew_re=POWER(z_re,2)-POWER(z_im,2)+c_re, |
|||
znew_im=2*z_re*z_im+c_im, |
|||
steps=steps+1 |
|||
WHERE active=1; |
|||
UPDATE points SET |
|||
z_re=znew_re, |
|||
z_im=znew_im, |
|||
active=IF(POWER(z_re,2)+POWER(z_im,2)>4,0,1) |
|||
WHERE active=1; |
|||
SET n = n - 1; |
|||
IF n > 0 THEN |
|||
ITERATE label; |
|||
END IF; |
|||
LEAVE label; |
|||
END LOOP label; |
|||
END| |
|||
-- Populate the table 'points' |
|||
CREATE PROCEDURE populate ( |
|||
r_min DOUBLE, |
|||
r_max DOUBLE, |
|||
r_step DOUBLE, |
|||
i_min DOUBLE, |
|||
i_max DOUBLE, |
|||
i_step DOUBLE) |
|||
BEGIN |
|||
DELETE FROM points; |
|||
SET @rl = r_min; |
|||
SET @a = 0; |
|||
rloop: LOOP |
|||
SET @im = i_min; |
|||
SET @b = 0; |
|||
iloop: LOOP |
|||
INSERT INTO points (c_re, c_im) |
|||
VALUES (@rl, @im); |
|||
SET @b=@b+1; |
|||
SET @im=i_min + @b * i_step; |
|||
IF @im < i_max THEN |
|||
ITERATE iloop; |
|||
END IF; |
|||
LEAVE iloop; |
|||
END LOOP iloop; |
|||
SET @a=@a+1; |
|||
SET @rl=r_min + @a * r_step; |
|||
IF @rl < r_max THEN |
|||
ITERATE rloop; |
|||
END IF; |
|||
LEAVE rloop; |
|||
END LOOP rloop; |
|||
END| |
|||
DELIMITER ; |
|||
-- Choose size and resolution of graph |
|||
-- R_min, R_max, R_step, I_min, I_max, I_step |
|||
CALL populate( -2.5, 1.5, 0.005, -2, 2, 0.005 ); |
|||
-- Calculate 50 iterations |
|||
CALL itrt( 50 ); |
|||
-- Create the image (/tmp/image.ppm) |
|||
-- Note, MySQL will not over-write an existing file and you may need |
|||
-- administrator access to delete or move it |
|||
SELECT @xmax:=COUNT(c_re) INTO @xmax FROM points GROUP BY c_im LIMIT 1; |
|||
SELECT @ymax:=COUNT(c_im) INTO @ymax FROM points GROUP BY c_re LIMIT 1; |
|||
SET group_concat_max_len=11*@xmax*@ymax; |
|||
SELECT |
|||
'P3', @xmax, @ymax, 200, |
|||
GROUP_CONCAT( |
|||
CONCAT( |
|||
IF( active=1, 0, 55+MOD(steps, 200) ), ' ', |
|||
IF( active=1, 0, 55+MOD(POWER(steps,3), 200) ), ' ', |
|||
IF( active=1, 0, 55+MOD(POWER(steps,2), 200) ) ) |
|||
ORDER BY c_im ASC, c_re ASC SEPARATOR ' ' ) |
|||
INTO OUTFILE '/tmp/image.ppm' |
|||
FROM points; |
|||
</syntaxhighlight> |
|||
=={{header|Nim}}== |
|||
===Textual version=== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="nim">import complex |
|||
proc inMandelbrotSet(c: Complex, maxEscapeIterations = 50): bool = |
|||
result = true; var z: Complex |
|||
for i in 0..maxEscapeIterations: |
|||
z = z * z + c |
|||
if abs2(z) > 4: return false |
|||
iterator steps(start, step: float, numPixels: int): float = |
|||
for i in 0..numPixels: |
|||
yield start + i.float * step |
|||
proc mandelbrotImage(yStart, yStep, xStart, xStep: float, height, width: int): string = |
|||
for y in steps(yStart, yStep, height): |
|||
for x in steps(xStart, xStep, width): |
|||
result.add(if complex(x, y).inMandelbrotSet: '*' |
|||
else: ' ') |
|||
result.add('\n') |
|||
echo mandelbrotImage(1.0, -0.05, -2.0, 0.0315, 40, 80)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
** |
|||
****** |
|||
******** |
|||
****** |
|||
******** ** * |
|||
*** ***************** |
|||
************************ *** |
|||
**************************** |
|||
****************************** |
|||
****************************** |
|||
************************************ |
|||
* ********************************** |
|||
** ***** * ********************************** |
|||
*********** ************************************ |
|||
************** ************************************ |
|||
*************************************************** |
|||
***************************************************** |
|||
************************************************************************ |
|||
***************************************************** |
|||
*************************************************** |
|||
************** ************************************ |
|||
*********** ************************************ |
|||
** ***** * ********************************** |
|||
* ********************************** |
|||
************************************ |
|||
****************************** |
|||
****************************** |
|||
**************************** |
|||
************************ *** |
|||
*** ***************** |
|||
******** ** * |
|||
****** |
|||
******** |
|||
****** |
|||
** |
|||
</pre> |
|||
===Graphical version=== |
|||
{{trans|Julia}} |
|||
{{libheader|imageman}} |
|||
<syntaxhighlight lang="nim">import math, complex, lenientops |
|||
import imageman |
|||
const |
|||
W = 800 |
|||
H = 600 |
|||
Zoom = 0.5 |
|||
MoveX = -0.5 |
|||
MoveY = 0.0 |
|||
MaxIter = 30 |
|||
func hsvToRgb(h, s, v: float): array[3, float] = |
|||
let c = v * s |
|||
let x = c * (1 - abs(((h / 60) mod 2) - 1)) |
|||
let m = v - c |
|||
let (r, g, b) = if h < 60: (c, x, 0.0) |
|||
elif h < 120: (x, c, 0.0) |
|||
elif h < 180: (0.0, c, x) |
|||
elif h < 240: (0.0, x, c) |
|||
elif x < 300: (x, 0.0, c) |
|||
else: (c, 0.0, x) |
|||
result = [r + m, g + m, b + m] |
|||
var img = initImage[ColorRGBF64](W, H) |
|||
for x in 1..W: |
|||
for y in 1..H: |
|||
var i = MaxIter - 1 |
|||
let c = complex((2 * x - W) / (W * Zoom) + MoveX, (2 * y - H) / (H * Zoom) + MoveY) |
|||
var z = c |
|||
while abs(z) < 2 and i > 0: |
|||
z = z * z + c |
|||
dec i |
|||
let color = hsvToRgb(i / MaxIter * 360, 1, i / MaxIter) |
|||
img[x - 1, y - 1] = ColorRGBF64(color) |
|||
img.savePNG("mandelbrot.png", compression = 9)</syntaxhighlight> |
|||
=={{header|ObjectIcon}}== |
|||
A simple interactive graphics program that can dump PNG images. An escape-time algorithm is used to set the opacity of black on white. |
|||
You can run it with <code>oiscript the-file-name-you-gave-it.icn</code>. Or you can compile it to an executable intermediate code with <code>oit the-file-name-you-gave-it.icn</code> and then run <code>./the-file-name-you-gave-it</code> |
|||
<syntaxhighlight lang="objecticon"> |
|||
# -*- ObjectIcon -*- |
|||
import graphics |
|||
import ipl.graphics |
|||
import io |
|||
import util(Math) |
|||
procedure main () |
|||
local w |
|||
local width, height |
|||
local xcenter, ycenter, pixels_per_unit, max_iter |
|||
local zoom_ratio |
|||
write ("q or Q : quit") |
|||
write ("left press : recenter") |
|||
write ("+ : zoom in") |
|||
write ("- : zoom in") |
|||
write ("2 .. 9 : set zoom ratio") |
|||
write ("o or O : restore original") |
|||
write ("p or P : dump to a PNG") |
|||
width := 400 |
|||
height := 400 |
|||
pixels_per_unit := 150 |
|||
max_iter := 200 |
|||
zoom_ratio := 2 |
|||
xcenter := -0.75 |
|||
ycenter := 0.0 |
|||
w := Window(). |
|||
set_size(width, height). |
|||
set_resize(&yes). |
|||
set_bg("white"). |
|||
set_canvas("normal") | stop(&why) |
|||
event_loop (w, xcenter, ycenter, pixels_per_unit, max_iter, |
|||
zoom_ratio) |
|||
end |
|||
procedure event_loop (w, xcenter, ycenter, pixels_per_unit, |
|||
max_iter, zoom_ratio) |
|||
local event |
|||
local xy |
|||
local png_number, png_name |
|||
local redraw |
|||
local width, height |
|||
local xleft, ytop |
|||
local i, j |
|||
local cx, cy, step |
|||
local iter, color |
|||
png_number := 1 |
|||
redraw := &yes |
|||
repeat |
|||
{ |
|||
if \redraw then |
|||
{ |
|||
w.erase_area() |
|||
step := 1.0 / pixels_per_unit |
|||
width := w.get_width() |
|||
height := w.get_height() |
|||
xleft := xcenter - (width / (2.0 * pixels_per_unit)) |
|||
ytop := ycenter + (height / (2.0 * pixels_per_unit)) |
|||
cx := xleft |
|||
cy := ytop |
|||
j := 0 |
|||
i := 0 |
|||
redraw := &no |
|||
} |
|||
if j ~= height then |
|||
{ |
|||
iter := count_mandelbrot_iterations (cx, cy, max_iter) |
|||
color := map_iterations_to_color (max_iter, iter) |
|||
w.set_fg (color) |
|||
w.draw_point (i, j) |
|||
i +:= 1; cx +:= step |
|||
if i = width then |
|||
{ |
|||
i := 0; cx := xleft |
|||
j +:= 1; cy -:= step |
|||
} |
|||
} |
|||
if *w.pending() ~= 0 then |
|||
{ |
|||
event := w.event() |
|||
case event[1] of |
|||
{ |
|||
QuitEvents(): |
|||
exit() |
|||
Mouse.LEFT_PRESS: |
|||
{ |
|||
xy := window_coords_to_point (w, event[2], event[3], |
|||
xcenter, ycenter, |
|||
pixels_per_unit) |
|||
xcenter := xy[1] |
|||
ycenter := xy[2] |
|||
redraw := &yes |
|||
} |
|||
"+": |
|||
{ |
|||
pixels_per_unit := zoom_ratio * pixels_per_unit |
|||
redraw := &yes |
|||
} |
|||
"-": |
|||
{ |
|||
pixels_per_unit := |
|||
max (1, (1.0 / zoom_ratio) * pixels_per_unit) |
|||
redraw := &yes |
|||
} |
|||
!"23456789": |
|||
zoom_ratio := integer(event[1]) |
|||
!"oO": |
|||
{ |
|||
pixels_per_unit := 150 |
|||
max_iter := 200 |
|||
zoom_ratio := 2 |
|||
xcenter := -0.75 |
|||
ycenter := 0.0 |
|||
redraw := &yes |
|||
} |
|||
!"pP": |
|||
{ |
|||
png_name := "mandelbrot-image-" || png_number || ".png" |
|||
png_number +:= 1 |
|||
w.get_pixels().to_file(png_name) |
|||
write ("Wrote ", png_name) |
|||
} |
|||
Window.RESIZE: |
|||
redraw := &yes |
|||
} |
|||
WDelay(w, 100) |
|||
} |
|||
} |
|||
end |
|||
procedure count_mandelbrot_iterations (cx, cy, max_iter) |
|||
local x, y, xsquared, ysquared, iter, tmp |
|||
x := 0 |
|||
y := 0 |
|||
iter := 0 |
|||
until (iter = max_iter | |
|||
4 < (xsquared := x * x) + (ysquared := y * y)) do |
|||
{ |
|||
tmp := xsquared - ysquared + cx |
|||
y := (2 * x * y) + cy |
|||
x := tmp |
|||
iter +:= 1 |
|||
} |
|||
return iter |
|||
end |
|||
procedure map_iterations_to_color (max_iter, iter) |
|||
return "black " || |
|||
integer((Math.log (iter) * 100.0) / Math.log (max_iter)) || |
|||
"%" |
|||
end |
|||
procedure window_coords_to_point (w, xcoord, ycoord, |
|||
xcenter, ycenter, |
|||
pixels_per_unit) |
|||
local x, y |
|||
x := xcenter + |
|||
(((2.0 * xcoord) - w.get_width()) / (2.0 * pixels_per_unit)) |
|||
y := ycenter + |
|||
((w.get_height() - (2.0 * ycoord)) / (2.0 * pixels_per_unit)) |
|||
return [x, y] |
|||
end |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
An example of a dumped PNG: |
|||
[[File:Mandelbrot task OI sampleimage.png|thumb|none|alt=A sample of seahorse valley from the Object Icon program.]] |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
< |
<syntaxhighlight lang="ocaml">#load "graphics.cma";; |
||
let mandelbrot xMin xMax yMin yMax xPixels yPixels maxIter = |
let mandelbrot xMin xMax yMin yMax xPixels yPixels maxIter = |
||
Line 733: | Line 10,224: | ||
done;; |
done;; |
||
mandelbrot (-1.5) 0.5 (-1.0) 1.0 500 500 200;;</ |
mandelbrot (-1.5) 0.5 (-1.0) 1.0 500 500 200;;</syntaxhighlight> |
||
=={{header|Octave}}== |
=={{header|Octave}}== |
||
This code runs rather slowly and produces coloured Mandelbrot set by accident ( |
This code runs rather slowly and produces coloured Mandelbrot set by accident ([[Media:Mandel-Octave.jpg|output image]]). |
||
< |
<syntaxhighlight lang="octave">#! /usr/bin/octave -qf |
||
global width = 200; |
global width = 200; |
||
global height = 200; |
global height = 200; |
||
Line 772: | Line 10,263: | ||
endfor |
endfor |
||
saveimage("mandel.ppm", round(ms .* 255).', "ppm");</ |
saveimage("mandel.ppm", round(ms .* 255).', "ppm");</syntaxhighlight> |
||
A bit faster than the above implementation |
|||
<syntaxhighlight lang="octave"> |
|||
function z = mandelbrot() |
|||
% to view the image call "image(mandelbrot())" |
|||
width = 500; height = 500; |
|||
z = zeros(width, height); |
|||
c = zeros(width, height); |
|||
xi = 1; |
|||
for x = linspace(-2, 2, width) |
|||
yi = 1; |
|||
for y = linspace(-2, 2, height) |
|||
c(yi, xi) = x+y*i; yi += 1; |
|||
end |
|||
xi += 1; |
|||
end |
|||
for iter = 1:50 |
|||
z = z.*z + c; |
|||
end |
|||
z = abs(z); |
|||
end |
|||
</syntaxhighlight> |
|||
=={{header|Ol}}== |
|||
<syntaxhighlight lang="scheme"> |
|||
(define x-size 59) |
|||
(define y-size 21) |
|||
(define min-im -1) |
|||
(define max-im 1) |
|||
(define min-re -2) |
|||
(define max-re 1) |
|||
(define step-x (/ (- max-re min-re) x-size)) |
|||
(define step-y (/ (- max-im min-im) y-size)) |
|||
(for-each (lambda (y) |
|||
(let ((im (+ min-im (* step-y y)))) |
|||
(for-each (lambda (x) |
|||
(let*((re (+ min-re (* step-x x))) |
|||
(zr (inexact re)) |
|||
(zi (inexact im))) |
|||
(let loop ((n 0) (zi zi) (zr zr)) |
|||
(let ((a (* zr zr)) |
|||
(b (* zi zi))) |
|||
(cond |
|||
((> (+ a b) 4) |
|||
(display (string (- 62 n)))) |
|||
((= n 30) |
|||
(display (string (- 62 n)))) |
|||
(else |
|||
(loop (+ n 1) (+ (* 2 zr zi) im) (- (+ a re) b)))))))) |
|||
(iota x-size)) |
|||
(print))) |
|||
(iota y-size)) |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<========== |
|||
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======= |
|||
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== |
|||
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== |
|||
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== |
|||
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== |
|||
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= |
|||
><<<<;;;;;:::972456-567763 +9;;<<<<<<< |
|||
><;;;;;;::::9875& .3 *9;;;<<<<<< |
|||
>;;;;;;::997564' ' 8:;;;<<<<<< |
|||
>::988897735/ &89:;;;<<<<<< |
|||
>::988897735/ &89:;;;<<<<<< |
|||
>;;;;;;::997564' ' 8:;;;<<<<<< |
|||
><;;;;;;::::9875& .3 *9;;;<<<<<< |
|||
><<<<;;;;;:::972456-567763 +9;;<<<<<<< |
|||
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= |
|||
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== |
|||
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== |
|||
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== |
|||
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== |
|||
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======= |
|||
</pre> |
|||
=={{header|OpenEdge/Progress}}== |
|||
<syntaxhighlight lang="progress (openedge abl)">DEFINE VARIABLE print_str AS CHAR NO-UNDO INIT ''. |
|||
DEFINE VARIABLE X1 AS DECIMAL NO-UNDO INIT 50. |
|||
DEFINE VARIABLE Y1 AS DECIMAL NO-UNDO INIT 21. |
|||
DEFINE VARIABLE X AS DECIMAL NO-UNDO. |
|||
DEFINE VARIABLE Y AS DECIMAL NO-UNDO. |
|||
DEFINE VARIABLE N AS DECIMAL NO-UNDO. |
|||
DEFINE VARIABLE I3 AS DECIMAL NO-UNDO. |
|||
DEFINE VARIABLE R3 AS DECIMAL NO-UNDO. |
|||
DEFINE VARIABLE Z1 AS DECIMAL NO-UNDO. |
|||
DEFINE VARIABLE Z2 AS DECIMAL NO-UNDO. |
|||
DEFINE VARIABLE A AS DECIMAL NO-UNDO. |
|||
DEFINE VARIABLE B AS DECIMAL NO-UNDO. |
|||
DEFINE VARIABLE I1 AS DECIMAL NO-UNDO INIT -1.0. |
|||
DEFINE VARIABLE I2 AS DECIMAL NO-UNDO INIT 1.0. |
|||
DEFINE VARIABLE R1 AS DECIMAL NO-UNDO INIT -2.0. |
|||
DEFINE VARIABLE R2 AS DECIMAL NO-UNDO INIT 1.0. |
|||
DEFINE VARIABLE S1 AS DECIMAL NO-UNDO. |
|||
DEFINE VARIABLE S2 AS DECIMAL NO-UNDO. |
|||
S1 = (R2 - R1) / X1. |
|||
S2 = (I2 - I1) / Y1. |
|||
DO Y = 0 TO Y1 - 1: |
|||
I3 = I1 + S2 * Y. |
|||
DO X = 0 TO X1 - 1: |
|||
R3 = R1 + S1 * X. |
|||
Z1 = R3. |
|||
Z2 = I3. |
|||
DO N = 0 TO 29: |
|||
A = Z1 * Z1. |
|||
B = Z2 * Z2. |
|||
IF A + B > 4.0 THEN |
|||
LEAVE. |
|||
Z2 = 2 * Z1 * Z2 + I3. |
|||
Z1 = A - B + R3. |
|||
END. |
|||
print_str = print_str + CHR(62 - N). |
|||
END. |
|||
print_str = print_str + '~n'. |
|||
END. |
|||
OUTPUT TO "C:\Temp\out.txt". |
|||
MESSAGE print_str. |
|||
OUTPUT CLOSE. |
|||
</syntaxhighlight>Example :<BR> |
|||
=={{header|PARI/GP}}== |
|||
Define function mandelbrot(): |
|||
<syntaxhighlight lang="parigp">mandelbrot() = |
|||
{ |
|||
forstep(y=-1, 1, 0.05, |
|||
forstep(x=-2, 0.5, 0.0315, |
|||
print1(((c)->my(z=c);for(i=1,20,z=z*z+c;if(abs(z)>2,return(" ")));"#")(x+y*I))); |
|||
print()); |
|||
}</syntaxhighlight> |
|||
Output:<pre>gp > mandelbrot() |
|||
# |
|||
# ### # |
|||
######## |
|||
######### |
|||
###### |
|||
## ## ############ # |
|||
### ################### # |
|||
############################# |
|||
############################ |
|||
################################ |
|||
################################ |
|||
#################################### # |
|||
# # ################################### |
|||
########### ################################### |
|||
########### ##################################### |
|||
############## #################################### |
|||
#################################################### |
|||
###################################################### |
|||
######################################################################### |
|||
###################################################### |
|||
#################################################### |
|||
############## #################################### |
|||
########### ##################################### |
|||
########### ################################### |
|||
# # ################################### |
|||
#################################### # |
|||
################################ |
|||
################################ |
|||
############################ |
|||
############################# |
|||
### ################### # |
|||
## ## ############ # |
|||
###### |
|||
######### |
|||
######## |
|||
# ### # |
|||
# |
|||
</pre> |
|||
=={{header|Pascal}}== |
|||
{{trans|C}} |
|||
<syntaxhighlight lang="pascal">program mandelbrot; |
|||
{$IFDEF FPC} |
|||
{$MODE DELPHI} |
|||
{$ENDIF} |
|||
const |
|||
ixmax = 800; |
|||
iymax = 800; |
|||
cxmin = -2.5; |
|||
cxmax = 1.5; |
|||
cymin = -2.0; |
|||
cymax = 2.0; |
|||
maxcolorcomponentvalue = 255; |
|||
maxiteration = 200; |
|||
escaperadius = 2; |
|||
type |
|||
colortype = record |
|||
red : byte; |
|||
green : byte; |
|||
blue : byte; |
|||
end; |
|||
var |
|||
ix, iy : integer; |
|||
cx, cy : real; |
|||
pixelwidth : real = (cxmax - cxmin) / ixmax; |
|||
pixelheight : real = (cymax - cymin) / iymax; |
|||
filename : string = 'new1.ppm'; |
|||
comment : string = '# '; |
|||
outfile : textfile; |
|||
color : colortype; |
|||
zx, zy : real; |
|||
zx2, zy2 : real; |
|||
iteration : integer; |
|||
er2 : real = (escaperadius * escaperadius); |
|||
begin |
|||
{$I-} |
|||
assign(outfile, filename); |
|||
rewrite(outfile); |
|||
if ioresult <> 0 then |
|||
begin |
|||
{$IFDEF FPC} |
|||
writeln(stderr, 'Unable to open output file: ', filename); |
|||
{$ELSE} |
|||
writeln('ERROR: Unable to open output file: ', filename); |
|||
{$ENDIF} |
|||
exit; |
|||
end; |
|||
writeln(outfile, 'P6'); |
|||
writeln(outfile, ' ', comment); |
|||
writeln(outfile, ' ', ixmax); |
|||
writeln(outfile, ' ', iymax); |
|||
writeln(outfile, ' ', maxcolorcomponentvalue); |
|||
for iy := 1 to iymax do |
|||
begin |
|||
cy := cymin + (iy - 1)*pixelheight; |
|||
if abs(cy) < pixelheight / 2 then cy := 0.0; |
|||
for ix := 1 to ixmax do |
|||
begin |
|||
cx := cxmin + (ix - 1)*pixelwidth; |
|||
zx := 0.0; |
|||
zy := 0.0; |
|||
zx2 := zx*zx; |
|||
zy2 := zy*zy; |
|||
iteration := 0; |
|||
while (iteration < maxiteration) and (zx2 + zy2 < er2) do |
|||
begin |
|||
zy := 2*zx*zy + cy; |
|||
zx := zx2 - zy2 + cx; |
|||
zx2 := zx*zx; |
|||
zy2 := zy*zy; |
|||
iteration := iteration + 1; |
|||
end; |
|||
if iteration = maxiteration then |
|||
begin |
|||
color.red := 0; |
|||
color.green := 0; |
|||
color.blue := 0; |
|||
end |
|||
else |
|||
begin |
|||
color.red := 255; |
|||
color.green := 255; |
|||
color.blue := 255; |
|||
end; |
|||
write(outfile, chr(color.red), chr(color.green), chr(color.blue)); |
|||
end; |
|||
end; |
|||
close(outfile); |
|||
end.</syntaxhighlight> |
|||
=={{header|Peri}}== |
|||
<syntaxhighlight lang="peri"> |
|||
###sysinclude standard.uh |
|||
###sysinclude str.uh |
|||
###sysinclude system.uh |
|||
###sysinclude X.uh |
|||
$ff0000 sto szin |
|||
300 sto maxiter |
|||
maxypixel sto YRES |
|||
maxxpixel sto XRES |
|||
myscreen "Mandelbrot" @YRES @XRES graphic |
|||
#g |
|||
@YRES 2 / (#d) sto y2 |
|||
@YRES 2 / (#d) sto x2 |
|||
@XRES i: {{ |
|||
@YRES {{ |
|||
{{}}§i #g !(#d) 480. - @x2 - @x2 / |
|||
sto xx |
|||
{{}} #g !(#d) @y2 - @y2 / |
|||
sto yy |
|||
zero#d xa zero#d ya zero iter |
|||
#d |
|||
ciklus: |
|||
@xa dup* @ya dup* - @xx + |
|||
@xa 2. * @ya * @yy + sto ya |
|||
sto xa ++()#g iter |
|||
@xa dup* @ya dup* + 4. > @iter @maxiter >=#g |#g then §ciklusvége |
|||
goto §ciklus |
|||
ciklusvége: |
|||
@iter @maxiter ==#g { |
|||
myscreen {{}} {{}}§i @szin setpixel |
|||
}{ |
|||
myscreen {{}} {{}}§i @iter 64 *#g setpixel |
|||
} |
|||
}} |
|||
}} |
|||
myscreen 10000 key? |
|||
vége: myscreen inv graphic |
|||
//."A lenyomott billentyű: " kprintnl |
|||
end |
|||
{ „xx” } |
|||
{ „x2” } |
|||
{ „yy” } |
|||
{ „y2” } |
|||
{ „xa” } |
|||
{ „ya” } |
|||
{ „iter” } |
|||
{ „maxiter” } |
|||
{ „szin” } |
|||
{ „YRES” } |
|||
{ „XRES” } |
|||
{ „myscreen” } |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
[[File:Peri_mandelbrot.png]] |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
translation / optimization of the ruby solution |
translation / optimization of the ruby solution |
||
< |
<syntaxhighlight lang="perl">use Math::Complex; |
||
sub mandelbrot { |
sub mandelbrot { |
||
Line 790: | Line 10,623: | ||
{print mandelbrot($x + $y * i) ? ' ' : '#'} |
{print mandelbrot($x + $y * i) ? ' ' : '#'} |
||
print "\n" |
print "\n" |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Phix}}== |
|||
;Ascii |
|||
This is included in the distribution (with some extra validation) as demo\mandle.exw |
|||
<syntaxhighlight lang="phix">-- |
|||
-- Mandlebrot set in ascii art demo. |
|||
-- |
|||
constant b=" .:,;!/>)|&IH%*#" |
|||
atom r, i, c, C, z, Z, t, k |
|||
for y=30 to 0 by -1 do |
|||
C = y*0.1-1.5 |
|||
puts(1,'\n') |
|||
for x=0 to 74 do |
|||
c = x*0.04-2 |
|||
z = 0 |
|||
Z = 0 |
|||
r = c |
|||
i = C |
|||
k = 0 |
|||
while k<112 do |
|||
t = z*z-Z*Z+r |
|||
Z = 2*z*Z+i |
|||
z = t |
|||
if z*z+Z*Z>10 then exit end if |
|||
k += 1 |
|||
end while |
|||
puts(1,b[remainder(k,16)+1]) |
|||
end for |
|||
end for</syntaxhighlight> |
|||
;Graphical |
|||
This is included in the distribution as demo\arwendemo\mandel.exw |
|||
<syntaxhighlight lang="phix">include arwen.ew |
|||
include ..\arwen\dib256.ew |
|||
constant HelpText = "Left-click drag with the mouse to move the image.\n"& |
|||
" (the image is currently only redrawn on mouseup).\n"& |
|||
"Right-click-drag with the mouse to select a region to zoom in to.\n"& |
|||
"Use the mousewheel to zoom in and out (nb: can be slow).\n"& |
|||
"Press F2 to select iterations, higher==more detail but slower.\n"& |
|||
"Resize the window as you please, but note that going fullscreen, \n"& |
|||
"especially at high iteration, may mean a quite long draw time.\n"& |
|||
"Press Escape to close the window." |
|||
procedure Help() |
|||
void = messageBox("Mandelbrot Set",HelpText,MB_OK) |
|||
end procedure |
|||
integer cWidth = 520 -- client area width |
|||
integer cHeight = 480 -- client area height |
|||
constant Main = create(Window, "Mandelbrot Set", 0, 0, 50, 50, cWidth+16, cHeight+38, 0), |
|||
mainHwnd = getHwnd(Main), |
|||
mainDC = getPrivateDC(Main), |
|||
mIter = create(Menu, "", 0, 0, 0,0,0,0,0), |
|||
iterHwnd = getHwnd(mIter), |
|||
mIter50 = create(MenuItem,"50 (fast, low detail)", 0, mIter, 0,0,0,0,0), |
|||
mIter100 = create(MenuItem,"100 (default)", 0, mIter, 0,0,0,0,0), |
|||
mIter500 = create(MenuItem,"500", 0, mIter, 0,0,0,0,0), |
|||
mIter1000 = create(MenuItem,"1000 (slow, high detail)",0, mIter, 0,0,0,0,0), |
|||
m50to1000 = {mIter50,mIter100,mIter500,mIter1000}, |
|||
i50to1000 = { 50, 100, 500, 1000} |
|||
integer mainDib = 0 |
|||
constant whitePen = c_func(xCreatePen, {0,1,BrightWhite}) |
|||
constant NULL_BRUSH = 5, |
|||
NullBrushID = c_func(xGetStockObject,{NULL_BRUSH}) |
|||
atom t0 |
|||
integer iter |
|||
atom x0, y0 -- top-left coords to draw |
|||
atom scale -- controls width/zoom |
|||
procedure init() |
|||
x0 = -2 |
|||
y0 = -1.25 |
|||
scale = 2.5/cHeight |
|||
iter = 100 |
|||
void = c_func(xSelectObject,{mainDC,whitePen}) |
|||
void = c_func(xSelectObject,{mainDC,NullBrushID}) |
|||
end procedure |
|||
init() |
|||
function in_set(atom x, atom y) |
|||
atom u,t |
|||
if x>-0.75 then |
|||
u = x-0.25 |
|||
t = u*u+y*y |
|||
return ((2*t+u)*(2*t+u)>t) |
|||
else |
|||
return ((x+1)*(x+1)+y*y)>0.0625 |
|||
end if |
|||
end function |
|||
function pixel_colour(atom x0, atom y0, integer iter) |
|||
integer count = 1 |
|||
atom x = 0, y = 0 |
|||
while (count<=iter) and (x*x+y*y<4) do |
|||
count += 1 |
|||
{x,y} = {x*x-y*y+x0,2*x*y+y0} |
|||
end while |
|||
if count<=iter then return count end if |
|||
return 0 |
|||
end function |
|||
procedure mandel(atom x0, atom y0, atom scale) |
|||
atom x,y |
|||
integer c |
|||
t0 = time() |
|||
y = y0 |
|||
for yi=1 to cHeight do |
|||
x = x0 |
|||
for xi=1 to cWidth do |
|||
c = 0 -- default to black |
|||
if in_set(x,y) then |
|||
c = pixel_colour(x,y,iter) |
|||
end if |
|||
setDibPixel(mainDib, xi, yi, c) |
|||
x += scale |
|||
end for |
|||
y += scale |
|||
end for |
|||
end procedure |
|||
integer firsttime = 1 |
|||
integer drawBox = 0 |
|||
integer drawTime = 0 |
|||
procedure newDib() |
|||
sequence pal |
|||
if mainDib!=0 then |
|||
{} = deleteDib(mainDib) |
|||
end if |
|||
mainDib = createDib(cWidth, cHeight) |
|||
pal = repeat({0,0,0},256) |
|||
for i=2 to 256 do |
|||
pal[i][1] = i*5 |
|||
pal[i][2] = 0 |
|||
pal[i][3] = i*10 |
|||
end for |
|||
setDibPalette(mainDib, 1, pal) |
|||
mandel(x0,y0,scale) |
|||
drawTime = 2 |
|||
end procedure |
|||
procedure reDraw() |
|||
setText(Main,"Please Wait...") |
|||
mandel(x0,y0,scale) |
|||
drawTime = 2 |
|||
repaintWindow(Main,False) |
|||
end procedure |
|||
procedure zoom(integer z) |
|||
while z do |
|||
if z>0 then |
|||
scale /= 1.1 |
|||
z -= 1 |
|||
else |
|||
scale *= 1.1 |
|||
z += 1 |
|||
end if |
|||
end while |
|||
reDraw() |
|||
end procedure |
|||
integer dx=0,dy=0 -- mouse down coords |
|||
integer mx=0,my=0 -- mouse move/up coords |
|||
function mainHandler(integer id, integer msg, atom wParam, object lParam) |
|||
integer x, y -- scratch vars |
|||
atom scale10 |
|||
if msg=WM_SIZE then -- (also activate/firsttime) |
|||
{{},{},x,y} = getClientRect(Main) |
|||
if firsttime or cWidth!=x or cHeight!=y then |
|||
scale *= cWidth/x |
|||
{cWidth, cHeight} = {x,y} |
|||
newDib() |
|||
firsttime = 0 |
|||
end if |
|||
elsif msg=WM_PAINT then |
|||
copyDib(mainDC, 0, 0, mainDib) |
|||
if drawBox then |
|||
void = c_func(xRectangle, {mainDC, dx, dy, mx, my}) |
|||
end if |
|||
if drawTime then |
|||
if drawTime=2 then |
|||
setText(Main,sprintf("Mandelbrot Set [generated in %gs]",time()-t0)) |
|||
else |
|||
setText(Main,"Mandelbrot Set") |
|||
end if |
|||
drawTime -= 1 |
|||
end if |
|||
elsif msg=WM_CHAR then |
|||
if wParam=VK_ESCAPE then |
|||
closeWindow(Main) |
|||
elsif wParam='+' then zoom(+1) |
|||
elsif wParam='-' then zoom(-1) |
|||
end if |
|||
elsif msg=WM_LBUTTONDOWN |
|||
or msg=WM_RBUTTONDOWN then |
|||
{dx,dy} = lParam |
|||
elsif msg=WM_MOUSEMOVE then |
|||
if and_bits(wParam,MK_LBUTTON) then |
|||
{mx,my} = lParam |
|||
-- minus dx,dy (see WM_LBUTTONUP) |
|||
-- DEV maybe a timer to redraw, but probably too slow... |
|||
-- (this is where we need a background worker thread, |
|||
-- ideally one we can direct to abandon what it is |
|||
-- currently doing and start work on new x,y instead) |
|||
elsif and_bits(wParam,MK_RBUTTON) then |
|||
{mx,my} = lParam |
|||
drawBox = 1 |
|||
repaintWindow(Main,False) |
|||
end if |
|||
elsif msg=WM_MOUSEWHEEL then |
|||
wParam = floor(wParam/#10000) |
|||
if wParam>=#8000 then -- sign bit set |
|||
wParam-=#10000 |
|||
end if |
|||
wParam = floor(wParam/120) -- (gives +/-1, usually) |
|||
zoom(wParam) |
|||
elsif msg=WM_LBUTTONUP then |
|||
{mx,my} = lParam |
|||
drawBox = 0 |
|||
x0 += (dx-mx)*scale |
|||
y0 += (dy-my)*scale |
|||
reDraw() |
|||
elsif msg=WM_RBUTTONUP then |
|||
{mx,my} = lParam |
|||
drawBox = 0 |
|||
if mx!=dx and my!=dy then |
|||
x0 += min(mx,dx)*scale |
|||
y0 += min(my,dy)*scale |
|||
scale *= (abs(mx-dx))/cHeight |
|||
reDraw() |
|||
end if |
|||
elsif msg=WM_KEYDOWN then |
|||
if wParam=VK_F1 then |
|||
Help() |
|||
elsif wParam=VK_F2 then |
|||
{x,y} = getWindowRect(Main) |
|||
void = c_func(xTrackPopupMenu, {iterHwnd,TPM_LEFTALIGN,x+20,y+40,0,mainHwnd,NULL}) |
|||
elsif find(wParam,{VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT}) then |
|||
drawBox = 0 |
|||
scale10 = scale*10 |
|||
if wParam=VK_UP then |
|||
y0 += scale10 |
|||
elsif wParam=VK_DOWN then |
|||
y0 -= scale10 |
|||
elsif wParam=VK_LEFT then |
|||
x0 += scale10 |
|||
elsif wParam=VK_RIGHT then |
|||
x0 -= scale10 |
|||
end if |
|||
reDraw() |
|||
end if |
|||
elsif msg=WM_COMMAND then |
|||
id = find(id,m50to1000) |
|||
if id!=0 then |
|||
iter = i50to1000[id] |
|||
reDraw() |
|||
end if |
|||
end if |
|||
return 0 |
|||
end function |
|||
setHandler({Main,mIter50,mIter100,mIter500,mIter1000}, routine_id("mainHandler")) |
|||
WinMain(Main,SW_NORMAL) |
|||
void = deleteDib(0)</syntaxhighlight> |
|||
=={{header|PHP}}== |
|||
{{libheader|GD Graphics Library}} |
|||
{{works with|PHP|5.3.5}} |
|||
[[File:Mandel-php.png|thumb|right|Sample output]] |
|||
<syntaxhighlight lang="php">$min_x=-2; |
|||
$max_x=1; |
|||
$min_y=-1; |
|||
$max_y=1; |
|||
$dim_x=400; |
|||
$dim_y=300; |
|||
$im = @imagecreate($dim_x, $dim_y) |
|||
or die("Cannot Initialize new GD image stream"); |
|||
header("Content-Type: image/png"); |
|||
$black_color = imagecolorallocate($im, 0, 0, 0); |
|||
$white_color = imagecolorallocate($im, 255, 255, 255); |
|||
for($y=0;$y<=$dim_y;$y++) { |
|||
for($x=0;$x<=$dim_x;$x++) { |
|||
$c1=$min_x+($max_x-$min_x)/$dim_x*$x; |
|||
$c2=$min_y+($max_y-$min_y)/$dim_y*$y; |
|||
$z1=0; |
|||
$z2=0; |
|||
for($i=0;$i<100;$i++) { |
|||
$new1=$z1*$z1-$z2*$z2+$c1; |
|||
$new2=2*$z1*$z2+$c2; |
|||
$z1=$new1; |
|||
$z2=$new2; |
|||
if($z1*$z1+$z2*$z2>=4) { |
|||
break; |
|||
} |
|||
} |
|||
if($i<100) { |
|||
imagesetpixel ($im, $x, $y, $white_color); |
|||
} |
|||
} |
|||
} |
|||
imagepng($im); |
|||
imagedestroy($im); |
|||
</syntaxhighlight> |
|||
=={{header|Picat}}== |
|||
{{trans|Unicon}} |
|||
Picat has not support for fancy graphics so it's plain 0/1 ASCII. Also, there's no built-in support for complex numbers. |
|||
<syntaxhighlight lang="picat">go => |
|||
Width = 90, |
|||
Height = 50, |
|||
Limit = 50, |
|||
foreach(Y in 1..Height) |
|||
P="", |
|||
foreach (X in 1..Width) |
|||
Z=complex(0,0), |
|||
C=complex(2.5*X/Width-2.0,2.0*Y/Height-1.0), |
|||
J = 0, |
|||
while (J < Limit, c_abs(Z)<2.0) |
|||
Z := c_add(c_mul(Z,Z),C), |
|||
J := J + 1 |
|||
end, |
|||
if J == Limit then |
|||
P := P ++ "#" |
|||
else |
|||
P := P ++ "." |
|||
end |
|||
end, |
|||
printf("%s\n", P) |
|||
end, |
|||
nl. |
|||
% Operations on complex numbers |
|||
complex(R,I) = [R,I]. |
|||
c_add(X,Y) = complex(X[1]+Y[1],X[2]+Y[2]). |
|||
c_mul(X,Y) = complex(X[1]*Y[1]-X[2]*Y[2],X[1]*Y[2]+X[2]*Y[1]). |
|||
c_abs(X) = sqrt(X[1]*X[1]+X[2]*X[2]).</syntaxhighlight> |
|||
{{out}} |
|||
<pre>.......................................................................................... |
|||
.......................................................................................... |
|||
...................................................................##..................... |
|||
..................................................................##...................... |
|||
...............................................................########................... |
|||
..............................................................#########................... |
|||
...............................................................#######.................... |
|||
................................................................######.................... |
|||
..........................................................#.#.############................ |
|||
...................................................###..#####################............. |
|||
...................................................###########################..####...... |
|||
.....................................................##############################....... |
|||
..................................................###############################......... |
|||
..............................................#.###################################....... |
|||
................................................####################################...... |
|||
................................................####################################.#.... |
|||
...............................................#######################################.... |
|||
...............................#...##.........#######################################..... |
|||
.............................##########......#########################################.... |
|||
..............................############...#########################################.... |
|||
...........................################..#########################################.... |
|||
...........................#################.########################################..... |
|||
...........................#################.#######################################...... |
|||
.......................############################################################....... |
|||
#################################################################################......... |
|||
.......................############################################################....... |
|||
...........................#################.#######################################...... |
|||
...........................#################.########################################..... |
|||
...........................################..#########################################.... |
|||
..............................############...#########################################.... |
|||
.............................##########......#########################################.... |
|||
...............................#...##.........#######################################..... |
|||
...............................................#######################################.... |
|||
................................................####################################.#.... |
|||
................................................####################################...... |
|||
..............................................#.###################################....... |
|||
..................................................###############################......... |
|||
.....................................................##############################....... |
|||
...................................................###########################..####...... |
|||
...................................................###..#####################............. |
|||
..........................................................#.#.############................ |
|||
................................................................######.................... |
|||
...............................................................#######.................... |
|||
..............................................................#########................... |
|||
...............................................................########................... |
|||
..................................................................##...................... |
|||
...................................................................##..................... |
|||
.......................................................................................... |
|||
.......................................................................................... |
|||
.......................................................................#..................</pre> |
|||
=={{header|PicoLisp}}== |
|||
<syntaxhighlight lang="picolisp">(scl 6) |
|||
(let Ppm (make (do 300 (link (need 400)))) |
|||
(for (Y . Row) Ppm |
|||
(for (X . @) Row |
|||
(let (ZX 0 ZY 0 CX (*/ (- X 250) 1.0 150) CY (*/ (- Y 150) 1.0 150) C 570) |
|||
(while (and (> 4.0 (+ (*/ ZX ZX 1.0) (*/ ZY ZY 1.0))) (gt0 C)) |
|||
(let Tmp (- (*/ ZX ZX 1.0) (*/ ZY ZY 1.0) (- CX)) |
|||
(setq |
|||
ZY (+ (*/ 2 ZX ZY 1.0) CY) |
|||
ZX Tmp ) ) |
|||
(dec 'C) ) |
|||
(set (nth Ppm Y X) (list 0 C C)) ) ) ) |
|||
(out "img.ppm" |
|||
(prinl "P6") |
|||
(prinl 400 " " 300) |
|||
(prinl 255) |
|||
(for Y Ppm (for X Y (apply wr X))) ) )</syntaxhighlight> |
|||
=={{header|PostScript}}== |
=={{header|PostScript}}== |
||
< |
<syntaxhighlight lang="postscript">%!PS-Adobe-2.0 |
||
%%BoundingBox: 0 0 300 200 |
%%BoundingBox: 0 0 300 200 |
||
%%EndComments |
%%EndComments |
||
Line 838: | Line 11,096: | ||
showpage |
showpage |
||
origstate restore |
origstate restore |
||
%%EOF</ |
%%EOF</syntaxhighlight> |
||
=={{header| |
=={{header|PowerShell}}== |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PureBasic>EnableExplicit |
|||
$x = $y = $i = $j = $r = -16 |
|||
$colors = [Enum]::GetValues([System.ConsoleColor]) |
|||
while(($y++) -lt 15) |
|||
#Window1 = 0 |
|||
{ |
|||
#Image1 = 0 |
|||
for($x=0; ($x++) -lt 84; Write-Host " " -BackgroundColor ($colors[$k -band 15]) -NoNewline) |
|||
#ImgGadget = 0 |
|||
{ |
|||
$i = $k = $r = 0 |
|||
do |
|||
#max_iteration = 64 |
|||
{ |
|||
$j = $r * $r - $i * $i -2 + $x / 25 |
|||
#height = 600 |
|||
$i = 2 * $r * $i + $y / 10 |
|||
Define.d x0 ,y0 ,xtemp ,cr, ci |
|||
$r = $j |
|||
Define.i i, n, x, y ,Event ,color |
|||
} |
|||
while (($j * $j + $i * $i) -lt 11 -band ($k++) -lt 111) |
|||
} |
|||
Write-Host |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|Processing}}== |
|||
Click on an area to zoom in. Choose areas with multiple colors for interesting zooming. |
|||
<syntaxhighlight lang="java">double x, y, zr, zi, zr2, zi2, cr, ci, n; |
|||
double zmx1, zmx2, zmy1, zmy2, f, di, dj; |
|||
double fn1, fn2, fn3, re, gr, bl, xt, yt, i, j; |
|||
void setup() { |
|||
size(500, 500); |
|||
di = 0; |
|||
dj = 0; |
|||
f = 10; |
|||
fn1 = random(20); |
|||
fn2 = random(20); |
|||
fn3 = random(20); |
|||
zmx1 = int(width / 4); |
|||
zmx2 = 2; |
|||
zmy1 = int(height / 4); |
|||
zmy2 = 2; |
|||
} |
|||
void draw() { |
|||
if (i <= width) i++; |
|||
x = (i + di)/ zmx1 - zmx2; |
|||
for ( j = 0; j <= height; j++) { |
|||
y = zmy2 - (j + dj) / zmy1; |
|||
zr = 0; |
|||
zi = 0; |
|||
zr2 = 0; |
|||
zi2 = 0; |
|||
cr = x; |
|||
ci = y; |
|||
n = 1; |
|||
while (n < 200 && (zr2 + zi2) < 4) { |
|||
zi2 = zi * zi; |
|||
zr2 = zr * zr; |
|||
zi = 2 * zi * zr + ci; |
|||
zr = zr2 - zi2 + cr; |
|||
n++; |
|||
} |
|||
re = (n * fn1) % 255; |
|||
gr = (n * fn2) % 255; |
|||
bl = (n * fn3) % 255; |
|||
stroke((float)re, (float)gr, (float)bl); |
|||
point((float)i, (float)j); |
|||
} |
|||
} |
|||
void mousePressed() { |
|||
background(200); |
|||
xt = mouseX; |
|||
yt = mouseY; |
|||
di = di + xt - float(width / 2); |
|||
dj = dj + yt - float(height / 2); |
|||
zmx1 = zmx1 * f; |
|||
zmx2 = zmx2 * (1 / f); |
|||
zmy1 = zmy1 * f; |
|||
zmy2 = zmy2 * (1 / f); |
|||
di = di * f; |
|||
dj = dj * f; |
|||
i = 0; |
|||
j = 0; |
|||
}</syntaxhighlight>'''The sketch can be run online''' :<BR> [https://www.openprocessing.org/sketch/794150 here.] |
|||
==={{header|Processing Python mode}}=== |
|||
Click on an area to zoom in. |
|||
Choose areas with multiple colors for interesting zooming. |
|||
<syntaxhighlight lang="python">i = di = dj = 0 |
|||
fn1, fn2, fn3 = random(20), random(20), random(20) |
|||
f = 10 |
|||
def setup(): |
|||
global zmx1, zmx2, zmy1, zmy2 |
|||
size(500, 500) |
|||
zmx1 = int(width / 4) |
|||
zmx2 = 2 |
|||
zmy1 = int(height / 4) |
|||
zmy2 = 2 |
|||
def draw(): |
|||
global i |
|||
if i <= width: |
|||
i += 1 |
|||
x = float(i + di) / zmx1 - zmx2 |
|||
for j in range(height + 1): |
|||
y = zmy2 - float(j + dj) / zmy1 |
|||
zr = zi = zr2 = zi2 = 0 |
|||
cr, ci = x, y |
|||
n = 1 |
|||
while n < 200 and (zr2 + zi2) < 4: |
|||
zi2 = zi * zi |
|||
zr2 = zr * zr |
|||
zi = 2 * zi * zr + ci |
|||
zr = zr2 - zi2 + cr |
|||
n += 1 |
|||
re = (n * fn1) % 255 |
|||
gr = (n * fn2) % 255 |
|||
bl = (n * fn3) % 255 |
|||
stroke(re, gr, bl) |
|||
point(i, j) |
|||
def mousePressed(): |
|||
global zmx1, zmx2, zmy1, zmy2, di, dj |
|||
global i, j |
|||
background(200) |
|||
xt, yt = mouseX, mouseY |
|||
di = di + xt - width / 2. |
|||
dj = dj + yt - height / 2. |
|||
zmx1 = zmx1 * f |
|||
zmx2 = zmx2 * (1. / f) |
|||
zmy1 = zmy1 * f |
|||
zmy2 = zmy2 * (1. / f) |
|||
di, dj = di * f, dj * f |
|||
i = j = 0</syntaxhighlight> |
|||
=={{header|Prolog}}== |
|||
SWI-Prolog has a graphic interface XPCE : |
|||
<syntaxhighlight lang="prolog">:- use_module(library(pce)). |
|||
mandelbrot :- |
|||
new(D, window('Mandelbrot Set')), |
|||
send(D, size, size(700, 650)), |
|||
new(Img, image(@nil, width := 700, height := 650, kind := pixmap)), |
|||
forall(between(0,699, I), |
|||
( forall(between(0,649, J), |
|||
( get_RGB(I, J, R, G, B), |
|||
R1 is (R * 256) mod 65536, |
|||
G1 is (G * 256) mod 65536, |
|||
B1 is (B * 256) mod 65536, |
|||
send(Img, pixel(I, J, colour(@default, R1, G1, B1))))))), |
|||
new(Bmp, bitmap(Img)), |
|||
send(D, display, Bmp, point(0,0)), |
|||
send(D, open). |
|||
get_RGB(X, Y, R, G, B) :- |
|||
CX is (X - 350) / 150, |
|||
CY is (Y - 325) / 150, |
|||
Iter = 570, |
|||
compute_RGB(CX, CY, 0, 0, Iter, It), |
|||
IterF is It \/ It << 15, |
|||
R is IterF >> 16, |
|||
Iter1 is IterF - R << 16, |
|||
G is Iter1 >> 8, |
|||
B is Iter1 - G << 8. |
|||
compute_RGB(CX, CY, ZX, ZY, Iter, IterF) :- |
|||
ZX * ZX + ZY * ZY < 4, |
|||
Iter > 0, |
|||
!, |
|||
Tmp is ZX * ZX - ZY * ZY + CX, |
|||
ZY1 is 2 * ZX * ZY + CY, |
|||
Iter1 is Iter - 1, |
|||
compute_RGB(CX, CY, Tmp, ZY1, Iter1, IterF). |
|||
compute_RGB(_CX, _CY, _ZX, _ZY, Iter, Iter).</syntaxhighlight>Example :<BR> |
|||
[[FILE:Mandelbrot.jpg]] |
|||
Dim Color.l (255) |
|||
For n = 0 To 63 |
|||
Color( 0 + n ) = RGB( n*4+128, 4 * n, 0 ) |
|||
Color( 64 + n ) = RGB( 64, 255, 4 * n ) |
|||
Color( 128 + n ) = RGB( 64, 255 - 4 * n , 255 ) |
|||
Color( 192 + n ) = RGB( 64, 0, 255 - 4 * n ) |
|||
Next |
|||
If OpenWindow(#Window1, 0, 0, #width, #height, "'Mandelbrot set' PureBasic Example", #PB_Window_SystemMenu ) |
|||
If CreateImage(#Image1, #width, #height) |
|||
ImageGadget(#ImgGadget, 0, 0, #width, #height, ImageID(#Image1)) |
|||
For y.i = 1 To #height -1 |
|||
StartDrawing(ImageOutput(#Image1)) |
|||
For x.i = 1 To #width -1 |
|||
x0 = 0 |
|||
y0 = 0; |
|||
cr = (x / #width)*2.5 -2 |
|||
ci = (y / #height)*2.5 -1.25 |
|||
i = 0 |
|||
While (x0*x0 + y0*y0 <= 4.0) And i < #max_iteration |
|||
i +1 |
|||
xtemp = x0*x0 - y0*y0 + cr |
|||
y0 = 2*x0*y0 + ci |
|||
x0 = xtemp |
|||
Wend |
|||
If i >= #max_iteration |
|||
Plot(x, y, 0 ) |
|||
Else |
|||
Plot(x, y, Color(i & 255)) |
|||
EndIf |
|||
Next |
|||
StopDrawing() |
|||
SetGadgetState(#ImgGadget, ImageID(#Image1)) |
|||
Repeat |
|||
Event = WindowEvent() |
|||
If Event = #PB_Event_CloseWindow |
|||
End |
|||
EndIf |
|||
Until Event = 0 |
|||
Next |
|||
EndIf |
|||
Repeat |
|||
Event = WaitWindowEvent() |
|||
Until Event = #PB_Event_CloseWindow |
|||
EndIf</lang>Example:<br> |
|||
[[File:Mandelbrot-PureBasic.png]] |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
Translation of the ruby solution |
Translation of the ruby solution |
||
<syntaxhighlight lang="python"># Python 3.0+ and 2.5+ |
|||
<lang python> |
|||
try: |
|||
from functools import reduce |
|||
except: |
|||
pass |
|||
def mandelbrot(a): |
def mandelbrot(a): |
||
return reduce(lambda z, |
return reduce(lambda z, _: z * z + a, range(50), 0) |
||
def step(start, step, iterations): |
def step(start, step, iterations): |
||
return (start + (i * step) for i in |
return (start + (i * step) for i in range(iterations)) |
||
rows = (( |
rows = (("*" if abs(mandelbrot(complex(x, y))) < 2 else " " |
||
for x in step(-2.0, .0315, 80)) |
for x in step(-2.0, .0315, 80)) |
||
for y in step(1, -.05, 41)) |
for y in step(1, -.05, 41)) |
||
print |
print("\n".join("".join(row) for row in rows)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
A more "Pythonic" version of the code: |
|||
<syntaxhighlight lang="python"> |
|||
import math |
|||
def mandelbrot(z , c , n=40): |
|||
if abs(z) > 1000: |
|||
return float("nan") |
|||
elif n > 0: |
|||
return mandelbrot(z ** 2 + c, c, n - 1) |
|||
else: |
|||
return z ** 2 + c |
|||
print("\n".join(["".join(["#" if not math.isnan(mandelbrot(0, x + 1j * y).real) else " " |
|||
for x in [a * 0.02 for a in range(-80, 30)]]) |
|||
for y in [a * 0.05 for a in range(-20, 20)]]) |
|||
) |
|||
</syntaxhighlight> |
|||
Finally, we can also use Matplotlib to visualize the Mandelbrot set with Python: |
|||
{{libheader|matplotlib}} |
|||
{{libheader|NumPy}} |
|||
<syntaxhighlight lang="python">from pylab import * |
|||
from numpy import NaN |
|||
def m(a): |
|||
z = 0 |
|||
for n in range(1, 100): |
|||
z = z**2 + a |
|||
if abs(z) > 2: |
|||
return n |
|||
return NaN |
|||
X = arange(-2, .5, .002) |
|||
Y = arange(-1, 1, .002) |
|||
Z = zeros((len(Y), len(X))) |
|||
for iy, y in enumerate(Y): |
|||
print (iy, "of", len(Y)) |
|||
for ix, x in enumerate(X): |
|||
Z[iy,ix] = m(x + 1j * y) |
|||
imshow(Z, cmap = plt.cm.prism, interpolation = 'none', extent = (X.min(), X.max(), Y.min(), Y.max())) |
|||
xlabel("Re(c)") |
|||
ylabel("Im(c)") |
|||
savefig("mandelbrot_python.svg") |
|||
show()</syntaxhighlight> |
|||
Another Numpy version using masks to avoid (explicit) nested loops. |
|||
Runs about 16x faster for the same resolution. |
|||
<syntaxhighlight lang="python">import matplotlib.pyplot as plt |
|||
import numpy as np |
|||
npts = 300 |
|||
max_iter = 100 |
|||
X = np.linspace(-2, 1, 2 * npts) |
|||
Y = np.linspace(-1, 1, npts) |
|||
#broadcast X to a square array |
|||
C = X[:, None] + 1J * Y |
|||
#initial value is always zero |
|||
Z = np.zeros_like(C) |
|||
exit_times = max_iter * np.ones(C.shape, np.int32) |
|||
mask = exit_times > 0 |
|||
for k in range(max_iter): |
|||
Z[mask] = Z[mask] * Z[mask] + C[mask] |
|||
mask, old_mask = abs(Z) < 2, mask |
|||
#use XOR to detect the area which has changed |
|||
exit_times[mask ^ old_mask] = k |
|||
plt.imshow(exit_times.T, |
|||
cmap=plt.cm.prism, |
|||
extent=(X.min(), X.max(), Y.min(), Y.max())) |
|||
plt.show()</syntaxhighlight> |
|||
===Normal Map Effect, Mercator Projection and Deep Zoom Images=== |
|||
'''Normalization, Distance Estimation and Boundary Detection''' |
|||
The Mandelbrot set is printed with smooth colors. The ''e^(-|z|)-smoothing'', ''normalized iteration count'' and ''exterior distance estimation'' algorithms are used with NumPy and complex matrices (see Javier Barrallo & Damien M. Jones: [http://www.mi.sanu.ac.rs/vismath/javier/index.html ''Coloring Algorithms for Dynamical Systems in the Complex Plane''] and Arnaud Chéritat: [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Boundary_detection_methods_via_distance_estimators ''Boundary detection methods via distance estimators'']). Partial antialiasing is used for boundary detection. |
|||
<syntaxhighlight lang="python">import numpy as np |
|||
import matplotlib.pyplot as plt |
|||
d, h = 800, 500 # pixel density (= image width) and image height |
|||
n, r = 200, 500 # number of iterations and escape radius (r > 2) |
|||
x = np.linspace(0, 2, num=d+1) |
|||
y = np.linspace(0, 2 * h / d, num=h+1) |
|||
A, B = np.meshgrid(x - 1, y - h / d) |
|||
C = 2.0 * (A + B * 1j) - 0.5 |
|||
Z, dZ = np.zeros_like(C), np.zeros_like(C) |
|||
D, S, T = np.zeros(C.shape), np.zeros(C.shape), np.zeros(C.shape) |
|||
for k in range(n): |
|||
M = abs(Z) < r |
|||
S[M], T[M] = S[M] + np.exp(- abs(Z[M])), T[M] + 1 |
|||
Z[M], dZ[M] = Z[M] ** 2 + C[M], 2 * Z[M] * dZ[M] + 1 |
|||
plt.imshow(S ** 0.1, cmap=plt.cm.twilight_shifted, origin="lower") |
|||
plt.savefig("Mandelbrot_set_1.png", dpi=200) |
|||
N = abs(Z) >= r # normalized iteration count |
|||
T[N] = T[N] - np.log2(np.log(np.abs(Z[N])) / np.log(r)) |
|||
plt.imshow(T ** 0.1, cmap=plt.cm.twilight_shifted, origin="lower") |
|||
plt.savefig("Mandelbrot_set_2.png", dpi=200) |
|||
N = abs(Z) > 2 # exterior distance estimation |
|||
D[N] = np.log(abs(Z[N])) * abs(Z[N]) / abs(dZ[N]) |
|||
plt.imshow(D ** 0.1, cmap=plt.cm.twilight_shifted, origin="lower") |
|||
plt.savefig("Mandelbrot_set_3.png", dpi=200) |
|||
N, thickness = D > 0, 0.01 # boundary detection |
|||
D[N] = np.maximum(1 - D[N] / thickness, 0) |
|||
plt.imshow(D ** 2.0, cmap=plt.cm.binary, origin="lower") |
|||
plt.savefig("Mandelbrot_set_4.png", dpi=200)</syntaxhighlight> |
|||
'''Normal Map Effect and Stripe Average Coloring''' |
|||
The Mandelbrot set is represented using Normal Maps and Stripe Average Coloring by Jussi Härkönen (cf. Arnaud Chéritat: [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Normal_map_effect ''Normal map effect'']). Note that the second derivative (ddZ) grows very fast, so the second method can only be used for small iteration numbers (n <= 400). See also the picture in section [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Mixing_it_all ''Mixing it all''] and [https://www.shadertoy.com/view/wtscDX Julia Stripes] on Shadertoy. To get a stripe pattern similar to that of Arnaud Chéritat, one can increase the ''density'' of the stripes, use ''cos'' instead of ''sin'', and set the colormap to ''binary''. |
|||
<syntaxhighlight lang="python">import numpy as np |
|||
import matplotlib.pyplot as plt |
|||
d, h = 800, 500 # pixel density (= image width) and image height |
|||
n, r = 200, 500 # number of iterations and escape radius (r > 2) |
|||
direction, height = 45.0, 1.5 # direction and height of the light |
|||
density, intensity = 4.0, 0.5 # density and intensity of the stripes |
|||
x = np.linspace(0, 2, num=d+1) |
|||
y = np.linspace(0, 2 * h / d, num=h+1) |
|||
A, B = np.meshgrid(x - 1, y - h / d) |
|||
C = (2.0 + 1.0j) * (A + B * 1j) - 0.5 |
|||
Z, dZ, ddZ = np.zeros_like(C), np.zeros_like(C), np.zeros_like(C) |
|||
D, S, T = np.zeros(C.shape), np.zeros(C.shape), np.zeros(C.shape) |
|||
for k in range(n): |
|||
M = abs(Z) < r |
|||
S[M], T[M] = S[M] + np.sin(density * np.angle(Z[M])), T[M] + 1 |
|||
Z[M], dZ[M], ddZ[M] = Z[M] ** 2 + C[M], 2 * Z[M] * dZ[M] + 1, 2 * (dZ[M] ** 2 + Z[M] * ddZ[M]) |
|||
N = abs(Z) >= r # basic normal map effect and stripe average coloring (potential function) |
|||
P, Q = S[N] / T[N], (S[N] + np.sin(density * np.angle(Z[N]))) / (T[N] + 1) |
|||
U, V = Z[N] / dZ[N], 1 + (np.log2(np.log(np.abs(Z[N])) / np.log(r)) * (P - Q) + Q) * intensity |
|||
U, v = U / abs(U), np.exp(direction / 180 * np.pi * 1j) # unit normal vectors and light vector |
|||
D[N] = np.maximum((U.real * v.real + U.imag * v.imag + V * height) / (1 + height), 0) |
|||
plt.imshow(D ** 1.0, cmap=plt.cm.bone, origin="lower") |
|||
plt.savefig("Mandelbrot_normal_map_1.png", dpi=200) |
|||
N = abs(Z) > 2 # advanced normal map effect using higher derivatives (distance estimation) |
|||
U = Z[N] * dZ[N] * ((1 + np.log(abs(Z[N]))) * np.conj(dZ[N] ** 2) - np.log(abs(Z[N])) * np.conj(Z[N] * ddZ[N])) |
|||
U, v = U / abs(U), np.exp(direction / 180 * np.pi * 1j) # unit normal vectors and light vector |
|||
D[N] = np.maximum((U.real * v.real + U.imag * v.imag + height) / (1 + height), 0) |
|||
plt.imshow(D ** 1.0, cmap=plt.cm.afmhot, origin="lower") |
|||
plt.savefig("Mandelbrot_normal_map_2.png", dpi=200)</syntaxhighlight> |
|||
'''Mercator Mandelbrot Maps and Zoom Images''' |
|||
A small change in the code above creates Mercator maps of the Mandelbrot set (see David Madore: [http://www.madore.org/~david/math/mandelbrot.html ''Mandelbrot set images and videos''] and Anders Sandberg: [https://www.flickr.com/photos/arenamontanus/sets/72157615740829949 ''Mercator Mandelbrot Maps'']). The maximum magnification is about <math>e ^ {2 \pi \cdot h / d} = e ^ {2 \pi \cdot 5.5} \approx 535.5 ^ {5.5} \approx 10 ^ {15}</math>, which is also the maximum for 64-bit arithmetic. Note that Anders Sandberg uses a different scaling. He uses <math>10 ^ {3 \cdot h / d} = 1000 ^ {h / d}</math> instead of <math>e ^ {2 \pi \cdot h / d} \approx 535.5 ^ {h / d}</math>, so his images appear somewhat compressed in comparison (but not much, because <math>1000 ^ {5.0} \approx 535.5 ^ {5.5}</math>). With the same pixel density and the same maximum magnification, the difference in height between the maps is only about 10 percent. By misusing a scatter plot, it is possible to create zoom images of the Mandelbrot set. See also [https://commons.wikimedia.org/wiki/File:Mandelbrot_sequence_new.gif ''Mandelbrot sequence new''] on Wikimedia for a zoom animation to the given coordinates. |
|||
<syntaxhighlight lang="python">import numpy as np |
|||
import matplotlib.pyplot as plt |
|||
d, h = 200, 1200 # pixel density (= image width) and image height |
|||
n, r = 8000, 10000 # number of iterations and escape radius (r > 2) |
|||
a = -.743643887037158704752191506114774 # https://mathr.co.uk/web/m-location-analysis.html |
|||
b = 0.131825904205311970493132056385139 # try: a, b, n = -1.748764520194788535, 3e-13, 800 |
|||
x = np.linspace(0, 2, num=d+1) |
|||
y = np.linspace(0, 2 * h / d, num=h+1) |
|||
A, B = np.meshgrid(x * np.pi, y * np.pi) |
|||
C = 8.0 * np.exp((A + B * 1j) * 1j) + (a + b * 1j) |
|||
Z, dZ = np.zeros_like(C), np.zeros_like(C) |
|||
D = np.zeros(C.shape) |
|||
for k in range(n): |
|||
M = Z.real ** 2 + Z.imag ** 2 < r ** 2 |
|||
Z[M], dZ[M] = Z[M] ** 2 + C[M], 2 * Z[M] * dZ[M] + 1 |
|||
N = abs(Z) > 2 # exterior distance estimation |
|||
D[N] = np.log(abs(Z[N])) * abs(Z[N]) / abs(dZ[N]) |
|||
plt.imshow(D.T ** 0.05, cmap=plt.cm.nipy_spectral, origin="lower") |
|||
plt.savefig("Mercator_Mandelbrot_map.png", dpi=200) |
|||
X, Y = C.real, C.imag # zoom images (adjust circle size 100 and zoom level 20 as needed) |
|||
R, c, z = 100 * (2 / d) * np.pi * np.exp(- B), min(d, h) + 1, max(0, h - d) // 20 |
|||
fig, ax = plt.subplots(2, 2, figsize=(12, 12)) |
|||
ax[0,0].scatter(X[1*z:1*z+c,0:d], Y[1*z:1*z+c,0:d], s=R[0:c,0:d]**2, c=D[1*z:1*z+c,0:d]**.5, cmap=plt.cm.nipy_spectral) |
|||
ax[0,1].scatter(X[2*z:2*z+c,0:d], Y[2*z:2*z+c,0:d], s=R[0:c,0:d]**2, c=D[2*z:2*z+c,0:d]**.4, cmap=plt.cm.nipy_spectral) |
|||
ax[1,0].scatter(X[3*z:3*z+c,0:d], Y[3*z:3*z+c,0:d], s=R[0:c,0:d]**2, c=D[3*z:3*z+c,0:d]**.3, cmap=plt.cm.nipy_spectral) |
|||
ax[1,1].scatter(X[4*z:4*z+c,0:d], Y[4*z:4*z+c,0:d], s=R[0:c,0:d]**2, c=D[4*z:4*z+c,0:d]**.2, cmap=plt.cm.nipy_spectral) |
|||
plt.savefig("Mercator_Mandelbrot_zoom.png", dpi=100)</syntaxhighlight> |
|||
'''Perturbation Theory and Deep Mercator Maps''' |
|||
For deep zoom images it is sufficient to calculate a single point with high accuracy. A good approximation can then be found for all other points by means of a perturbation calculation with standard accuracy. Rebasing is used to reduce glitches. See [https://en.wikipedia.org/wiki/Plotting_algorithms_for_the_Mandelbrot_set#Perturbation_theory_and_series_approximation Perturbation theory] (Wikipedia) and [https://gbillotey.github.io/Fractalshades-doc/math.html#avoiding-loss-of-precision Avoiding loss of precision] (Fractalshades) for details. See also the image [https://www.flickr.com/photos/arenamontanus/3430921497/in/album-72157615740829949/ Deeper Mercator Mandelbrot] by Anders Sandberg. |
|||
<syntaxhighlight lang="python">import numpy as np |
|||
import matplotlib.pyplot as plt |
|||
import decimal as dc # decimal floating point arithmetic with arbitrary precision |
|||
dc.getcontext().prec = 80 # set precision to 80 digits (about 256 bits) |
|||
d, h = 50, 1000 # pixel density (= image width) and image height |
|||
n, r = 80000, 100000 # number of iterations and escape radius (r > 2) |
|||
a = dc.Decimal("-1.256827152259138864846434197797294538253477389787308085590211144291") |
|||
b = dc.Decimal(".37933802890364143684096784819544060002129071484943239316486643285025") |
|||
S = np.zeros(n+1, dtype=np.complex128) |
|||
u, v = dc.Decimal(0), dc.Decimal(0) |
|||
for k in range(n+1): |
|||
S[k] = float(u) + float(v) * 1j |
|||
if u ** 2 + v ** 2 < r ** 2: |
|||
u, v = u ** 2 - v ** 2 + a, 2 * u * v + b |
|||
else: |
|||
print("The reference sequence diverges within %s iterations." % k) |
|||
break |
|||
x = np.linspace(0, 2, num=d+1, dtype=np.float64) |
|||
y = np.linspace(0, 2 * h / d, num=h+1, dtype=np.float64) |
|||
A, B = np.meshgrid(x * np.pi, y * np.pi) |
|||
C = 8.0 * np.exp((A + B * 1j) * 1j) |
|||
E, Z, dZ = np.zeros_like(C), np.zeros_like(C), np.zeros_like(C) |
|||
D, I, J = np.zeros(C.shape), np.zeros(C.shape, dtype=np.int64), np.zeros(C.shape, dtype=np.int64) |
|||
for k in range(n): |
|||
Z2 = Z.real ** 2 + Z.imag ** 2 |
|||
M, R = Z2 < r ** 2, Z2 < E.real ** 2 + E.imag ** 2 |
|||
E[R], I[R] = Z[R], J[R] # rebase when z is closer to zero |
|||
E[M], I[M] = (2 * S[I[M]] + E[M]) * E[M] + C[M], I[M] + 1 |
|||
Z[M], dZ[M] = S[I[M]] + E[M], 2 * Z[M] * dZ[M] + 1 |
|||
N = abs(Z) > 2 # exterior distance estimation |
|||
D[N] = np.log(abs(Z[N])) * abs(Z[N]) / abs(dZ[N]) |
|||
plt.imshow(D.T ** 0.015, cmap=plt.cm.nipy_spectral, origin="lower") |
|||
plt.savefig("Mercator_Mandelbrot_deep_map.png", dpi=200)</syntaxhighlight> |
|||
You can only rebase to the beginning of the reference sequence. If you want to change from current reference point <math>S_i</math> to reference point <math>S_j</math>, the difference <math>\epsilon_j = z - s_j</math> must be calculated. With this subtraction, however, the entire precision is lost due to [https://en.wikipedia.org/wiki/Catastrophic_cancellation catastrophic cancellation]. Only at the first reference point <math>S_0 = (0, 0)</math> there is no cancellation because <math>\epsilon_0 = z - s_0 = z - 0 = z</math>. Therefore, the rebasing condition <math>|z| < |\epsilon_i|</math> can also be written as <math>|\epsilon_0| < |\epsilon_i|</math> or as <math>|z - s_0| < |z - s_i|</math>. This keeps the differences to the reference sequence as small as possible: rebasing occurs when the distance to reference point <math>S_0</math> is smaller than the distance to the current reference point <math>S_i</math>. |
|||
===Python - "One liner"=== |
|||
<syntaxhighlight lang="python"> |
|||
print( |
|||
'\n'.join( |
|||
''.join( |
|||
' *'[(z:=0, c:=x/50+y/50j, [z:=z*z+c for _ in range(99)], abs(z))[-1]<2] |
|||
for x in range(-100,25) |
|||
) |
|||
for y in range(-50,50) |
|||
)) |
|||
</syntaxhighlight> |
|||
===Python - "Functional"=== |
|||
Based on the "One liner" approach. |
|||
<syntaxhighlight lang="python"> |
|||
from functools import reduce |
|||
def mandelbrot(x, y, c): return ' *'[abs(reduce(lambda z, _: z*z + c, range(99), 0)) < 2] |
|||
print('\n'.join(''.join(mandelbrot(x, y, x/50 + y/50j) for x in range(-100, 25)) for y in range(-50, 50))) |
|||
</syntaxhighlight> |
|||
=={{header|q}}== |
|||
<syntaxhighlight lang="q">/adapted from https://www.linkedin.com/pulse/want-work-k-1010data-michal-wallace |
|||
q)s:{(.[-]x*x),2*prd x} / complex square (x is R,Im pair) |
|||
q)m:{floor sqrt sum x*x} / magnitude (distance from origin) |
|||
q)d: 120 60 / dimensions of the picture |
|||
q)t: -88 -30 / camera translation |
|||
q)f: reciprocal 40 20 / scale factor |
|||
q)c: (,/:\:) . f * t + til each d / complex plane near mandelbrot set |
|||
q)z: d # enlist 0 0 / 3d array of zeroes in same shape |
|||
q)mb: c+ (s'')@ / mandelbrot: s(z) + c |
|||
q)r: 1 _ 8 mb\z / collect 8 times |
|||
q)o: " 12345678"@ sum 2<m'''[r] / "color" by how soon point "escapes" |
|||
q)-1 "\n"sv flip o; / transpose and print the output |
|||
</syntaxhighlight> |
|||
<pre>555555555555555555555556666666666666665555555555555555555555555555555555555555555555555555555555555666666666666666666666 |
|||
555555555555555555556666666666666555555555555555555555555555555555555555555555555555555555555555555555556666666666666666 |
|||
555555555555555556666666666666555555555555555555555555555555555555555555555555555555555555555555555555555556666666666666 |
|||
555555555555555666666666665555555555555555555555555555555555555555555556666666666666666666555555555555555555555666666666 |
|||
555555555555666666666666555555555555555555555555555555555555555556666666666666666666666666666665555555555555555556666666 |
|||
555555555566666666666555555555555555555555555555555555555555566666666555555555555555555555566666665555555555555555556666 |
|||
555555556666666666655555555555555555555555555555555555556666666655555555555555555555555555555555666665555555555555555566 |
|||
555555666666666655555555555555555555555555555555555566666666555555555555555554444444444555555555555666665555555555555555 |
|||
55556666666666555555555555555555555555555555555566666666555555555555555555444432 13344444555555555555666655555555555555 |
|||
556666666666655555555555555555555555555555555666666665555555555555555554444443321 1222234445555555555556666655555555555 |
|||
666666666665555555555555555555555555555556666666665555555555555555555444444433321 3344455555555555566666555555555 |
|||
666666666555555555555555555555555555556666666665555555555555555555544444443332211 22334444455555555555666655555555 |
|||
666666665555555555555555555555555566666666665555555555555555555544444444333321 12233444444555555555566666555555 |
|||
6666665555555555555555555555555666666666665555555555555555555444444443333322 123334444444555555555666655555 |
|||
6666655555555555555555555555666666666665555555555555555554444444433333332221 22333344444445555555566666555 |
|||
666655555555555555555555566666666666555555555555555554444444443333322222211 11223333333444455555556666655 |
|||
666555555555555555555556666666666555555555555555544444444444332111 111 11222222 23444555555666665 |
|||
665555555555555555556666666666555555555555555444444444444333321 11 2334455555566666 |
|||
655555555555555555666666665555555555555544444444444444433333221 134445555556666 |
|||
555555555555555566666665555555555555544444444444444433333332211 234444555555666 |
|||
555555555555556666655555555555555444444444444333333333332221 1233444555555566 |
|||
55555555555566665555555555555544444332233333333333322222211 1223344455555566 |
|||
5555555555666555555555555554444443331 1122222111122222111 2344455555556 |
|||
5555555566655555555555555444444433321 1 344455555556 |
|||
5555555666555555555555544444444333221 12334455555555 |
|||
5555566655555555555554444444433332221 2344445555555 |
|||
555566655555555555444444443333322111 12344445555555 |
|||
5556665555555554444443333333221 23344445555555 |
|||
556666555544444443333333322221 233344445555555 |
|||
55666555444333322 122111111 12233444445555555 |
|||
55666555 12233444445555555 |
|||
55666555444333322 122111111 12233444445555555 |
|||
556666555544444443333333322221 233344445555555 |
|||
5556665555555554444443333333221 23344445555555 |
|||
555566655555555555444444443333322111 12344445555555 |
|||
5555566655555555555554444444433332221 2344445555555 |
|||
5555555666555555555555544444444333221 12334455555555 |
|||
5555555566655555555555555444444433321 1 344455555556 |
|||
5555555555666555555555555554444443331 1122222111122222111 2344455555556 |
|||
55555555555566665555555555555544444332233333333333322222211 1223344455555566 |
|||
555555555555556666655555555555555444444444444333333333332221 1233444555555566 |
|||
555555555555555566666665555555555555544444444444444433333332211 234444555555666 |
|||
655555555555555555666666665555555555555544444444444444433333221 134445555556666 |
|||
665555555555555555556666666666555555555555555444444444444333321 11 2334455555566666 |
|||
666555555555555555555556666666666555555555555555544444444444332111 111 11222222 23444555555666665 |
|||
666655555555555555555555566666666666555555555555555554444444443333322222211 11223333333444455555556666655 |
|||
6666655555555555555555555555666666666665555555555555555554444444433333332221 22333344444445555555566666555 |
|||
6666665555555555555555555555555666666666665555555555555555555444444443333322 123334444444555555555666655555 |
|||
666666665555555555555555555555555566666666665555555555555555555544444444333321 12233444444555555555566666555555 |
|||
666666666555555555555555555555555555556666666665555555555555555555544444443332211 22334444455555555555666655555555 |
|||
666666666665555555555555555555555555555556666666665555555555555555555444444433321 3344455555555555566666555555555 |
|||
556666666666655555555555555555555555555555555666666665555555555555555554444443321 1222234445555555555556666655555555555 |
|||
55556666666666555555555555555555555555555555555566666666555555555555555555444432 13344444555555555555666655555555555555 |
|||
555555666666666655555555555555555555555555555555555566666666555555555555555554444444444555555555555666665555555555555555 |
|||
555555556666666666655555555555555555555555555555555555556666666655555555555555555555555555555555666665555555555555555566 |
|||
555555555566666666666555555555555555555555555555555555555555566666666555555555555555555555566666665555555555555555556666 |
|||
555555555555666666666666555555555555555555555555555555555555555556666666666666666666666666666665555555555555555556666666 |
|||
555555555555555666666666665555555555555555555555555555555555555555555556666666666666666666555555555555555555555666666666 |
|||
555555555555555556666666666666555555555555555555555555555555555555555555555555555555555555555555555555555556666666666666 |
|||
555555555555555555556666666666666555555555555555555555555555555555555555555555555555555555555555555555556666666666666666</pre> |
|||
=={{header|R}}== |
=={{header|R}}== |
||
< |
<syntaxhighlight lang="r">iterate.until.escape <- function(z, c, trans, cond, max=50, response=dwell) { |
||
#we iterate all active points in the same array operation, |
|||
x <- c() |
|||
#and keeping track of which points are still iterating. |
|||
y <- c() |
|||
active <- seq_along(z) |
|||
dwell <- z |
|||
while( Re(cost) <= Re(zto) ) { |
|||
dwell[] <- 0 |
|||
cost <- Re(cost) + Im(zfrom)*1i |
|||
for (i in 1:max) { |
|||
z[active] <- trans(z[active], c[active]); |
|||
j <- 0 |
|||
survived <- cond(z[active]) |
|||
dwell[active[!survived]] <- i |
|||
while( (abs(z) < 2) && (j < maxiter)) { |
|||
active <- active[survived] |
|||
if (length(active) == 0) break |
|||
} |
|||
if ( j == maxiter ) { |
|||
x <- c(x, Re(cost)) |
|||
y <- c(y, Im(cost)) |
|||
} |
|||
cost <- cost + inc*1i |
|||
} |
|||
cost <- cost + inc |
|||
} |
} |
||
eval(substitute(response)) |
|||
plot(x,y, pch=".") |
|||
} |
} |
||
re = seq(-2, 1, len=500) |
|||
createmandel(-2-1i, 1+1i)</lang> |
|||
im = seq(-1.5, 1.5, len=500) |
|||
c <- outer(re, im, function(x,y) complex(real=x, imaginary=y)) |
|||
x <- iterate.until.escape(array(0, dim(c)), c, |
|||
function(z,c)z^2+c, function(z)abs(z) <= 2, |
|||
max=100) |
|||
image(x)</syntaxhighlight> |
|||
===Mandelbrot Set with R Animation=== |
|||
Modified Mandelbrot set animation by Jarek Tuszynski, PhD. (see: [https://en.wikipedia.org/wiki/R_(programming_language)#Mandelbrot_set Wikipedia: R (programming_language)] and [https://rtricks.blogspot.com/2007/04/mandelbrot-set-with-r-animation.html R Tricks: Mandelbrot Set with R Animation]) |
|||
<syntaxhighlight lang="r">#install.packages("caTools") # install external package (if missing) |
|||
library(caTools) # external package providing write.gif function |
|||
jet.colors <- colorRampPalette(c("red", "blue", "#007FFF", "cyan", "#7FFF7F", |
|||
"yellow", "#FF7F00", "red", "#7F0000")) |
|||
dx <- 800 # define width |
|||
dy <- 600 # define height |
|||
C <- complex(real = rep(seq(-2.5, 1.5, length.out = dx), each = dy), |
|||
imag = rep(seq(-1.5, 1.5, length.out = dy), dx)) |
|||
C <- matrix(C, dy, dx) # reshape as square matrix of complex numbers |
|||
Z <- 0 # initialize Z to zero |
|||
X <- array(0, c(dy, dx, 20)) # initialize output 3D array |
|||
for (k in 1:20) { # loop with 20 iterations |
|||
Z <- Z^2 + C # the central difference equation |
|||
X[, , k] <- exp(-abs(Z)) # capture results |
|||
} |
|||
write.gif(X, "Mandelbrot.gif", col = jet.colors, delay = 100)</syntaxhighlight> |
|||
=={{header|Racket}}== |
|||
<syntaxhighlight lang="racket"> |
|||
#lang racket |
|||
(require racket/draw) |
|||
(define (iterations a z i) |
|||
(define z′ (+ (* z z) a)) |
|||
(if (or (= i 255) (> (magnitude z′) 2)) |
|||
i |
|||
(iterations a z′ (add1 i)))) |
|||
(define (iter->color i) |
|||
(if (= i 255) |
|||
(make-object color% "black") |
|||
(make-object color% (* 5 (modulo i 15)) (* 32 (modulo i 7)) (* 8 (modulo i 31))))) |
|||
(define (mandelbrot width height) |
|||
(define target (make-bitmap width height)) |
|||
(define dc (new bitmap-dc% [bitmap target])) |
|||
(for* ([x width] [y height]) |
|||
(define real-x (- (* 3.0 (/ x width)) 2.25)) |
|||
(define real-y (- (* 2.5 (/ y height)) 1.25)) |
|||
(send dc set-pen (iter->color (iterations (make-rectangular real-x real-y) 0 0)) 1 'solid) |
|||
(send dc draw-point x y)) |
|||
(send target save-file "mandelbrot.png" 'png)) |
|||
(mandelbrot 300 200) |
|||
</syntaxhighlight> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{Works with|rakudo|2023.08-3-g2f8234c22}} |
|||
Using the [https://docs.raku.org/language/statement-prefixes#hyper,_race hyper statement prefix] for concurrency, the code below produces a [[Write ppm file|graymap]] to standard output. |
|||
[[File:mandelbrot-raku.jpg|300px|thumb|right]] |
|||
<syntaxhighlight lang=raku>constant MAX-ITERATIONS = 64; |
|||
my $width = +(@*ARGS[0] // 800); |
|||
my $height = $width + $width %% 2; |
|||
say "P2"; |
|||
say "$width $height"; |
|||
say MAX-ITERATIONS; |
|||
sub cut(Range $r, UInt $n where $n > 1 --> Seq) { |
|||
$r.min, * + ($r.max - $r.min) / ($n - 1) ... $r.max |
|||
} |
|||
my @re = cut(-2 .. 1/2, $width); |
|||
my @im = cut( 0 .. 5/4, 1 + ($height div 2)) X* 1i; |
|||
sub mandelbrot(Complex $z is copy, Complex $c --> Int) { |
|||
for 1 .. MAX-ITERATIONS { |
|||
$z = $z*$z + $c; |
|||
return $_ if $z.abs > 2; |
|||
} |
|||
return 0; |
|||
} |
|||
my @lines = hyper for @im X+ @re { |
|||
mandelbrot(0i, $_); |
|||
}.rotor($width); |
|||
.put for @lines[1..*].reverse; |
|||
.put for @lines;</syntaxhighlight> |
|||
<!-- # Not sure this version is that much modern or faster now. |
|||
Alternately, a more modern, faster version. |
|||
[[File:Mandelbrot-set-perl6.png|300px|thumb|right]] |
|||
<syntaxhighlight lang="perl6" line>use Image::PNG::Portable; |
|||
my ($w, $h) = 800, 800; |
|||
my $out = Image::PNG::Portable.new: :width($w), :height($h); |
|||
my $maxIter = 150; |
|||
my @re = scale(-2.05 .. 1.05, $h); |
|||
my @im = scale( -11/8 .. 11/8, $w) X* 1i; |
|||
for ^($w div 2) -> $x { |
|||
^$h .map: -> $y { |
|||
my $i = (mandelbrot( @re[$y] + @im[$x] ) / $maxIter) ** .25; |
|||
my @hsv = hsv2rgb($i, 1, ?$i).rotate; |
|||
$out.set: $x, $y, |@hsv; |
|||
$out.set: $w - 1 - $x, $y, |@hsv; |
|||
} |
|||
} |
|||
$out.write: 'Mandelbrot-set-perl6.png'; |
|||
sub scale (Range $r,Int $n) { $r.min, * + ($r.max - $r.min) / ($n - 1) ... $r.max } |
|||
sub mandelbrot(Complex $c) { |
|||
my $z = $c; |
|||
for ^$maxIter { |
|||
$z = $z * $z + $c; |
|||
.return if $z.abs > 2; |
|||
} |
|||
0 |
|||
} |
|||
sub hsv2rgb ( $h, $s, $v ){ |
|||
state %cache; |
|||
%cache{"$h|$s|$v"} //= do { |
|||
my $c = $v * $s; |
|||
my $x = $c * (1 - abs( (($h*6) % 2) - 1 ) ); |
|||
my $m = $v - $c; |
|||
[(do given $h { |
|||
when 0..^1/6 { $c, $x, 0 } |
|||
when 1/6..^1/3 { $x, $c, 0 } |
|||
when 1/3..^1/2 { 0, $c, $x } |
|||
when 1/2..^2/3 { 0, $x, $c } |
|||
when 2/3..^5/6 { $x, 0, $c } |
|||
when 5/6..1 { $c, 0, $x } |
|||
} ).map: ((*+$m) * 255).Int] |
|||
} |
|||
}</syntaxhighlight> |
|||
--> |
|||
=={{header|REXX}}== |
|||
===version 1=== |
|||
{{trans|AWK}} |
|||
This REXX version doesn't depend on the ASCII sequence of glyphs; an internal character string was used that mimics a part of the ASCII glyph sequence. |
|||
<syntaxhighlight lang="rexx">/*REXX program generates and displays a Mandelbrot set as an ASCII art character image.*/ |
|||
@ = '>=<;:9876543210/.-,+*)(''&%$#"!' /*the characters used in the display. */ |
|||
Xsize = 59; minRE = -2; maxRE = +1; stepX = (maxRE-minRE) / Xsize |
|||
Ysize = 21; minIM = -1; maxIM = +1; stepY = (maxIM-minIM) / Ysize |
|||
do y=0 for ysize; im=minIM + stepY*y |
|||
$= |
|||
do x=0 for Xsize; re=minRE + stepX*x; zr=re; zi=im |
|||
do n=0 for 30; a=zr**2; b=zi**2; if a+b>4 then leave |
|||
zi=zr*zi*2 + im; zr=a-b+re |
|||
end /*n*/ |
|||
$=$ || substr(@, n+1, 1) /*append number (as a char) to $ string*/ |
|||
end /*x*/ |
|||
say $ /*display a line of character output.*/ |
|||
end /*y*/ /*stick a fork in it, we're all done. */</syntaxhighlight> |
|||
'''output''' using the internal defaults: |
|||
<pre> |
|||
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<========== |
|||
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======= |
|||
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== |
|||
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== |
|||
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== |
|||
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== |
|||
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= |
|||
><<<<;;;;;:::972456-567763 +9;;<<<<<<< |
|||
><;;;;;;::::9875& .3 *9;;;<<<<<< |
|||
>;;;;;;::997564' ' 8:;;;<<<<<< |
|||
>::988897735/ &89:;;;<<<<<< |
|||
>::988897735/ &89:;;;<<<<<< |
|||
>;;;;;;::997564' ' 8:;;;<<<<<< |
|||
><;;;;;;::::9875& .3 *9;;;<<<<<< |
|||
><<<<;;;;;:::972456-567763 +9;;<<<<<<< |
|||
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= |
|||
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== |
|||
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== |
|||
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== |
|||
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== |
|||
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======= |
|||
</pre> |
|||
===version 2=== |
|||
This REXX version uses glyphs that are "darker" (with a white background) around the output's peripheral. |
|||
<syntaxhighlight lang="rexx">/*REXX program generates and displays a Mandelbrot set as an ASCII art character image.*/ |
|||
@ = '█▓▒░@9876543210=.-,+*)(·&%$#"!' /*the characters used in the display. */ |
|||
Xsize = 59; minRE = -2; maxRE = +1; stepX = (maxRE-minRE) / Xsize |
|||
Ysize = 21; minIM = -1; maxIM = +1; stepY = (maxIM-minIM) / Ysize |
|||
do y=0 for ysize; im=minIM + stepY*y |
|||
$= |
|||
do x=0 for Xsize; re=minRE + stepX*x; zr=re; zi=im |
|||
do n=0 for 30; a=zr**2; b=zi**2; if a+b>4 then leave |
|||
zi=zr*zi*2 + im; zr=a-b+re |
|||
end /*n*/ |
|||
$=$ || substr(@, n+1, 1) /*append number (as a char) to $ string*/ |
|||
end /*x*/ |
|||
say $ /*display a line of character output.*/ |
|||
end /*y*/ /*stick a fork in it, we're all done. */</syntaxhighlight> |
|||
'''output''' using the internal defaults: |
|||
<pre> |
|||
██████▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░@@@96032@░░░░▒▒▒▒▓▓▓▓▓▓▓▓▓▓ |
|||
█████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@@873*079@@░░░░▒▒▒▒▒▓▓▓▓▓▓▓ |
|||
████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@9974 (.9@@@@░░▒▒▒▒▒▓▓▓▓▓▓ |
|||
███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░@98888764 5789999@░░▒▒▒▒▒▓▓▓▓ |
|||
██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░@@@@996. &2 45335@░▒▒▒▒▒▒▓▓▓ |
|||
██▓▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@999752 *79@░▒▒▒▒▒▒▓▓ |
|||
█▓▒▒▒▒▒▒▒▒░░░@599999999886 %78@░░▒▒▒▒▒▒▓ |
|||
█▒▒▒▒░░░░░@@@972456-567763 +9░░▒▒▒▒▒▒▒ |
|||
█▒░░░░░░@@@@9875& .3 *9░░░▒▒▒▒▒▒ |
|||
█░░░░░░@@997564· · 8@░░░▒▒▒▒▒▒ |
|||
█@@988897735= &89@░░░▒▒▒▒▒▒ |
|||
█@@988897735= &89@░░░▒▒▒▒▒▒ |
|||
█░░░░░░@@997564· · 8@░░░▒▒▒▒▒▒ |
|||
█▒░░░░░░@@@@9875& .3 *9░░░▒▒▒▒▒▒ |
|||
█▒▒▒▒░░░░░@@@972456-567763 +9░░▒▒▒▒▒▒▒ |
|||
█▓▒▒▒▒▒▒▒▒░░░@599999999886 %78@░░▒▒▒▒▒▒▓ |
|||
██▓▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@999752 *79@░▒▒▒▒▒▒▓▓ |
|||
██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░@@@@996. &2 45335@░▒▒▒▒▒▒▓▓▓ |
|||
███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░@98888764 5789999@░░▒▒▒▒▒▓▓▓▓ |
|||
████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@9974 (.9@@@@░░▒▒▒▒▒▓▓▓▓▓▓ |
|||
█████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@@873*079@@░░░░▒▒▒▒▒▓▓▓▓▓▓▓ |
|||
</pre> |
|||
===version 3=== |
|||
This REXX version produces a larger output (it uses the full width of the terminal screen (less one), and the height is one-half of the width. |
|||
<syntaxhighlight lang="rexx">/*REXX program generates and displays a Mandelbrot set as an ASCII art character image.*/ |
|||
@ = '█▓▒░@9876543210=.-,+*)(·&%$#"!' /*the characters used in the display. */ |
|||
parse arg Xsize Ysize . /*obtain optional arguments from the CL*/ |
|||
if Xsize=='' then Xsize=linesize() - 1 /*X: the (usable) linesize (minus 1).*/ |
|||
if Ysize=='' then Ysize=Xsize%2 + (Xsize//2==1) /*Y: half the linesize (make it even).*/ |
|||
minRE = -2; maxRE = +1; stepX = (maxRE-minRE) / Xsize |
|||
minIM = -1; maxIM = +1; stepY = (maxIM-minIM) / Ysize |
|||
do y=0 for ysize; im=minIM + stepY*y |
|||
$= |
|||
do x=0 for Xsize; re=minRE + stepX*x; zr=re; zi=im |
|||
do n=0 for 30; a=zr**2; b=zi**2; if a+b>4 then leave |
|||
zi=zr*zi*2 + im; zr=a-b+re |
|||
end /*n*/ |
|||
$=$ || substr(@, n+1, 1) /*append number (as a char) to $ string*/ |
|||
end /*x*/ |
|||
say $ /*display a line of character output.*/ |
|||
end /*y*/ /*stick a fork in it, we're all done. */</syntaxhighlight> |
|||
'''output''' using the internal defaults: |
|||
<pre> |
|||
████████▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░@@@@985164(9@░░░░░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓ |
|||
███████▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@@@98763=5799@░░░░░░▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓ |
|||
███████▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@@98763.-2789@@@░░░░░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓ |
|||
██████▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@@985 2. 1448@@@@░░░░░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓ |
|||
█████▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@999874 *=79@@@@@░░░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓ |
|||
█████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@999998873 17899@@@@@░░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓ |
|||
████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@98888888764 #4678899999@@░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓ |
|||
████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@@@9343,665 322= =215357888709@░░▒▒▒▒▒▒▒▒▓▓▓▓▓ |
|||
███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░@@@@@9986 + 32 ,56554)79@░▒▒▒▒▒▒▒▒▒▓▓▓▓ |
|||
███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░@@@@@@@999863 + 2· ",59@░░▒▒▒▒▒▒▒▒▓▓▓▓ |
|||
███▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@@@@@9998763 $ 379@@░▒▒▒▒▒▒▒▒▒▓▓▓ |
|||
██▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@@@@@999986.2 $ +689@@░░▒▒▒▒▒▒▒▒▒▓▓ |
|||
██▓▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@689999@@@99999887 05789@░░▒▒▒▒▒▒▒▒▒▓▓ |
|||
██▒▒▒▒▒▒▒▒▒▒░░░░░@@9717888877888888763. 2558@░░░▒▒▒▒▒▒▒▒▒▓ |
|||
█▓▒▒▒▒▒▒░░░░░░░@@@996)566761467777762 4@░░░▒▒▒▒▒▒▒▒▒▓ |
|||
█▓▒▒▒▒░░░░░░░░@@@@99763 & 42&..366651· .68@░░░░▒▒▒▒▒▒▒▒▓ |
|||
█▒▒▒░░░░░░░░@@@@@@98864* ) $ 343 259@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█▒▒░░░░░░░░@@@@@@988753. 11 #9@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█▒░░░░░░░░@@@@@9877650 - 289@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█░░░░░░░░@9999887%413+ % &69@@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█░@@@@@89999888763 % ( 389@@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█@@99872676676422 5789@@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█@@99872676676422 5789@@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█░@@@@@89999888763 % ( 389@@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█░░░░░░░░@9999887%413+ % &69@@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█▒░░░░░░░░@@@@@9877650 - 289@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█▒▒░░░░░░░░@@@@@@988753. 11 #9@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█▒▒▒░░░░░░░░@@@@@@98864* ) $ 343 259@░░░░▒▒▒▒▒▒▒▒▒ |
|||
█▓▒▒▒▒░░░░░░░░@@@@99763 & 42&..366651· .68@░░░░▒▒▒▒▒▒▒▒▓ |
|||
█▓▒▒▒▒▒▒░░░░░░░@@@996)566761467777762 4@░░░▒▒▒▒▒▒▒▒▒▓ |
|||
██▒▒▒▒▒▒▒▒▒▒░░░░░@@9717888877888888763. 2558@░░░▒▒▒▒▒▒▒▒▒▓ |
|||
██▓▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@689999@@@99999887 05789@░░▒▒▒▒▒▒▒▒▒▓▓ |
|||
██▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@@@@@999986.2 $ +689@@░░▒▒▒▒▒▒▒▒▒▓▓ |
|||
███▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@@@@@9998763 $ 379@@░▒▒▒▒▒▒▒▒▒▓▓▓ |
|||
███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░@@@@@@@999863 + 2· ",59@░░▒▒▒▒▒▒▒▒▓▓▓▓ |
|||
███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░@@@@@9986 + 32 ,56554)79@░▒▒▒▒▒▒▒▒▒▓▓▓▓ |
|||
████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@@@9343,665 322= =215357888709@░░▒▒▒▒▒▒▒▒▓▓▓▓▓ |
|||
████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@98888888764 #4678899999@@░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓ |
|||
█████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@999998873 17899@@@@@░░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓ |
|||
█████▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@999874 *=79@@@@@░░░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓ |
|||
██████▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@@985 2. 1448@@@@░░░░░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓ |
|||
███████▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@@98763.-2789@@@░░░░░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓ |
|||
███████▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@@@98763=5799@░░░░░░▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓ |
|||
</pre> |
|||
This REXX program makes use of '''linesize''' REXX program (or BIF) which is used to determine the screen width (or linesize) of the terminal (console). |
|||
The '''LINESIZE.REX''' REXX program is included here ──► [[LINESIZE.REX]]. <br><br> |
|||
=={{header|Ring}}== |
|||
<syntaxhighlight lang="ring"> |
|||
load "guilib.ring" |
|||
new qapp |
|||
{ |
|||
win1 = new qwidget() { |
|||
setwindowtitle("Mandelbrot set") |
|||
setgeometry(100,100,500,500) |
|||
label1 = new qlabel(win1) { |
|||
setgeometry(10,10,400,400) |
|||
settext("") |
|||
} |
|||
new qpushbutton(win1) { |
|||
setgeometry(200,400,100,30) |
|||
settext("draw") |
|||
setclickevent("draw()") |
|||
} |
|||
show() |
|||
} |
|||
exec() |
|||
} |
|||
func draw |
|||
p1 = new qpicture() |
|||
color = new qcolor() { |
|||
setrgb(0,0,255,255) |
|||
} |
|||
pen = new qpen() { |
|||
setcolor(color) |
|||
setwidth(1) |
|||
} |
|||
new qpainter() { |
|||
begin(p1) |
|||
setpen(pen) |
|||
x1=300 y1=250 |
|||
i1=-1 i2=1 r1=-2 r2=1 |
|||
s1=(r2-r1)/x1 s2=(i2-i1)/y1 |
|||
for y=0 to y1 |
|||
i3=i1+s2*y |
|||
for x=0 to x1 |
|||
r3=r1+s1*x z1=r3 z2=i3 |
|||
for n=0 to 30 |
|||
a=z1*z1 b=z2*z2 |
|||
if a+b>4 exit ok |
|||
z2=2*z1*z2+i3 z1=a-b+r3 |
|||
next |
|||
if n != 31 drawpoint(x,y) ok |
|||
next |
|||
next |
|||
endpaint() |
|||
} |
|||
label1 { setpicture(p1) show() } |
|||
</syntaxhighlight> |
|||
Output: |
|||
[[File:CalmoSoftMandelbrot.jpg]] |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Text only, prints an 80-char by 41-line depiction. Found [http://www.xcombinator.com/2008/02/22/ruby-inject-and-the-mandelbrot-set/ here]. |
Text only, prints an 80-char by 41-line depiction. Found [http://www.xcombinator.com/2008/02/22/ruby-inject-and-the-mandelbrot-set/ here]. |
||
< |
<syntaxhighlight lang="ruby">require 'complex' |
||
def mandelbrot(a) |
def mandelbrot(a) |
||
Array.new(50 |
Array.new(50).inject(0) { |z,c| z*z + a } |
||
end |
end |
||
Line 957: | Line 12,065: | ||
end |
end |
||
puts |
puts |
||
end</ |
end</syntaxhighlight> |
||
{{trans|Tcl}} |
{{trans|Tcl}} |
||
Uses |
Uses [[Raster graphics operations/Ruby]] |
||
<syntaxhighlight lang="ruby"># frozen_string_literal: true |
|||
<lang ruby>class RGBColour |
|||
require_relative 'raster_graphics' |
|||
class RGBColour |
|||
def self.mandel_colour(i) |
def self.mandel_colour(i) |
||
self.new( 16*(i % 15), 32*(i % 7), 8*(i % 31) ) |
self.new( 16*(i % 15), 32*(i % 7), 8*(i % 31) ) |
||
Line 992: | Line 12,104: | ||
end |
end |
||
count |
count |
||
end |
end |
||
end |
end |
||
Pixmap.mandelbrot(300,300).save('mandel.ppm')</ |
Pixmap.mandelbrot(300,300).save('mandel.ppm')</syntaxhighlight> |
||
{{libheader|RubyGems}} |
|||
{{libheader|JRubyArt}} |
|||
JRubyArt is a port of processing to ruby |
|||
<syntaxhighlight lang="ruby"> |
|||
# frozen_string_literal: true |
|||
def setup |
|||
sketch_title 'Mandelbrot' |
|||
load_pixels |
|||
no_loop |
|||
end |
|||
def draw |
|||
grid(900, 600) do |x, y| |
|||
const = Complex( |
|||
map1d(x, (0...900), (-3..1.5)), map1d(y, (0...600), (-1.5..1.5)) |
|||
) |
|||
pixels[x + y * 900] = color( |
|||
constrained_map(mandel(const, 20), (5..20), (255..0)) |
|||
) |
|||
end |
|||
update_pixels |
|||
end |
|||
def mandel(z, max) |
|||
score = 0 |
|||
const = z |
|||
while score < max |
|||
# z = z^2 + c |
|||
z *= z |
|||
z += const |
|||
break if z.abs > 2 |
|||
score += 1 |
|||
end |
|||
score |
|||
end |
|||
def settings |
|||
size(900, 600) |
|||
end |
|||
</syntaxhighlight> |
|||
=={{header|Rust}}== |
|||
Dependencies: image, num-complex |
|||
<syntaxhighlight lang="rust">extern crate image; |
|||
extern crate num_complex; |
|||
use num_complex::Complex; |
|||
fn main() { |
|||
let max_iterations = 256u16; |
|||
let img_side = 800u32; |
|||
let cxmin = -2f32; |
|||
let cxmax = 1f32; |
|||
let cymin = -1.5f32; |
|||
let cymax = 1.5f32; |
|||
let scalex = (cxmax - cxmin) / img_side as f32; |
|||
let scaley = (cymax - cymin) / img_side as f32; |
|||
// Create a new ImgBuf |
|||
let mut imgbuf = image::ImageBuffer::new(img_side, img_side); |
|||
// Calculate for each pixel |
|||
for (x, y, pixel) in imgbuf.enumerate_pixels_mut() { |
|||
let cx = cxmin + x as f32 * scalex; |
|||
let cy = cymin + y as f32 * scaley; |
|||
let c = Complex::new(cx, cy); |
|||
let mut z = Complex::new(0f32, 0f32); |
|||
let mut i = 0; |
|||
for t in 0..max_iterations { |
|||
if z.norm() > 2.0 { |
|||
break; |
|||
} |
|||
z = z * z + c; |
|||
i = t; |
|||
} |
|||
*pixel = image::Luma([i as u8]); |
|||
} |
|||
// Save image |
|||
imgbuf.save("fractal.png").unwrap(); |
|||
}</syntaxhighlight> |
|||
=={{header|Sass/SCSS}}== |
|||
<syntaxhighlight lang="coffeescript"> |
|||
$canvasWidth: 200; |
|||
$canvasHeight: 200; |
|||
$iterations: 20; |
|||
$xCorner: -2; |
|||
$yCorner: -1.5; |
|||
$zoom: 3; |
|||
$data: ()!global; |
|||
@mixin plot ($x,$y,$count){ |
|||
$index: ($y * $canvasWidth + $x) * 4; |
|||
$r: $count * -12 + 255; |
|||
$g: $count * -12 + 255; |
|||
$b: $count * -12 + 255; |
|||
$data: append($data, $x + px $y + px 0 rgb($r,$g,$b), comma)!global; |
|||
} |
|||
@for $x from 1 to $canvasWidth { |
|||
@for $y from 1 to $canvasHeight { |
|||
$count: 0; |
|||
$size: 0; |
|||
$cx: $xCorner + (($x * $zoom) / $canvasWidth); |
|||
$cy: $yCorner + (($y * $zoom) / $canvasHeight); |
|||
$zx: 0; |
|||
$zy: 0; |
|||
@while $count < $iterations and $size <= 4 { |
|||
$count: $count + 1; |
|||
$temp: ($zx * $zx) - ($zy * $zy); |
|||
$zy: (2 * $zx * $zy) + $cy; |
|||
$zx: $temp + $cx; |
|||
$size: ($zx * $zx) + ($zy * $zy); |
|||
} |
|||
@include plot($x, $y, $count); |
|||
} |
|||
} |
|||
.set { |
|||
height: 1px; |
|||
width: 1px; |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate($canvasWidth*0.5px, $canvasWidth*0.5px); |
|||
box-shadow: $data; |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|Scala}}== |
|||
{{works with|Scala|2.8}} |
|||
Uses RgbBitmap from [[Basic_bitmap_storage#Scala|Basic Bitmap Storage]] task and Complex number class from [[Arithmetic/Complex#Scala|this]] |
|||
programming task. |
|||
<syntaxhighlight lang="scala">import org.rosettacode.ArithmeticComplex._ |
|||
import java.awt.Color |
|||
object Mandelbrot |
|||
{ |
|||
def generate(width:Int =600, height:Int =400)={ |
|||
val bm=new RgbBitmap(width, height) |
|||
val maxIter=1000 |
|||
val xMin = -2.0 |
|||
val xMax = 1.0 |
|||
val yMin = -1.0 |
|||
val yMax = 1.0 |
|||
val cx=(xMax-xMin)/width |
|||
val cy=(yMax-yMin)/height |
|||
for(y <- 0 until bm.height; x <- 0 until bm.width){ |
|||
val c=Complex(xMin+x*cx, yMin+y*cy) |
|||
val iter=itMandel(c, maxIter, 4) |
|||
bm.setPixel(x, y, getColor(iter, maxIter)) |
|||
} |
|||
bm |
|||
} |
|||
def itMandel(c:Complex, imax:Int, bailout:Int):Int={ |
|||
var z=Complex() |
|||
for(i <- 0 until imax){ |
|||
z=z*z+c; |
|||
if(z.abs > bailout) return i |
|||
} |
|||
imax; |
|||
} |
|||
def getColor(iter:Int, max:Int):Color={ |
|||
if (iter==max) return Color.BLACK |
|||
var c=3*math.log(iter)/math.log(max-1.0) |
|||
if(c<1) new Color((255*c).toInt, 0, 0) |
|||
else if(c<2) new Color(255, (255*(c-1)).toInt, 0) |
|||
else new Color(255, 255, (255*(c-2)).toInt) |
|||
} |
|||
}</syntaxhighlight> |
|||
Read–eval–print loop |
|||
<syntaxhighlight lang="scala">import scala.swing._ |
|||
import javax.swing.ImageIcon |
|||
val imgMandel=Mandelbrot.generate() |
|||
val mainframe=new MainFrame(){title="Test"; visible=true |
|||
contents=new Label(){icon=new ImageIcon(imgMandel.image)} |
|||
}</syntaxhighlight> |
|||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
===A simple implementation for many Scheme implementations=== |
|||
This implementation writes an image of the Mandelbrot set to a plain pgm file. The set itself is drawn in white, while the exterior is drawn in black. |
This implementation writes an image of the Mandelbrot set to a plain pgm file. The set itself is drawn in white, while the exterior is drawn in black. |
||
< |
<syntaxhighlight lang="scheme">(define x-centre -0.5) |
||
(define y-centre 0.0) |
(define y-centre 0.0) |
||
(define width 4.0) |
(define width 4.0) |
||
Line 1,016: | Line 12,324: | ||
(or (= n 0) |
(or (= n 0) |
||
(*inside? z-0 (+ (* z z) z-0) (- n 1))))) |
(*inside? z-0 (+ (* z z) z-0) (- n 1))))) |
||
(*inside? z |
(*inside? z 0 n)) |
||
(define (boolean->integer b) |
(define (boolean->integer b) |
||
Line 1,038: | Line 12,346: | ||
(begin (display (pixel i j)) (newline)))))))) |
(begin (display (pixel i j)) (newline)))))))) |
||
(plot)</ |
(plot)</syntaxhighlight> |
||
===An interactive program for CHICKEN Scheme=== |
|||
{{trans|ObjectIcon}} |
|||
{{works with|CHICKEN Scheme|5.3.0}} |
|||
You will need several CHICKEN "eggs", which can be deduced from the imports. |
|||
Compile with (for example) <code>csc -O3 mandelbrot_task_CHICKEN.scm</code>. |
|||
<syntaxhighlight lang="scheme"> |
|||
;; A program written for CHICKEN Scheme version 5.3.0 and various |
|||
;; eggs. |
|||
(import (r7rs)) |
|||
(import (scheme base)) |
|||
(import (scheme case-lambda)) |
|||
(import (scheme inexact)) |
|||
(import (prefix sdl2 "sdl2:")) |
|||
(import (prefix imlib2 "imlib2:")) |
|||
(import (format)) |
|||
(import (matchable)) |
|||
(import (simple-exceptions)) |
|||
(define sdl2-subsystems-used '(events video)) |
|||
;; ------------------------------ |
|||
;; Basics for using the sdl2 egg: |
|||
(sdl2:set-main-ready!) |
|||
(sdl2:init! sdl2-subsystems-used) |
|||
(on-exit sdl2:quit!) |
|||
(current-exception-handler |
|||
(let ((original-handler (current-exception-handler))) |
|||
(lambda (exception) |
|||
(sdl2:quit!) |
|||
(original-handler exception)))) |
|||
;; ------------------------------ |
|||
(define-record-type <mandel-params> |
|||
(%%make-mandel-params) |
|||
mandel-params? |
|||
(window ref-window set-window!) |
|||
(xcenter ref-xcenter set-xcenter!) |
|||
(ycenter ref-ycenter set-ycenter!) |
|||
(pixels-per-unit ref-pixels-per-unit set-pixels-per-unit!) |
|||
(pixels-per-event-check ref-pixels-per-event-check |
|||
set-pixels-per-event-check!) |
|||
(max-escape-time ref-max-escape-time set-max-escape-time!)) |
|||
(define initial-width 400) |
|||
(define initial-height 400) |
|||
(define initial-xcenter -3/4) |
|||
(define initial-ycenter 0) |
|||
(define initial-pixels-per-unit 150) |
|||
(define initial-pixels-per-event-check 1000) |
|||
(define initial-max-escape-time 1000) |
|||
(define (make-mandel-params window) |
|||
(let ((params (%%make-mandel-params))) |
|||
(set-window! params window) |
|||
(set-xcenter! params initial-xcenter) |
|||
(set-ycenter! params initial-ycenter) |
|||
(set-pixels-per-unit! params initial-pixels-per-unit) |
|||
(set-pixels-per-event-check! params |
|||
initial-pixels-per-event-check) |
|||
(set-max-escape-time! params initial-max-escape-time) |
|||
params)) |
|||
(define window (sdl2:create-window! "mandelbrot set task" |
|||
'centered 'centered |
|||
initial-width initial-height |
|||
'())) |
|||
(define params (make-mandel-params window)) |
|||
(define empty-color (sdl2:make-color 200 200 200)) |
|||
(define (clear-mandel!) |
|||
(sdl2:fill-rect! (sdl2:window-surface (ref-window params)) |
|||
#f empty-color) |
|||
(sdl2:update-window-surface! window)) |
|||
(define drawing? #t) |
|||
(define redraw? #f) |
|||
(define (draw-mandel! event-checker) |
|||
(clear-mandel!) |
|||
(let repeat () |
|||
(let*-values |
|||
(((window) (ref-window params)) |
|||
((width height) (sdl2:window-size window))) |
|||
(let* ((xcenter (ref-xcenter params)) |
|||
(ycenter (ref-ycenter params)) |
|||
(pixels-per-unit (ref-pixels-per-unit params)) |
|||
(pixels-per-event-check |
|||
(ref-pixels-per-event-check params)) |
|||
(max-escape-time (ref-max-escape-time params)) |
|||
(step (/ 1.0 pixels-per-unit)) |
|||
(xleft (- xcenter (/ width (* 2.0 pixels-per-unit)))) |
|||
(ytop (+ ycenter (/ height (* 2.0 pixels-per-unit)))) |
|||
(pixel-count 0)) |
|||
(do ((j 0 (+ j 1)) |
|||
(cy ytop (- cy step))) |
|||
((= j height)) |
|||
(do ((i 0 (+ i 1)) |
|||
(cx xleft (+ cx step))) |
|||
((= i width)) |
|||
(let* ((color (compute-color-by-escape-time-algorithm |
|||
cx cy max-escape-time))) |
|||
(sdl2:surface-set! (sdl2:window-surface window) |
|||
i j color) |
|||
(if (= pixel-count pixels-per-event-check) |
|||
(let ((event-checker (call/cc event-checker))) |
|||
(cond (redraw? |
|||
(set! redraw? #f) |
|||
(clear-mandel!) |
|||
(repeat))) |
|||
(set! pixel-count 0)) |
|||
(set! pixel-count (+ pixel-count 1))))) |
|||
;; Display a row. |
|||
(sdl2:update-window-surface! window)))) |
|||
(set! drawing? #f) |
|||
(repeat))) |
|||
(define (compute-color-by-escape-time-algorithm |
|||
cx cy max-escape-time) |
|||
(escape-time->color (compute-escape-time cx cy max-escape-time) |
|||
max-escape-time)) |
|||
(define (compute-escape-time cx cy max-escape-time) |
|||
(let loop ((x 0.0) |
|||
(y 0.0) |
|||
(iter 0)) |
|||
(if (= iter max-escape-time) |
|||
iter |
|||
(let ((xsquared (* x x)) |
|||
(ysquared (* y y))) |
|||
(if (< 4 (+ xsquared ysquared)) |
|||
iter |
|||
(let ((x (+ cx (- xsquared ysquared))) |
|||
(y (+ cy (* (+ x x) y)))) |
|||
(loop x y (+ iter 1)))))))) |
|||
(define (escape-time->color escape-time max-escape-time) |
|||
;; This is a very naive and ad hoc algorithm for choosing colors, |
|||
;; but hopefully will suffice for the task. With this algorithm, at |
|||
;; least one can zoom in and see some of the fractal-like structures |
|||
;; out on the filaments. |
|||
(let* ((initial-ppu initial-pixels-per-unit) |
|||
(ppu (ref-pixels-per-unit params)) |
|||
(fraction (* (/ (log escape-time) (log max-escape-time)))) |
|||
(fraction (if (= fraction 1.0) |
|||
fraction |
|||
(* fraction |
|||
(/ (log initial-ppu) |
|||
(log (max initial-ppu (* 0.05 ppu))))))) |
|||
(value (- 255 (min 255 (exact-rounded (* fraction 255)))))) |
|||
(sdl2:make-color value value value))) |
|||
(define (exact-rounded x) |
|||
(exact (round x))) |
|||
(define (event-loop) |
|||
(define event (sdl2:make-event)) |
|||
(define painter draw-mandel!) |
|||
(define zoom-ratio 2) |
|||
(define (recenter! xcoord ycoord) |
|||
(let*-values |
|||
(((window) (ref-window params)) |
|||
((width height) (sdl2:window-size window)) |
|||
((ppu) (ref-pixels-per-unit params))) |
|||
(set-xcenter! params |
|||
(+ (ref-xcenter params) |
|||
(/ (- (* 2.0 xcoord) width) (* 2.0 ppu)))) |
|||
(set-ycenter! params |
|||
(+ (ref-ycenter params) |
|||
(/ (- height (* 2.0 ycoord)) (* 2.0 ppu)))))) |
|||
(define (zoom-in!) |
|||
(let* ((ppu (ref-pixels-per-unit params)) |
|||
(ppu (* ppu zoom-ratio))) |
|||
(set-pixels-per-unit! params ppu))) |
|||
(define (zoom-out!) |
|||
(let* ((ppu (ref-pixels-per-unit params)) |
|||
(ppu (* (/ 1.0 zoom-ratio) ppu))) |
|||
(set-pixels-per-unit! params (max 1 ppu)))) |
|||
(define (restore-original-settings!) |
|||
(set-xcenter! params initial-xcenter) |
|||
(set-ycenter! params initial-ycenter) |
|||
(set-pixels-per-unit! params initial-pixels-per-unit) |
|||
(set-pixels-per-event-check! |
|||
params initial-pixels-per-event-check) |
|||
(set-max-escape-time! params initial-max-escape-time) |
|||
(set! zoom-ratio 2)) |
|||
(define dump-image! ; Really this should put up a dialog. |
|||
(let ((dump-number 1)) |
|||
(lambda () |
|||
(let*-values |
|||
(((window) (ref-window params)) |
|||
((width height) (sdl2:window-size window)) |
|||
((surface) (sdl2:window-surface window))) |
|||
(let ((filename (string-append "mandelbrot-image-" |
|||
(number->string dump-number) |
|||
".png")) |
|||
(img (imlib2:image-create width height))) |
|||
(do ((j 0 (+ j 1))) |
|||
((= j height)) |
|||
(do ((i 0 (+ i 1))) |
|||
((= i width)) |
|||
(let-values |
|||
(((r g b a) (sdl2:color->values |
|||
(sdl2:surface-ref surface i j)))) |
|||
(imlib2:image-draw-pixel |
|||
img (imlib2:color/rgba r g b a) i j)))) |
|||
(imlib2:image-alpha-set! img #f) |
|||
(imlib2:image-save img filename) |
|||
(format #t "~a written~%" filename) |
|||
(set! dump-number (+ dump-number 1))))))) |
|||
(let loop () |
|||
(when redraw? |
|||
(set! drawing? #t)) |
|||
(when drawing? |
|||
(set! painter (call/cc painter))) |
|||
(set! redraw? #f) |
|||
(if (not (sdl2:poll-event! event)) |
|||
(loop) |
|||
(begin |
|||
(match (sdl2:event-type event) |
|||
('quit) ; Quit by leaving the loop. |
|||
('window |
|||
(match (sdl2:window-event-event event) |
|||
;; It should be possible to resize the window, but I |
|||
;; have not yet figured out how to do this with SDL2 |
|||
;; and not crash sometimes. |
|||
((or 'exposed 'restored) |
|||
(sdl2:update-window-surface! (ref-window params)) |
|||
(loop)) |
|||
(_ (loop)))) |
|||
('mouse-button-down |
|||
(recenter! (sdl2:mouse-button-event-x event) |
|||
(sdl2:mouse-button-event-y event)) |
|||
(set! redraw? #t) |
|||
(loop)) |
|||
('key-down |
|||
(match (sdl2:keyboard-event-sym event) |
|||
('q 'quit-by-leaving-the-loop) |
|||
((or 'plus 'kp-plus) |
|||
(zoom-in!) |
|||
(set! redraw? #t) |
|||
(loop)) |
|||
((or 'minus 'kp-minus) |
|||
(zoom-out!) |
|||
(set! redraw? #t) |
|||
(loop)) |
|||
((or 'n-2 'kp-2) |
|||
(set! zoom-ratio 2) |
|||
(loop)) |
|||
((or 'n-3 'kp-3) |
|||
(set! zoom-ratio 3) |
|||
(loop)) |
|||
((or 'n-4 'kp-4) |
|||
(set! zoom-ratio 4) |
|||
(loop)) |
|||
((or 'n-5 'kp-5) |
|||
(set! zoom-ratio 5) |
|||
(loop)) |
|||
((or 'n-6 'kp-6) |
|||
(set! zoom-ratio 6) |
|||
(loop)) |
|||
((or 'n-7 'kp-7) |
|||
(set! zoom-ratio 7) |
|||
(loop)) |
|||
((or 'n-8 'kp-8) |
|||
(set! zoom-ratio 8) |
|||
(loop)) |
|||
((or 'n-9 'kp-9) |
|||
(set! zoom-ratio 9) |
|||
(loop)) |
|||
('o |
|||
(restore-original-settings!) |
|||
(set! redraw? #t) |
|||
(loop)) |
|||
('p |
|||
(dump-image!) |
|||
(loop)) |
|||
(some-key-in-which-we-are-not-interested |
|||
(loop)))) |
|||
(some-event-in-which-we-are-not-interested |
|||
(loop))))))) |
|||
;; At the least this legend should go in a window, but printing it to |
|||
;; the terminal will, hopefully, suffice for the task. |
|||
(format #t "~%~8tACTIONS~%") |
|||
(format #t "~8t-------~%") |
|||
(define fmt "~2t~a~15t: ~a~%") |
|||
(format #t fmt "Q key" "quit") |
|||
(format #t fmt "mouse button" "recenter") |
|||
(format #t fmt "+ key" "zoom in") |
|||
(format #t fmt "- key" "zoom in") |
|||
(format #t fmt "2 .. 9 key" "set zoom ratio") |
|||
(format #t fmt "O key" "restore original") |
|||
(format #t fmt "P key" "dump to a PNG") |
|||
(format #t "~%") |
|||
(event-loop) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
An example of a PNG dumped by the program while it was zoomed in: |
|||
[[File:Mandelbrot task CHICKEN sampleimage.png|thumb|none|alt=A zoomed-in picture of a part of the Mandelbrot set.]] |
|||
=={{header|Scratch}}== |
|||
[[File:scratch-mandelbrot.gif]] |
|||
=={{header|Seed7}}== |
|||
<pre> |
|||
$ include "seed7_05.s7i"; |
|||
include "float.s7i"; |
|||
include "complex.s7i"; |
|||
include "draw.s7i"; |
|||
include "keybd.s7i"; |
|||
# Display the Mandelbrot set, that are points z[0] in the complex plane |
|||
# for which the sequence z[n+1] := z[n] ** 2 + z[0] (n >= 0) is bounded. |
|||
# Since this program is computing intensive it should be compiled with |
|||
# s7c -O2 mandelbr |
|||
const integer: pix is 200; |
|||
const integer: max_iter is 256; |
|||
var array color: colorTable is max_iter times black; |
|||
const func integer: iterate (in complex: z0) is func |
|||
result |
|||
var integer: iter is 1; |
|||
local |
|||
var complex: z is complex.value; |
|||
begin |
|||
z := z0; |
|||
while sqrAbs(z) < 4.0 and # not diverged |
|||
iter < max_iter do # not converged |
|||
z *:= z; |
|||
z +:= z0; |
|||
incr(iter); |
|||
end while; |
|||
end func; |
|||
const proc: displayMandelbrotSet (in complex: center, in float: zoom) is func |
|||
local |
|||
var integer: x is 0; |
|||
var integer: y is 0; |
|||
var complex: z0 is complex.value; |
|||
begin |
|||
for x range -pix to pix do |
|||
for y range -pix to pix do |
|||
z0 := center + complex(flt(x) * zoom, flt(y) * zoom); |
|||
point(x + pix, y + pix, colorTable[iterate(z0)]); |
|||
end for; |
|||
end for; |
|||
end func; |
|||
const proc: main is func |
|||
local |
|||
const integer: num_pix is 2 * pix + 1; |
|||
var integer: col is 0; |
|||
begin |
|||
screen(num_pix, num_pix); |
|||
clear(curr_win, black); |
|||
KEYBOARD := GRAPH_KEYBOARD; |
|||
for col range 1 to pred(max_iter) do |
|||
colorTable[col] := color(65535 - (col * 5003) mod 65535, |
|||
(col * 257) mod 65535, |
|||
(col * 2609) mod 65535); |
|||
end for; |
|||
displayMandelbrotSet(complex(-0.75, 0.0), 1.3 / flt(pix)); |
|||
flushGraphic; |
|||
readln(KEYBOARD); |
|||
end func; |
|||
</pre> |
|||
Original source: [http://seed7.sourceforge.net/algorith/graphic.htm#mandelbr] |
|||
=={{header|SenseTalk}}== |
|||
<syntaxhighlight lang="sensetalk">put 0 into oReal # Real origin |
|||
put 0 into oImag # Imaginary origin |
|||
put 0.5 into mag # Magnification |
|||
put oReal - .8 / mag into leftReal |
|||
put oImag + .5 / mag into topImag |
|||
put 1 / 200 / mag into inc |
|||
put [ |
|||
(0,255,255), # aqua |
|||
(0,0,255), # blue |
|||
(255,0,255), # fuchsia |
|||
(128,128,128), # gray |
|||
(0,128,0), # green |
|||
(0,255,0), # lime |
|||
(128,0,0), # maroon |
|||
(0,0,128), # navy |
|||
(128,128,0), # olive |
|||
(128,0,128), # purple |
|||
(255,0,0), # red |
|||
(192,192,192), # silver |
|||
(0,128,128), # teal |
|||
(255,255,255), # white |
|||
(255,255,0) # yellow |
|||
] into colors |
|||
put "mandelbrot.ppm" into myFile |
|||
open file myFile for writing |
|||
write "P3" & return to file myFile # PPM file magic number |
|||
write "320 200" & return to file myFile # Width and height |
|||
write "255" & return to file myFile # Max value in color channels |
|||
put topImag into cImag |
|||
repeat with each item in 1 .. 200 |
|||
put leftReal into cReal |
|||
repeat with each item in 1 .. 320 |
|||
put 0 into zReal |
|||
put 0 into zImag |
|||
put 0 into count |
|||
put 0 into size |
|||
repeat at least once until size > 2 or count = 100 |
|||
put zReal squared + zImag squared * -1 into newZreal |
|||
put zReal * zImag + zReal * zImag into newZimag |
|||
put newZreal + cReal into zReal |
|||
put newZimag + cImag into zImag |
|||
put sqrt(zReal squared + zImag squared) into size |
|||
add 1 to count |
|||
end repeat |
|||
if size > 2 then # Outside the set - colorize |
|||
put item count mod 15 + 1 of colors into color |
|||
write color joined by " " to file myFile |
|||
write return to file myFile |
|||
else # Inside the set - black |
|||
write "0 0 0" & return to file myFile |
|||
end if |
|||
add inc to cReal |
|||
end repeat |
|||
subtract inc from cImag |
|||
end repeat |
|||
close file myFile |
|||
</syntaxhighlight> |
|||
=={{header|SequenceL}}== |
|||
'''SequenceL Code for Computing and Coloring:'''<br> |
|||
<syntaxhighlight lang="sequencel">import <Utilities/Complex.sl>; |
|||
import <Utilities/Sequence.sl>; |
|||
import <Utilities/Math.sl>; |
|||
COLOR_STRUCT ::= (R: int(0), G: int(0), B: int(0)); |
|||
rgb(r(0), g(0), b(0)) := (R: r, G: g, B: b); |
|||
RESULT_STRUCT ::= (FinalValue: Complex(0), Iterations: int(0)); |
|||
makeResult(val(0), iters(0)) := (FinalValue: val, Iterations: iters); |
|||
zSquaredOperation(startingNum(0), currentNum(0)) := |
|||
complexAdd(startingNum, complexMultiply(currentNum, currentNum)); |
|||
zSquared(minX(0), maxX(0), resolutionX(0), minY(0), maxY(0), resolutionY(0), maxMagnitude(0), maxIters(0))[Y,X] := |
|||
let |
|||
stepX := (maxX - minX) / resolutionX; |
|||
stepY := (maxY - minY) / resolutionY; |
|||
currentX := X * stepX + minX; |
|||
currentY := Y * stepY + minY; |
|||
in |
|||
operateUntil(zSquaredOperation, makeComplex(currentX, currentY), makeComplex(currentX, currentY), maxMagnitude, 0, maxIters) |
|||
foreach Y within 0 ... (resolutionY - 1), |
|||
X within 0 ... (resolutionX - 1); |
|||
operateUntil(operation(0), startingNum(0), currentNum(0), maxMagnitude(0), currentIters(0), maxIters(0)) := |
|||
let |
|||
operated := operation(startingNum, currentNum); |
|||
in |
|||
makeResult(currentNum, maxIters) when currentIters >= maxIters |
|||
else |
|||
makeResult(currentNum, currentIters) when complexMagnitude(currentNum) >= maxMagnitude |
|||
else |
|||
operateUntil(operation, startingNum, operated, maxMagnitude, currentIters + 1, maxIters); |
|||
//region Smooth Coloring |
|||
COLOR_COUNT := size(colorSelections); |
|||
colorRange := range(0, 255, 1); |
|||
colors := |
|||
let |
|||
first[i] := rgb(0, 0, i) foreach i within colorRange; |
|||
second[i] := rgb(i, i, 255) foreach i within colorRange; |
|||
third[i] := rgb(255, 255, i) foreach i within reverse(colorRange); |
|||
fourth[i] := rgb(255, i, 0) foreach i within reverse(colorRange); |
|||
fifth[i] := rgb(i, 0, 0) foreach i within reverse(colorRange); |
|||
red[i] := rgb(i, 0, 0) foreach i within colorRange; |
|||
redR[i] := rgb(i, 0, 0) foreach i within reverse(colorRange); |
|||
green[i] := rgb(0, i, 0) foreach i within colorRange; |
|||
greenR[i] :=rgb(0, i, 0) foreach i within reverse(colorRange); |
|||
blue[i] := rgb(0, 0, i) foreach i within colorRange; |
|||
blueR[i] := rgb(0, 0, i) foreach i within reverse(colorRange); |
|||
in |
|||
//red ++ redR ++ green ++ greenR ++ blue ++ blueR; |
|||
first ++ second ++ third ++ fourth ++ fifth; |
|||
//first ++ fourth; |
|||
colorSelections := range(1, size(colors), 30); |
|||
getSmoothColorings(zSquaredResult(2), maxIters(0))[Y,X] := |
|||
let |
|||
current := zSquaredResult[Y,X]; |
|||
zn := complexMagnitude(current.FinalValue); |
|||
nu := ln(ln(zn) / ln(2)) / ln(2); |
|||
result := abs(current.Iterations + 1 - nu); |
|||
index := floor(result); |
|||
rem := result - index; |
|||
color1 := colorSelections[(index mod COLOR_COUNT) + 1]; |
|||
color2 := colorSelections[((index + 1) mod COLOR_COUNT) + 1]; |
|||
in |
|||
rgb(0, 0, 0) when current.Iterations = maxIters |
|||
else |
|||
colors[color1] when color2 < color1 |
|||
else |
|||
colors[floor(linearInterpolate(color1, color2, rem))]; |
|||
linearInterpolate(v0(0), v1(0), t(0)) := (1 - t) * v0 + t * v1; |
|||
//endregion</syntaxhighlight> |
|||
'''C++ Driver Code:'''<br> |
|||
{{libheader|CImg}} |
|||
<syntaxhighlight lang="c">#include "SL_Generated.h" |
|||
#include "../../../ThirdParty/CImg/CImg.h" |
|||
using namespace std; |
|||
using namespace cimg_library; |
|||
int main(int argc, char ** argv) |
|||
{ |
|||
int cores = 0; |
|||
Sequence<Sequence<_sl_RESULT_STRUCT> > computeResult; |
|||
Sequence<Sequence<_sl_COLOR_STRUCT> > colorResult; |
|||
sl_init(cores); |
|||
int maxIters = 1000; |
|||
int imageWidth = 1920; |
|||
int imageHeight = 1200; |
|||
double maxMag = 256; |
|||
double xmin = -2.5; |
|||
double xmax = 1.0; |
|||
double ymin = -1.0; |
|||
double ymax = 1.0; |
|||
CImg<unsigned char> visu(imageWidth, imageHeight, 1, 3); |
|||
CImgDisplay draw_disp(visu, "Mandelbrot Fractal in SequenceL"); |
|||
bool redraw = true; |
|||
SLTimer t; |
|||
double computeTime; |
|||
double colorTime; |
|||
double renderTime; |
|||
while(!draw_disp.is_closed()) |
|||
{ |
|||
if(redraw) |
|||
{ |
|||
redraw = false; |
|||
t.start(); |
|||
sl_zSquared(xmin, xmax, imageWidth, ymin, ymax, imageHeight, maxMag, maxIters, cores, computeResult); |
|||
t.stop(); |
|||
computeTime = t.getTime(); |
|||
t.start(); |
|||
sl_getSmoothColorings(computeResult, maxIters, cores, colorResult); |
|||
t.stop(); |
|||
colorTime = t.getTime(); |
|||
t.start(); |
|||
visu.fill(0); |
|||
for(int i = 1; i <= colorResult.size(); i++) |
|||
{ |
|||
for(int j = 1; j <= colorResult[i].size(); j++) |
|||
{ |
|||
visu(j-1,i-1,0,0) = colorResult[i][j].R; |
|||
visu(j-1,i-1,0,1) = colorResult[i][j].G; |
|||
visu(j-1,i-1,0,2) = colorResult[i][j].B; |
|||
} |
|||
} |
|||
visu.display(draw_disp); |
|||
t.stop(); |
|||
renderTime = t.getTime(); |
|||
draw_disp.set_title("X:[%f, %f] Y:[%f, %f] | Mandelbrot Fractal in SequenceL | Compute Time: %f | Color Time: %f | Render Time: %f | Total FPS: %f", xmin, xmax, ymin, ymax, cores, computeTime, colorTime, renderTime, 1 / (computeTime + colorTime + renderTime)); |
|||
} |
|||
draw_disp.wait(); |
|||
double xdiff = (xmax - xmin); |
|||
double ydiff = (ymax - ymin); |
|||
double xcenter = ((1.0 * draw_disp.mouse_x()) / imageWidth) * xdiff + xmin; |
|||
double ycenter = ((1.0 * draw_disp.mouse_y()) / imageHeight) * ydiff + ymin; |
|||
if(draw_disp.button()&1) |
|||
{ |
|||
redraw = true; |
|||
xmin = xcenter - (xdiff / 4); |
|||
xmax = xcenter + (xdiff / 4); |
|||
ymin = ycenter - (ydiff / 4); |
|||
ymax = ycenter + (ydiff / 4); |
|||
} |
|||
else if(draw_disp.button()&2) |
|||
{ |
|||
redraw = true; |
|||
xmin = xcenter - xdiff; |
|||
xmax = xcenter + xdiff; |
|||
ymin = ycenter - ydiff; |
|||
ymax = ycenter + ydiff; |
|||
} |
|||
} |
|||
sl_done(); |
|||
return 0; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
[https://i.imgur.com/xeM4u9O.png Output Screenshot] |
|||
=={{header|Sidef}}== |
|||
<syntaxhighlight lang="ruby">func mandelbrot(z) { |
|||
var c = z |
|||
{ z = (z*z + c) |
|||
z.abs > 2 && return true |
|||
} * 20 |
|||
return false |
|||
} |
|||
for y range(1, -1, -0.05) { |
|||
for x in range(-2, 0.5, 0.0315) { |
|||
print(mandelbrot(x + y.i) ? ' ' : '#') |
|||
} |
|||
print "\n" |
|||
}</syntaxhighlight> |
|||
=={{header|Simula}}== |
|||
{{trans|Scheme}} |
|||
<syntaxhighlight lang="simula">BEGIN |
|||
REAL XCENTRE, YCENTRE, WIDTH, RMAX, XOFFSET, YOFFSET, PIXELSIZE; |
|||
INTEGER N, IMAX, JMAX, COLOURMAX; |
|||
TEXT FILENAME; |
|||
CLASS COMPLEX(RE,IM); REAL RE,IM;; |
|||
REF(COMPLEX) PROCEDURE ADD(A,B); REF(COMPLEX) A,B; |
|||
ADD :- NEW COMPLEX(A.RE + B.RE, A.IM + B.IM); |
|||
REF(COMPLEX) PROCEDURE SUB(A,B); REF(COMPLEX) A,B; |
|||
SUB :- NEW COMPLEX(A.RE - B.RE, A.IM - B.IM); |
|||
REF(COMPLEX) PROCEDURE MUL(A,B); REF(COMPLEX) A,B; |
|||
MUL :- NEW COMPLEX(A.RE * B.RE - A.IM * B.IM, |
|||
A.RE * B.IM + A.IM * B.RE); |
|||
REF(COMPLEX) PROCEDURE DIV(A,B); REF(COMPLEX) A,B; |
|||
BEGIN |
|||
REAL TMP; |
|||
TMP := B.RE * B.RE + B.IM * B.IM; |
|||
DIV :- NEW COMPLEX((A.RE * B.RE + A.IM * B.IM) / TMP, |
|||
(A.IM * B.RE - A.RE * B.IM) / TMP); |
|||
END DIV; |
|||
REF(COMPLEX) PROCEDURE RECTANGULAR(RE,IM); REAL RE,IM; |
|||
RECTANGULAR :- NEW COMPLEX(RE,IM); |
|||
REAL PROCEDURE MAGNITUDE(CX); REF(COMPLEX) CX; |
|||
MAGNITUDE := SQRT(CX.RE**2 + CX.IM**2); |
|||
BOOLEAN PROCEDURE INSIDEP(Z); REF(COMPLEX) Z; |
|||
BEGIN |
|||
BOOLEAN PROCEDURE INSIDE(Z0,Z,N); REAL N; REF(COMPLEX) Z,Z0; |
|||
INSIDE := MAGNITUDE(Z) < RMAX |
|||
AND THEN N = 0 OR ELSE INSIDE(Z0, ADD(Z0,MUL(Z,Z)), N-1); |
|||
INSIDEP := INSIDE(Z, NEW COMPLEX(0,0), N); |
|||
END INSIDEP; |
|||
INTEGER PROCEDURE BOOL2INT(B); BOOLEAN B; |
|||
BOOL2INT := IF B THEN COLOURMAX ELSE 0; |
|||
INTEGER PROCEDURE PIXEL(I,J); INTEGER I,J; |
|||
PIXEL := BOOL2INT(INSIDEP(RECTANGULAR(XOFFSET + PIXELSIZE * I, |
|||
YOFFSET - PIXELSIZE * J))); |
|||
PROCEDURE PLOT; |
|||
BEGIN |
|||
REF (OUTFILE) OUTF; |
|||
INTEGER J,I; |
|||
OUTF :- NEW OUTFILE(FILENAME); |
|||
OUTF.OPEN(BLANKS(132)); |
|||
OUTF.OUTTEXT("P2"); OUTF.OUTIMAGE; |
|||
OUTF.OUTINT(IMAX,0); OUTF.OUTIMAGE; |
|||
OUTF.OUTINT(JMAX,0); OUTF.OUTIMAGE; |
|||
OUTF.OUTINT(COLOURMAX,0); OUTF.OUTIMAGE; |
|||
FOR J := 1 STEP 1 UNTIL JMAX DO |
|||
BEGIN |
|||
FOR I := 1 STEP 1 UNTIL IMAX DO |
|||
BEGIN |
|||
OUTF.OUTINT(PIXEL(I,J),0); |
|||
OUTF.OUTIMAGE; |
|||
END; |
|||
END; |
|||
OUTF.CLOSE; |
|||
END PLOT; |
|||
XCENTRE := -0.5; |
|||
YCENTRE := 0.0; |
|||
WIDTH := 4.0; |
|||
IMAX := 800; |
|||
JMAX := 600; |
|||
N := 100; |
|||
RMAX := 2.0; |
|||
FILENAME :- "out.pgm"; |
|||
COLOURMAX := 255; |
|||
PIXELSIZE := WIDTH / IMAX; |
|||
XOFFSET := XCENTRE - (0.5 * PIXELSIZE * (IMAX + 1)); |
|||
YOFFSET := YCENTRE + (0.5 * PIXELSIZE * (JMAX + 1)); |
|||
OUTTEXT("OUTPUT WILL BE WRITTEN TO "); |
|||
OUTTEXT(FILENAME); |
|||
OUTIMAGE; |
|||
PLOT; |
|||
END;</syntaxhighlight> |
|||
=={{header|Spin}}== |
|||
{{works with|BST/BSTC}} |
|||
{{works with|FastSpin/FlexSpin}} |
|||
{{works with|HomeSpun}} |
|||
{{works with|OpenSpin}} |
|||
<syntaxhighlight lang="spin">con |
|||
_clkmode = xtal1+pll16x |
|||
_clkfreq = 80_000_000 |
|||
xmin=-8601 ' int(-2.1*4096) |
|||
xmax=2867 ' int( 0.7*4096) |
|||
ymin=-4915 ' int(-1.2*4096) |
|||
ymax=4915 ' int( 1.2*4096) |
|||
maxiter=25 |
|||
obj |
|||
ser : "FullDuplexSerial" |
|||
pub main | c,cx,cy,dx,dy,x,y,x2,y2,iter |
|||
ser.start(31, 30, 0, 115200) |
|||
dx:=(xmax-xmin)/79 |
|||
dy:=(ymax-ymin)/24 |
|||
cy:=ymin |
|||
repeat while cy=<ymax |
|||
cx:=xmin |
|||
repeat while cx=<xmax |
|||
x:=0 |
|||
y:=0 |
|||
x2:=0 |
|||
y2:=0 |
|||
iter:=0 |
|||
repeat while iter=<maxiter and x2+y2=<16384 |
|||
y:=((x*y)~>11)+cy |
|||
x:=x2-y2+cx |
|||
iter+=1 |
|||
x2:=(x*x)~>12 |
|||
y2:=(y*y)~>12 |
|||
cx+=dx |
|||
ser.tx(iter+32) |
|||
cy+=dy |
|||
ser.str(string(13,10)) |
|||
waitcnt(_clkfreq+cnt) |
|||
ser.stop</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" |
|||
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'+)%%%$$$$$#####""""""""""" |
|||
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(+,)++&%$$$$$$######"""""" |
|||
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*5:/+('&%%$$$$$$#######""" |
|||
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),:::::::,'&%%%%%$$$$######## |
|||
!!!!!!!"""####################$$$$$$$$%%%&'())((())*,::::::/+))('&&&&)'%$$###### |
|||
!!!!!!""###################$$$$$%%%%%%&&&'+.:::/::::::::::::::::/++:..93%%$##### |
|||
!!!!!"################$$$%%%%%%%%%%&&&&'),+2:::::::::::::::::::::::::1(&&%$$#### |
|||
!!!!"##########$$$$$%%&(-(''''''''''''(*,5::::::::::::::::::::::::::::+)-&%$$### |
|||
!!!!####$$$$$$$$%%%%%&'(*-:1.+.:-4+))**:::::::::::::::::::::::::::::::4-(&%$$$## |
|||
!!!!#$$$$$$$$$%%%%%%'''++.6:::::::::8/0::::::::::::::::::::::::::::::::3(%%$$$$# |
|||
!!!#$$$$$$$%&&&&''()/-5.5::::::::::::::::::::::::::::::::::::::::::::::'&%%$$$$# |
|||
!!!(**+/+:523/80/46::::::::::::::::::::::::::::::::::::::::::::::::4+)'&&%%$$$$# |
|||
!!!#$$$$$$$%&&&&''().-2.:::::::::::::::::::::::::::::::::::::::::::::::'&%%$$$$# |
|||
!!!!#$$$$$$$$$%%%%%&'''/,.7::::::::::/0::::::::::::::::::::::::::::::::0'%%$$$$# |
|||
!!!!####$$$$$$$$%%%%%&'(*-:2.,/:-5+))**:::::::::::::::::::::::::::::::4+(&%$$$## |
|||
!!!!"##########$$$$$%%&(-(''''(''''''((*,4:::::::::::::::::::::::::::4+).&%$$### |
|||
!!!!!"################$$$%%%%%%%%%%&&&&'):,4:::::::::::::::::::::::::/('&%%$#### |
|||
!!!!!!""##################$$$$$$%%%%%%&&&'*.:::0::::::::::::::::1,,://9)%%$##### |
|||
!!!!!!!"""####################$$$$$$$$%%%&(())((()**-::::::/+)))'&&&')'%$$###### |
|||
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''(,:::::::+'&&%%%%%$$$######## |
|||
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*7:0+('&%%%$$$$$#######""" |
|||
!!!!!!!!!!!"""""""######################$$$$$$$$$%%%&&(+-).*&%$$$$$$######"""""" |
|||
!!!!!!!!!!!!!"""""""""#######################$$$$$$%%'3(%%%$$$$$######"""""""""" |
|||
!!!!!!!!!!!!!!!""""""""""""#####################################"""""""""""""""" |
|||
</pre> |
|||
=={{header|SparForte}}== |
|||
As a structured script. |
|||
<syntaxhighlight lang="ada">#!/usr/local/bin/spar |
|||
pragma annotate( summary, "mandel" ) |
|||
@( description, "Create a color image of the Mandelbrot set" ) |
|||
@( author, "Ken O. Burtch" ); |
|||
pragma license( unrestricted ); |
|||
pragma restriction( no_external_commands ); |
|||
procedure mandel is |
|||
mandel_limit : constant long_float := 4.0; -- reach this? it's the set |
|||
max_iterations : constant integer := 128; -- quit if looped this amt |
|||
center_r : constant long_float := -0.75; -- center of set (x=real) |
|||
center_i : constant long_float := 0.0; -- center of set (i=imag.) |
|||
c_r : long_float; -- current point (x=real) |
|||
c_i : long_float; -- current point (i=imag.) |
|||
loop_count : integer; -- number of iterations |
|||
z_r : long_float; -- mandelbot set formula |
|||
z_i : long_float; -- variables |
|||
z_r2 : long_float; |
|||
z_i2 : long_float; |
|||
c : pen.canvas_id; -- bush drawing canvas |
|||
plot : limited pen.rect; -- rectangle to draw with |
|||
s : string; |
|||
bits : integer; -- for determining color |
|||
red : pen.rgbcomponent; |
|||
green: pen.rgbcomponent; |
|||
blue : pen.rgbcomponent; |
|||
begin |
|||
-- create the drawing canvas |
|||
pen.new_window_canvas( 200, 200, 32, c ); |
|||
pen.set_title( c, "Mandelbrot" ); |
|||
-- loop for the size of the canvas (-50% to +50%) |
|||
for i in -50..50 loop |
|||
c_i := center_i - long_float(i)*0.025; |
|||
pen.wait_to_reveal( c ); |
|||
for r in -50..50 loop |
|||
c_r := center_r - long_float(r)*0.025; |
|||
-- Evaluatuate how close point (c_z, c_i ) in complex number space |
|||
-- is to the Mandelbrot set. Return a number between 0 and |
|||
-- max_iterations. A value of max_iterations implies that the point |
|||
-- is probably a member of the Mandelbrot set. |
|||
z_r := c_r; |
|||
z_i := c_i; |
|||
loop_count := 1; |
|||
loop |
|||
z_i2 := z_i*z_i; |
|||
z_r2 := z_r*z_r; |
|||
z_i := 2.0 * z_r * z_i + c_i; |
|||
z_r := z_r2 - z_i2 + c_r; |
|||
loop_count := @+1; |
|||
exit when not ( (z_r2 + z_i2 < mandel_limit) and (loop_count /= max_iterations) ); |
|||
end loop; |
|||
-- pick a color based on loop_count (mandelbrot set is black) |
|||
if loop_count = max_iterations then |
|||
red := 0.0; |
|||
green := 0.0; |
|||
blue := 0.0; |
|||
else |
|||
bits := (loop_count and 3 ); |
|||
red := 100.0-pen.rgbcomponent((100*bits/3)); |
|||
bits := (loop_count / 3 ) and 3; |
|||
green := 100.0-pen.rgbcomponent((100*bits/3)); |
|||
bits := (loop_count / 27 ) and 2; |
|||
blue := 100.0-pen.rgbcomponent((100*bits)/2); |
|||
end if; |
|||
pen.set_pen_ink( c, red, green, blue ); |
|||
-- Draw the point, reversing the X axis |
|||
pen.set_rect( plot, 100-(r+50),i+50, 100-(r+49), i+51 ); |
|||
pen.paint_rect( c, plot ); |
|||
end loop; |
|||
pen.reveal( c ); |
|||
end loop; |
|||
? "Press return"; |
|||
s := get_line; |
|||
end mandel;</syntaxhighlight> |
|||
=={{header|SPL}}== |
|||
<syntaxhighlight lang="spl">w,h = #.scrsize() |
|||
sfx = -2.5; sfy = -2*h/w; fs = 4/w |
|||
#.aaoff() |
|||
> y, 1...h |
|||
> x, 1...w |
|||
fx = sfx + x*fs; fy = sfy + y*fs |
|||
#.drawpoint(x,y,color(fx,fy):3) |
|||
< |
|||
< |
|||
color(x,y)= |
|||
zr = x; zi = y; n = 0; maxn = 150 |
|||
> zr*zr+zi*zi<4 & n<maxn |
|||
zrn = zr*zr-zi*zi+x; zin = 2*zr*zi+y |
|||
zr = zrn; zi = zin; n += 1 |
|||
< |
|||
? n=maxn, <= 0,0,0 |
|||
<= #.hsv2rgb(n/maxn*360,1,1):3 |
|||
.</syntaxhighlight> |
|||
=={{header|Swift}}== |
|||
Using the Swift Numerics package, as well as the C library Quick 'N Dirty BMP imported in Swift. |
|||
<syntaxhighlight lang="swift">import Foundation |
|||
import Numerics |
|||
import QDBMP |
|||
public typealias Color = (red: UInt8, green: UInt8, blue: UInt8) |
|||
public class BitmapDrawer { |
|||
public let imageHeight: Int |
|||
public let imageWidth: Int |
|||
var grid: [[Color?]] |
|||
private let bmp: OpaquePointer |
|||
public init(height: Int, width: Int) { |
|||
self.imageHeight = height |
|||
self.imageWidth = width |
|||
self.grid = [[Color?]](repeating: [Color?](repeating: nil, count: height), count: width) |
|||
self.bmp = BMP_Create(UInt(width), UInt(height), 24) |
|||
checkError() |
|||
} |
|||
deinit { |
|||
BMP_Free(bmp) |
|||
} |
|||
private func checkError() { |
|||
let err = BMP_GetError() |
|||
guard err == BMP_STATUS(0) else { |
|||
fatalError("\(err)") |
|||
} |
|||
} |
|||
public func save(to path: String = "~/Desktop/out.bmp") { |
|||
for x in 0..<imageWidth { |
|||
for y in 0..<imageHeight { |
|||
guard let color = grid[x][y] else { continue } |
|||
BMP_SetPixelRGB(bmp, UInt(x), UInt(y), color.red, color.green, color.blue) |
|||
checkError() |
|||
} |
|||
} |
|||
(path as NSString).expandingTildeInPath.withCString {s in |
|||
BMP_WriteFile(bmp, s) |
|||
} |
|||
} |
|||
public func setPixel(x: Int, y: Int, to color: Color?) { |
|||
grid[x][y] = color |
|||
} |
|||
} |
|||
let imageSize = 10_000 |
|||
let canvas = BitmapDrawer(height: imageSize, width: imageSize) |
|||
let maxIterations = 256 |
|||
let cxMin = -2.0 |
|||
let cxMax = 1.0 |
|||
let cyMin = -1.5 |
|||
let cyMax = 1.5 |
|||
let scaleX = (cxMax - cxMin) / Double(imageSize) |
|||
let scaleY = (cyMax - cyMin) / Double(imageSize) |
|||
for x in 0..<imageSize { |
|||
for y in 0..<imageSize { |
|||
let cx = cxMin + Double(x) * scaleX |
|||
let cy = cyMin + Double(y) * scaleY |
|||
let c = Complex(cx, cy) |
|||
var z = Complex(0.0, 0.0) |
|||
var i = 0 |
|||
for t in 0..<maxIterations { |
|||
if z.magnitude > 2 { |
|||
break |
|||
} |
|||
z = z * z + c |
|||
i = t |
|||
} |
|||
canvas.setPixel(x: x, y: y, to: Color(red: UInt8(i), green: UInt8(i), blue: UInt8(i))) |
|||
} |
|||
} |
|||
canvas.save()</syntaxhighlight> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{libheader|Tk}} |
{{libheader|Tk}} |
||
This code makes extensive use of Tk's built-in photo image system, which provides a 32-bit RGBA plotting surface that can be then quickly drawn in any number of places in the application. It uses a computational color scheme that was easy to code... |
This code makes extensive use of Tk's built-in photo image system, which provides a 32-bit RGBA plotting surface that can be then quickly drawn in any number of places in the application. It uses a computational color scheme that was easy to code... |
||
< |
<syntaxhighlight lang="tcl">package require Tk |
||
proc mandelIters {cx cy} { |
proc mandelIters {cx cy} { |
||
Line 1,071: | Line 13,429: | ||
update |
update |
||
} |
} |
||
.mandel configure -cursor {}</ |
.mandel configure -cursor {}</syntaxhighlight> |
||
=={{header|TeX}}== |
|||
{{libheader|pst-fractal}} |
|||
The <code>pst-fractal</code> package includes a Mandelbrot set drawn by emitting [[PostScript]] code (using [[PSTricks]]), so the actual work done in the printer or PostScript interpreter. |
|||
<syntaxhighlight lang="tex">\input pst-fractal |
|||
\psfractal[type=Mandel,xWidth=14cm,yWidth=12cm,maxIter=30,dIter=20] (-2.5,-1.5)(1,1.5) |
|||
\end</syntaxhighlight> |
|||
The coordinates are a rectangle in the complex plane to draw, scaled up to <code>xWidth,yWidth</code>. |
|||
More iterations with <code>maxIter</code> is higher resolution but slower. |
|||
<code>dIter</code> is a scale factor for the colours. |
|||
=={{header|LaTeX}}== |
|||
The <code>pstricks-examples</code> package which is samples from the PSTricks book includes similar for [[LaTeX]] (<code>25-02-6.ltx</code> and <code>33-02-6.ltx</code>). |
|||
{{libheader|PGF}} |
|||
The PGF <code>shadings</code> library includes a Mandelbrot set. |
|||
In PGF 3.0 the calculations are done in [[PostScript]] code emitted, so the output size is small but it only does 10 iterations so is very low resolution. |
|||
<syntaxhighlight lang="latex">\documentclass{minimal} |
|||
\usepackage{tikz} |
|||
\usetikzlibrary{shadings} |
|||
\begin{document} |
|||
\begin{tikzpicture} |
|||
\shade[shading=Mandelbrot set] (0,0) rectangle (4,4); |
|||
\end{tikzpicture} |
|||
\end{document}</syntaxhighlight> |
|||
=={{header|LuaTeX}}== |
|||
{{libheader|LuaTeX}} |
|||
[[LuaLaTeX]] plus pgfplots code can be found at [http://texwelt.de/wissen/fragen/3960/fraktale-mit-pgfplots http://texwelt.de/wissen/fragen/3960/fraktale-mit-pgfplots]. |
|||
The calculations are done by inline [[Lua]] code and the resulting bitmap shown with a PGF plot. |
|||
=={{header|TI-83 BASIC}}== |
|||
Based on the [[Mandelbrot_set#BASIC|BASIC Version]]. Due to the TI-83's lack of power, it takes around 2 hours to complete at 16 iterations. |
|||
<syntaxhighlight lang="ti83b">PROGRAM:MANDELBR |
|||
:Input "ITER. ",D |
|||
:For(A,Xmin,Xmax,ΔX) |
|||
:For(B,Ymin,Ymax,ΔY) |
|||
:0→X |
|||
:0→Y |
|||
:0→I |
|||
:D→M |
|||
:While X^2+Y^2≤4 and I<M |
|||
:X^2-Y^2+A→R |
|||
:2XY+B→Y |
|||
:R→X |
|||
:I+1→I |
|||
:End |
|||
:If I≠M |
|||
:Then |
|||
:I→C |
|||
:Else |
|||
:0→C |
|||
:End |
|||
:If C<1 |
|||
:Pt-On(A,B) |
|||
:End |
|||
:End |
|||
:End |
|||
</syntaxhighlight> |
|||
=={{header|Transact-SQL}}== |
|||
This is a Transact-SQL version of SQL Server to generate Mandelbrot set. Export the final result to a .ppm file to view the image. More details are available [https://krishnakumarsql.wordpress.com/2023/07/12/drawing-a-colorful-mandelbrot-set-in-sql-server/ here]. |
|||
<syntaxhighlight lang="Transact-SQL"> |
|||
-- Mandelbrot Set |
|||
-- SQL Server 2017 and above |
|||
SET NOCOUNT ON |
|||
GO |
|||
-- Plot area 800 X 800 |
|||
DECLARE @width INT = 800 |
|||
DECLARE @height INT = 800 |
|||
DECLARE @r_min DECIMAL (10, 8) = -2.5; |
|||
DECLARE @r_max DECIMAL (10, 8) = 1.5; |
|||
DECLARE @r_step DECIMAL (10, 8) = 0.005; |
|||
DECLARE @i_min DECIMAL (10, 8) = -2; |
|||
DECLARE @i_max DECIMAL (10, 8) = 2; |
|||
DECLARE @i_step DECIMAL (10, 8) = 0.005; |
|||
DECLARE @iter INT = 255; -- Iteration |
|||
DROP TABLE IF EXISTS dbo.Numbers |
|||
DROP TABLE IF EXISTS dbo.mandelbrot_set; |
|||
CREATE TABLE dbo.Numbers (n INT); |
|||
-- Generate a number table of 1000 rows |
|||
;WITH N1(n) AS |
|||
( |
|||
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL |
|||
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL |
|||
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 |
|||
), -- 10 |
|||
N2(n) AS (SELECT 1 FROM N1 CROSS JOIN N1 AS b), -- 10*10 |
|||
N3(n) AS (SELECT 1 FROM N1 CROSS JOIN N2) -- 10*100 |
|||
INSERT INTO dbo.Numbers (n) |
|||
SELECT n = ROW_NUMBER() OVER (ORDER BY n) |
|||
FROM N3 ORDER BY n; |
|||
/* |
|||
-- If the version is SQL Server 2022 and above |
|||
INSERT INTO dbo.Numbers (n) |
|||
SELECT value FROM GENERATE_SERIES(0, 1000); |
|||
*/ |
|||
CREATE TABLE dbo.mandelbrot_set |
|||
( |
|||
a INT, |
|||
b INT, |
|||
c_re DECIMAL (10, 8), |
|||
c_im DECIMAL (10, 8), |
|||
z_re DECIMAL (10, 8) DEFAULT 0, |
|||
z_im DECIMAL (10, 8) DEFAULT 0, |
|||
znew_re DECIMAL (10, 8) DEFAULT 0, |
|||
znew_im DECIMAL (10, 8) DEFAULT 0, |
|||
steps INT DEFAULT 0, |
|||
active BIT DEFAULT 1, |
|||
) |
|||
-- Store all the c_re, c_im corresponding to each point in the plot area |
|||
-- Generate 640,000 rows (800 X 800) |
|||
INSERT INTO dbo.mandelbrot_set (a, b, c_re, c_im, steps) |
|||
SELECT a.n as a, b.n as b |
|||
,(@r_min + (a.n * @r_step)) AS c_re |
|||
,(@i_min + (b.n * @i_step)) AS c_im |
|||
,@iter AS steps |
|||
FROM |
|||
( |
|||
SELECT n - 1 as n FROM dbo.Numbers WHERE n <= @width |
|||
) as a |
|||
CROSS JOIN |
|||
( |
|||
SELECT n - 1 as n FROM dbo.Numbers WHERE n <= @height |
|||
) as b; |
|||
-- Iteration |
|||
WHILE (@iter > 1) |
|||
BEGIN |
|||
UPDATE dbo.mandelbrot_set |
|||
SET |
|||
znew_re = POWER(z_re,2)-POWER(z_im,2)+c_re, |
|||
znew_im = 2*z_re*z_im+c_im, |
|||
steps = steps-1 |
|||
WHERE active=1; |
|||
UPDATE dbo.mandelbrot_set |
|||
SET |
|||
z_re=znew_re, |
|||
z_im=znew_im, |
|||
active= CASE |
|||
WHEN POWER(znew_re,2)+POWER(znew_im,2)>4 THEN 0 |
|||
ELSE 1 |
|||
END |
|||
WHERE active=1; |
|||
SET @iter = @iter - 1; |
|||
END |
|||
-- Generating PPM File |
|||
-- Save the below query results to a file with extension .ppm |
|||
-- NOTE : All the unwanted info like 'rows affected', 'completed time' etc. needs to be |
|||
-- removed from the file. Most of the image editing softwares and online viewers can display the .ppm file |
|||
SELECT 'P3' UNION ALL |
|||
SELECT CAST(@width AS VARCHAR(5)) + ' ' + CAST(@height AS VARCHAR(5)) UNION ALL |
|||
SELECT '255' UNION ALL |
|||
SELECT |
|||
STRING_AGG(CAST(CASE WHEN active = 1 THEN 0 ELSE 55 + steps % 200 END AS VARCHAR(10)) + ' ' -- R |
|||
+ CAST(CASE WHEN active = 1 THEN 0 ELSE 55+POWER(steps,3) % 200 END AS VARCHAR(10)) + ' ' -- G |
|||
+ CAST(CASE WHEN active = 1 THEN 0 ELSE 55+ POWER(steps,2) % 200 END AS VARCHAR(10)) -- B |
|||
, ' ') WITHIN GROUP (ORDER BY c_re, c_im) |
|||
FROM dbo.mandelbrot_set |
|||
GROUP BY c_re, c_im; |
|||
</syntaxhighlight> |
|||
'''OUTPUT''' |
|||
[[File:Mandelbrot set transact-sql.png|thumb]] |
|||
=={{header|TXR}}== |
|||
{{trans|Scheme}} |
|||
Creates same <code>mandelbrot.pgm</code> file. |
|||
<syntaxhighlight lang="txrlisp">(defvar x-centre -0.5) |
|||
(defvar y-centre 0.0) |
|||
(defvar width 4.0) |
|||
(defvar i-max 800) |
|||
(defvar j-max 600) |
|||
(defvar n 100) |
|||
(defvar r-max 2.0) |
|||
(defvar file "mandelbrot.pgm") |
|||
(defvar colour-max 255) |
|||
(defvar pixel-size (/ width i-max)) |
|||
(defvar x-offset (- x-centre (* 0.5 pixel-size (+ i-max 1)))) |
|||
(defvar y-offset (+ y-centre (* 0.5 pixel-size (+ j-max 1)))) |
|||
;; with-output-to-file macro |
|||
(defmacro with-output-to-file (name . body) |
|||
^(let ((*stdout* (open-file ,name "w"))) |
|||
(unwind-protect (progn ,*body) (close-stream *stdout*)))) |
|||
;; complex number library |
|||
(defmacro cplx (x y) ^(cons ,x ,y)) |
|||
(defmacro re (c) ^(car ,c)) |
|||
(defmacro im (c) ^(cdr ,c)) |
|||
(defsymacro c0 '(0 . 0)) |
|||
(macro-time |
|||
(defun with-cplx-expand (specs body) |
|||
(tree-case specs |
|||
(((re im expr) . rest) |
|||
^(tree-bind (,re . ,im) ,expr ,(with-cplx-expand rest body))) |
|||
(() (tree-case body |
|||
((a b . rest) ^(progn ,a ,b ,*rest)) |
|||
((a) a) |
|||
(x (error "with-cplx: invalid body ~s" body)))) |
|||
(x (error "with-cplx: bad args ~s" x))))) |
|||
(defmacro with-cplx (specs . body) |
|||
(with-cplx-expand specs body)) |
|||
(defun c+ (x y) |
|||
(with-cplx ((a b x) (c d y)) |
|||
(cplx (+ a c) (+ b d)))) |
|||
(defun c* (x y) |
|||
(with-cplx ((a b x) (c d y)) |
|||
(cplx (- (* a c) (* b d)) (+ (* b c) (* a d))))) |
|||
(defun modulus (z) |
|||
(with-cplx ((a b z)) |
|||
(sqrt (+ (* a a) (* b b))))) |
|||
;; Mandelbrot routines |
|||
(defun inside-p (z0 : (z c0) (n n)) |
|||
(and (< (modulus z) r-max) |
|||
(or (zerop n) |
|||
(inside-p z0 (c+ (c* z z) z0) (- n 1))))) |
|||
(defmacro int-bool (b) |
|||
^(if ,b colour-max 0)) |
|||
(defun pixel (i j) |
|||
(int-bool |
|||
(inside-p |
|||
(cplx (+ x-offset (* pixel-size i)) |
|||
(- y-offset (* pixel-size j)))))) |
|||
;; Mandelbrot loop and output |
|||
(defun plot () |
|||
(with-output-to-file file |
|||
(format t "P2\n~s\n~s\n~s\n" i-max j-max colour-max) |
|||
(each ((j (range 1 j-max))) |
|||
(each ((i (range 1 i-max))) |
|||
(format *stdout* "~s " (pixel i j))) |
|||
(put-line "" *stdout*)))) |
|||
(plot)</syntaxhighlight> |
|||
=={{header|uBasic/4tH}}== |
|||
uBasic does not support floating point calculations, so fixed point arithmetic is used, with Value 10000 representing 1.0. The Mandelbrot image is drawn using ASCII characters 1-9 to show number of iterations. Iteration count 10 or more is represented with '@'. To compensate the aspect ratio of |
|||
the font, step sizes in x and y directions are different. |
|||
<syntaxhighlight lang="basic">A =-21000 ' Left Edge = -2.1 |
|||
B = 15000 ' Right Edge = 1.5 |
|||
C = 15000 ' Top Edge = 1.5 |
|||
D =-15000 ' Bottom Edge = -1.5 |
|||
E = 200 ' Max Iteration Depth |
|||
F = 350 ' X Step Size |
|||
G = 750 ' Y Step Size |
|||
For L = C To D Step -G ' Y0 |
|||
For K = A To B-1 Step F ' X0 |
|||
V = 0 ' Y |
|||
U = 0 ' X |
|||
I = 32 ' Char To Be Displayed |
|||
For O = 0 To E-1 ' Iteration |
|||
X = (U/10 * U) / 1000 ' X*X |
|||
Y = (V/10 * V) / 1000 ' Y*Y |
|||
If (X + Y > 40000) |
|||
I = 48 + O ' Print Digit 0...9 |
|||
If (O > 9) ' If Iteration Count > 9, |
|||
I = 64 ' Print '@' |
|||
Endif |
|||
Break |
|||
Endif |
|||
Z = X - Y + K ' Temp = X*X - Y*Y + X0 |
|||
V = (U/10 * V) / 500 + L ' Y = 2*X*Y + Y0 |
|||
U = Z ' X = Temp |
|||
Next |
|||
Gosub I ' Ins_char(I) |
|||
Next |
|||
Print |
|||
Next |
|||
End |
|||
' Translate number to ASCII |
|||
32 Print " "; : Return |
|||
48 Print "0"; : Return |
|||
49 Print "1"; : Return |
|||
50 Print "2"; : Return |
|||
51 Print "3"; : Return |
|||
52 Print "4"; : Return |
|||
53 Print "5"; : Return |
|||
54 Print "6"; : Return |
|||
55 Print "7"; : Return |
|||
56 Print "8"; : Return |
|||
57 Print "9"; : Return |
|||
64 Print "@"; : Return</syntaxhighlight> |
|||
Output: |
|||
<pre>1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 |
|||
1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 |
|||
1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 |
|||
1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 |
|||
1111111111111112222222222222333333333333333333333333333333333333322222222222222222222222222222222222222 |
|||
1111111111111222222222233333333333333333333333344444457655544443333332222222222222222222222222222222222 |
|||
1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 |
|||
11111111111222222333333333333333333333334444444445555678@@@@7654444443333332222222222222222222222222222 |
|||
1111111112222223333333333333333333333444444444455556789@@@@98655544444433333332222222222222222222222222 |
|||
1111111122222333333333333333333333344444444445556668@@@ @@@@76555544444333333322222222222222222222222 |
|||
1111111122233333333333333333333344444444445566667778@@ @987666555544433333333222222222222222222222 |
|||
111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@87777@95443333333322222222222222222222 |
|||
1111112233333333333333333334444455555556678@@ @@ @@@@@@@8544333333333222222222222222222 |
|||
1111122333333333333333334445555555555666789@@@ @86554433333333322222222222222222 |
|||
1111123333333333333444466666555556666778@@@@ @@87655443333333332222222222222222 |
|||
111123333333344444455568@887789@8777788@@@ @@@@65443333333332222222222222222 |
|||
1111333344444444455556679@@@@@@@@@@@99@@@ @@765444333333333222222222222222 |
|||
1111334444444455555567789@@ @@@@ @855444333333333222222222222222 |
|||
11114444444455555668@99@@@ @ @@655444433333333322222222222222 |
|||
11134555556666677789@@@ @ @86655444433333333322222222222222 |
|||
111 @@876555444433333333322222222222222 |
|||
11134555556666677789@@@ @ @86655444433333333322222222222222 |
|||
11114444444455555668@99@@@ @ @@655444433333333322222222222222 |
|||
1111334444444455555567789@@ @@@@ @855444333333333222222222222222 |
|||
1111333344444444455556679@@@@@@@@@@@99@@@ @@765444333333333222222222222222 |
|||
111123333333344444455568@887789@8777788@@@ @@@@65443333333332222222222222222 |
|||
1111123333333333333444466666555556666778@@@@ @@87655443333333332222222222222222 |
|||
1111122333333333333333334445555555555666789@@@ @86554433333333322222222222222222 |
|||
1111112233333333333333333334444455555556678@@ @@ @@@@@@@8544333333333222222222222222222 |
|||
111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@87777@95443333333322222222222222222222 |
|||
1111111122233333333333333333333344444444445566667778@@ @987666555544433333333222222222222222222222 |
|||
1111111122222333333333333333333333344444444445556668@@@ @@@@76555544444333333322222222222222222222222 |
|||
1111111112222223333333333333333333333444444444455556789@@@@98655544444433333332222222222222222222222222 |
|||
11111111111222222333333333333333333333334444444445555678@@@@7654444443333332222222222222222222222222222 |
|||
1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 |
|||
1111111111111222222222233333333333333333333333344444457655544443333332222222222222222222222222222222222 |
|||
1111111111111112222222222222333333333333333333333333333333333333322222222222222222222222222222222222222 |
|||
1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 |
|||
1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 |
|||
1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 |
|||
1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 |
|||
0 OK, 0:1726 </pre> |
|||
=={{header|Uiua}}== |
|||
<syntaxhighlight lang="uiua"> |
|||
Size ← 800 |
|||
Cs ← ÷ 5[5_5_5 4_5_5 4_5_5 3_5_5 5_3_5 3_3_5 2_5_0 5_2_2 2_2_5 0_0_0] |
|||
# Initialise complex co-ordinates. |
|||
×2.5 ⊞ℂ:-1/4. ÷:-÷2,⇡.⟜(↯:0⊟.)Size |
|||
# Iterate 50 times (a, b, got_there) -> (a*a+b, b, got_there) |
|||
# got_there counts when corresponding value in b hits 2. |
|||
⍥⊃(+×.|⋅∘|+<2⌵⊙◌)50 0 |
|||
# Scale the results down and display |
|||
⊏:Cs⌈×9÷:⟜(/↥/↥)ₙ2◌◌ |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
[[File:Uiua Mandelbrot Set.png|thumb|center]] |
|||
=={{header|UNIX Shell}}== |
|||
{{works with|Bourne Again SHell|4}} |
|||
<syntaxhighlight lang="bash">function mandelbrot() { |
|||
local -ir maxiter=100 |
|||
local -i i j {x,y}m{in,ax} d{x,y} |
|||
local -ra C=( {0..9} ) |
|||
local -i lC=${#C[*]} |
|||
local -i columns=${COLUMNS:-72} lines=${LINES:-24} |
|||
(( |
|||
xmin=-21*4096/10, |
|||
xmax= 7*4096/10, |
|||
ymin=-12*4096/10, |
|||
ymax= 12*4096/10, |
|||
dx=(xmax-xmin)/columns, |
|||
dy=(ymax-ymin)/lines |
|||
)) |
|||
for ((cy=ymax, i=0; i<lines; cy-=dy, i++)) |
|||
do for ((cx=xmin, j=0; j<columns; cx+=dx, j++)) |
|||
do (( x=0, y=0, x2=0, y2=0 )) |
|||
for (( iter=0; iter<maxiter && x2+y2<=16384; iter++ )) |
|||
do |
|||
(( |
|||
y=((x*y)>>11)+cy, |
|||
x=x2-y2+cx, |
|||
x2=(x*x)>>12, |
|||
y2=(y*y)>>12 |
|||
)) |
|||
done |
|||
((c=iter%lC)) |
|||
echo -n "${C[c]}" |
|||
done |
|||
echo |
|||
done |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1111111111111222222222222333333333333333333333333333333333222222222222222 |
|||
1111111111112222222233333333333333333333344444456015554444333332222222222 |
|||
1111111111222222333333333333333333333444444445556704912544444433333222222 |
|||
1111111112222333333333333333333333444444444555678970508655544444333333222 |
|||
1111111222233333333333333333333444444444556667807000002076555544443333333 |
|||
1111112223333333333333333333444444455577898889016000003099766662644333333 |
|||
1111122333333333333333334444455555566793000800000000000000931045875443333 |
|||
1111123333333333333344455555555566668014000000000000000000000009865544333 |
|||
1111233333333344445568277777777777880600000000000000000000000009099544433 |
|||
1111333344444445555678041513450199023000000000000000000000000000807544433 |
|||
1112344444445555556771179000000000410000000000000000000000000000036544443 |
|||
1114444444566667782404400000000000000000000000000000000000000000775544443 |
|||
1119912160975272040000000000000000000000000000000000000000000219765544443 |
|||
1114444444566667792405800000000000000000000000000000000000000000075544443 |
|||
1113344444445555556773270000000000500000000000000000000000000000676544443 |
|||
1111333344444445555678045623255199020000000000000000000000000000707544433 |
|||
1111233333333444445568177777877777881500000000000000000000000009190544433 |
|||
1111123333333333333344455555555566668126000000000000000000000009865544333 |
|||
1111122333333333333333334444455555566793000100000000000000941355975443333 |
|||
1111112223333333333333333334444444455588908889016000003099876670654433333 |
|||
1111111222233333333333333333334444444445556667800000002976555554443333333 |
|||
1111111112222333333333333333333333444444444555679060608655544444333333222 |
|||
1111111111222222333333333333333333333444444445556702049544444433333222222 |
|||
1111111111112222222233333333333333333333344444456205554444333333222222222 |
|||
1111111111111222222222222333333333333333333333333333333333222222222222222 |
|||
</pre> |
|||
=={{header|Vala}}== |
|||
<syntaxhighlight lang="vala">public class Example: Gtk.Application { |
|||
private Gtk.ApplicationWindow window; |
|||
private Gtk.DrawingArea drawing_area; |
|||
public Example() { |
|||
Object(application_id: "my.application", flags: ApplicationFlags.FLAGS_NONE); |
|||
this.activate.connect(() => { |
|||
window = new Gtk.ApplicationWindow(this); |
|||
drawing_area = new Gtk.DrawingArea(); |
|||
drawing_area.set_draw_func(draw_mandelbrot); |
|||
window.set_child(drawing_area); |
|||
window.present(); |
|||
}); |
|||
} |
|||
private void draw_mandelbrot(Gtk.DrawingArea area, Cairo.Context cr, int width, int height) { |
|||
cr.set_source_rgb(0, 0, 0); |
|||
cr.paint(); |
|||
int x0 = -1; |
|||
double x_increment = 2.47 / (float) width; |
|||
double y_increment = 2.24 / (float) height; |
|||
for (double x = -2.0; x < 0.47; x += x_increment, x0++) { |
|||
int y0 = -1; |
|||
for (double y = -1.12; y < 1.12; y += y_increment, y0++) { |
|||
double c_re = x; |
|||
double c_im = y; |
|||
double x_ = 0, |
|||
y_ = 0; |
|||
int iterations = 0; |
|||
int max_iterations = 50; |
|||
while (iterations < max_iterations && x_ * x_ + y_ * y_ <= 4.0) { |
|||
double x_new = x_ * x_ - y_ * y_ + c_re; |
|||
y_ = 2.0 * x_ * y_ + c_im; |
|||
x_ = x_new; |
|||
iterations++; |
|||
} |
|||
if (iterations < max_iterations) { |
|||
cr.set_source_rgb((float) iterations / (float) max_iterations, 0, 0); |
|||
cr.rectangle(x0, y0, 1, 1); |
|||
cr.fill(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
public static int main(string[] argv) { |
|||
var app = new Example(); |
|||
return app.run(argv); |
|||
} |
|||
}</syntaxhighlight> |
|||
=={{header|VBScript}}== |
|||
<syntaxhighlight lang="vb"> |
|||
option explicit |
|||
' Raster graphics class in VBSCRIPT by Antoni Gual |
|||
'-------------------------------------------- |
|||
' An array keeps the image allowing to set pixels, draw lines and boxes in it. |
|||
' at class destroy a bmp file is saved to disk and the default viewer is called |
|||
' The class can work with 8 and 24 bit bmp. With 8 bit uses a built-in palette or can import a custom one |
|||
'Declaration : |
|||
' Set MyObj = (New ImgClass)(name,width,height, orient,bits_per_pixel,palette_array) |
|||
' name:path and name of the file created |
|||
' width, height of the canvas |
|||
' orient is the way the coord increases, 1 to 4 think of the 4 cuadrants of the caterian plane |
|||
' 1 X:l>r Y:b>t 2 X:r>l Y:b>t 3 X:r>l Y:t>b 4 X:l>r Y:t>b |
|||
' bits_per_pixel can bs only 8 and 24 |
|||
' palette array only to substitute the default palette for 8 bits, else put a 0 |
|||
' it sets the origin at the corner of the image (bottom left if orient=1) |
|||
Class ImgClass |
|||
Private ImgL,ImgH,ImgDepth,bkclr,loc,tt |
|||
private xmini,xmaxi,ymini,ymaxi,dirx,diry |
|||
public ImgArray() 'rgb in 24 bit mode, indexes to palette in 8 bits |
|||
private filename |
|||
private Palette,szpal |
|||
Public Property Let depth (x) |
|||
if depth=8 or depth =24 then |
|||
Imgdepth=depth |
|||
else |
|||
Imgdepth=8 |
|||
end if |
|||
bytepix=imgdepth/8 |
|||
end property |
|||
Public Property Let Pixel (x,y,color) |
|||
If (x>=ImgL) or x<0 then exit property |
|||
if y>=ImgH or y<0 then exit property |
|||
ImgArray(x,y)=Color |
|||
End Property |
|||
Public Property Get Pixel (x,y) |
|||
If (x<ImgL) And (x>=0) And (y<ImgH) And (y>=0) Then |
|||
Pixel=ImgArray(x,y) |
|||
End If |
|||
End Property |
|||
Public Property Get ImgWidth () |
|||
ImgWidth=ImgL-1 |
|||
End Property |
|||
Public Property Get ImgHeight () |
|||
ImgHeight=ImgH-1 |
|||
End Property |
|||
'constructor (fn,w*2,h*2,32,0,0) |
|||
Public Default Function Init(name,w,h,orient,dep,bkg,mipal) |
|||
'offx, offy posicion de 0,0. si ofx+ , x se incrementa de izq a der, si offy+ y se incrementa de abajo arriba |
|||
dim i,j |
|||
ImgL=w |
|||
ImgH=h |
|||
tt=timer |
|||
set0 0,0 'origin blc positive up and right |
|||
redim imgArray(ImgL-1,ImgH-1) |
|||
bkclr=bkg |
|||
if bkg<>0 then |
|||
for i=0 to ImgL-1 |
|||
for j=0 to ImgH-1 |
|||
imgarray(i,j)=bkg |
|||
next |
|||
next |
|||
end if |
|||
Select Case orient |
|||
Case 1: dirx=1 : diry=1 |
|||
Case 2: dirx=-1 : diry=1 |
|||
Case 3: dirx=-1 : diry=-1 |
|||
Case 4: dirx=1 : diry=-1 |
|||
End select |
|||
filename=name |
|||
ImgDepth =dep |
|||
'load user palette if provided |
|||
if imgdepth=8 then |
|||
loadpal(mipal) |
|||
end if |
|||
set init=me |
|||
end function |
|||
private sub loadpal(mipale) |
|||
if isarray(mipale) Then |
|||
palette=mipale |
|||
szpal=UBound(mipale)+1 |
|||
Else |
|||
szpal=256 |
|||
'Default palette recycled from ATARI |
|||
End if |
|||
End Sub |
|||
public sub set0 (x0,y0) 'origin can be changed during drawing |
|||
if x0<0 or x0>=imgl or y0<0 or y0>imgh then err.raise 9 |
|||
xmini=-x0 |
|||
ymini=-y0 |
|||
xmaxi=xmini+imgl-1 |
|||
ymaxi=ymini+imgh-1 |
|||
end sub |
|||
Private Sub Class_Terminate |
|||
if err <>0 then wscript.echo "Error " & err.number |
|||
wscript.echo "writing bmp to file" |
|||
savebmp |
|||
wscript.echo "opening " & filename |
|||
CreateObject("Shell.Application").ShellExecute filename |
|||
wscript.echo timer-tt & " seconds" |
|||
End Sub |
|||
'writes a 32bit integr value as binary to an utf16 string |
|||
function long2wstr( x) 'falta muy poco!!! |
|||
dim k1,k2,x1 |
|||
k1= (x and &hffff&)' or (&H8000& And ((X And &h8000&)<>0))) |
|||
k2=((X And &h7fffffff&) \ &h10000&) Or (&H8000& And (x<0)) |
|||
long2wstr=chrw(k1) & chrw(k2) |
|||
end function |
|||
function int2wstr(x) |
|||
int2wstr=ChrW((x and &h7fff) or (&H8000 And (X<0))) |
|||
End Function |
|||
Public Sub SaveBMP |
|||
'Save the picture to a bmp file |
|||
Dim s,ostream, x,y,loc |
|||
const hdrs=54 '14+40 |
|||
dim bms:bms=ImgH* 4*(((ImgL*imgdepth\8)+3)\4) 'bitmap size including padding |
|||
dim palsize:if (imgdepth=8) then palsize=szpal*4 else palsize=0 |
|||
with CreateObject("ADODB.Stream") 'auxiliary ostream, it creates an UNICODE with bom stream in memory |
|||
.Charset = "UTF-16LE" 'o "UTF16-BE" |
|||
.Type = 2' adTypeText |
|||
.open |
|||
'build a header |
|||
'bmp header: VBSCript does'nt have records nor writes binary values to files, so we use strings of unicode chars!! |
|||
'BMP header |
|||
.writetext ChrW(&h4d42) ' 0 "BM" 4d42 |
|||
.writetext long2wstr(hdrs+palsize+bms) ' 2 fiesize |
|||
.writetext long2wstr(0) ' 6 reserved |
|||
.writetext long2wstr (hdrs+palsize) '10 image offset |
|||
'InfoHeader |
|||
.writetext long2wstr(40) '14 infoheader size |
|||
.writetext long2wstr(Imgl) '18 image length |
|||
.writetext long2wstr(imgh) '22 image width |
|||
.writetext int2wstr(1) '26 planes |
|||
.writetext int2wstr(imgdepth) '28 clr depth (bpp) |
|||
.writetext long2wstr(&H0) '30 compression used 0= NOCOMPR |
|||
.writetext long2wstr(bms) '34 imgsize |
|||
.writetext long2wstr(&Hc4e) '38 bpp hor |
|||
.writetext long2wstr(&hc43) '42 bpp vert |
|||
.writetext long2wstr(szpal) '46 colors in palette |
|||
.writetext long2wstr(&H0) '50 important clrs 0=all |
|||
'write bitmap |
|||
'precalc data for orientation |
|||
Dim x1,x2,y1,y2 |
|||
If dirx=-1 Then x1=ImgL-1 :x2=0 Else x1=0:x2=ImgL-1 |
|||
If diry=-1 Then y1=ImgH-1 :y2=0 Else y1=0:y2=ImgH-1 |
|||
Select Case imgdepth |
|||
Case 32 |
|||
For y=y1 To y2 step diry |
|||
For x=x1 To x2 Step dirx |
|||
'writelong fic, Pixel(x,y) |
|||
.writetext long2wstr(Imgarray(x,y)) |
|||
Next |
|||
Next |
|||
Case 8 |
|||
'palette |
|||
For x=0 to szpal-1 |
|||
.writetext long2wstr(palette(x)) '52 |
|||
Next |
|||
'image |
|||
dim pad:pad=ImgL mod 4 |
|||
For y=y1 to y2 step diry |
|||
For x=x1 To x2 step dirx*2 |
|||
.writetext chrw((ImgArray(x,y) and 255)+ &h100& *(ImgArray(x+dirx,y) and 255)) |
|||
Next |
|||
'line padding |
|||
if pad and 1 then .writetext chrw(ImgArray(x2,y)) |
|||
if pad >1 then .writetext chrw(0) |
|||
Next |
|||
Case Else |
|||
WScript.Echo "ColorDepth not supported : " & ImgDepth & " bits" |
|||
End Select |
|||
'use a second stream to save to file starting past the BOM the first ADODB.Stream has added |
|||
Dim outf:Set outf= CreateObject("ADODB.Stream") |
|||
outf.Type = 1 ' adTypeBinary |
|||
outf.Open |
|||
.position=2 'remove bom (1 wchar) |
|||
.CopyTo outf |
|||
.close |
|||
outf.savetofile filename,2 'adSaveCreateOverWrite |
|||
outf.close |
|||
end with |
|||
End Sub |
|||
End Class |
|||
function mandelpx(x0,y0,maxit) |
|||
dim x,y,xt,i,x2,y2 |
|||
i=0:x2=0:y2=0 |
|||
Do While i< maxit |
|||
i=i+1 |
|||
xt=x2-y2+x0 |
|||
y=2*x*y+y0 |
|||
x=xt |
|||
x2=x*x:y2=y*y |
|||
If (x2+y2)>=4 Then Exit do |
|||
loop |
|||
if i=maxit then |
|||
mandelpx=0 |
|||
else |
|||
mandelpx = i |
|||
end if |
|||
end function |
|||
Sub domandel(x1,x2,y1,y2) |
|||
Dim i,ii,j,jj,pix,xi,yi,ym |
|||
ym=X.ImgHeight\2 |
|||
'get increments in the mandel plane |
|||
xi=Abs((x1-x2)/X.ImgWidth) |
|||
yi=Abs((y2-0)/(X.ImgHeight\2)) |
|||
j=0 |
|||
For jj=0. To y2 Step yi |
|||
i=0 |
|||
For ii=x1 To x2 Step xi |
|||
pix=mandelpx(ii,jj,256) |
|||
'use simmetry |
|||
X.imgarray(i,ym-j)=pix |
|||
X.imgarray(i,ym+j)=pix |
|||
i=i+1 |
|||
Next |
|||
j=j+1 |
|||
next |
|||
End Sub |
|||
'main------------------------------------ |
|||
Dim i,x |
|||
'custom palette |
|||
dim pp(255) |
|||
for i=1 to 255 |
|||
pp(i)=rgb(0,0,255*(i/255)^.25) 'VBS' RGB function is for the web, it's bgr for Windows BMP !! |
|||
next |
|||
dim fn:fn=CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2)& "\mandel.bmp" |
|||
Set X = (New ImgClass)(fn,580,480,1,8,0,pp) |
|||
domandel -2.,1.,-1.2,1.2 |
|||
Set X = Nothing |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
[[File:Mandelbrot vbs.png]] |
|||
=={{header|Vedit macro language}}== |
|||
Vedit macro language does not support floating point calculations, so fixed point arithmetic is used, with Value 10000 representing 1.0. |
|||
The Mandelbrot image is drawn using ASCII characters 1-9 to show number of iterations. Iteration count 10 or more is represented with '@'. |
|||
To compensate the aspect ratio of the font, step sizes in x and y directions are different. |
|||
<syntaxhighlight lang="vedit">#1 =-21000 // left edge = -2.1 |
|||
#2 = 15000 // right edge = 1.5 |
|||
#3 = 15000 // top edge = 1.5 |
|||
#4 =-15000 // bottom edge = -1.5 |
|||
#5 = 200 // max iteration depth |
|||
#6 = 350 // x step size |
|||
#7 = 750 // y step size |
|||
Buf_Switch(Buf_Free) |
|||
for (#12 = #3; #12 > #4; #12 -= #7) { // y0 |
|||
for (#11 = #1; #11 < #2; #11 += #6) { // x0 |
|||
#22 = 0 // y |
|||
#21 = 0 // x |
|||
#9 = ' ' // char to be displayed |
|||
for (#15 = 0; #15 < #5; #15++) { // iteration |
|||
#31 = (#21/10 * #21) / 1000 // x*x |
|||
#32 = (#22/10 * #22) / 1000 // y*y |
|||
if (#31 + #32 > 40000) { |
|||
#9 = '0' + #15 // print digit 0...9 |
|||
if (#15 > 9) { // if iteration count > 9, |
|||
#9 = '@' // print '@' |
|||
} |
|||
break |
|||
} |
|||
#33 = #31 - #32 + #11 // temp = x*x - y*y + x0 |
|||
#22 = (#21/10 * #22) / 500 + #12 // y = 2*x*y + y0 |
|||
#21 = #33 // x = temp |
|||
} |
|||
Ins_Char(#9) |
|||
} |
|||
Ins_Newline |
|||
} |
|||
BOF |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<small> |
|||
<pre> |
|||
1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 |
|||
1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 |
|||
1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 |
|||
1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 |
|||
1111111111111112222222222222333333333333333333333333333333333333322222222222222222222222222222222222222 |
|||
1111111111111222222222233333333333333333333333344444457655544443333332222222222222222222222222222222222 |
|||
1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 |
|||
11111111111222222333333333333333333333334444444445555678@@@@7654444443333332222222222222222222222222222 |
|||
1111111112222223333333333333333333333444444444455556789@@@@98655544444433333332222222222222222222222222 |
|||
1111111122222333333333333333333333344444444445556668@@@ @@@@76555544444333333322222222222222222222222 |
|||
1111111122233333333333333333333344444444445566667778@@ @987666555544433333333222222222222222222222 |
|||
111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@87777@95443333333322222222222222222222 |
|||
1111112233333333333333333334444455555556678@@ @@ @@@@@@@8544333333333222222222222222222 |
|||
1111122333333333333333334445555555555666789@@@ @86554433333333322222222222222222 |
|||
1111123333333333333444466666555556666778@@@@ @@87655443333333332222222222222222 |
|||
111123333333344444455568@887789@8777788@@@ @@@@65443333333332222222222222222 |
|||
1111333344444444455556679@@@@@@@@@@@99@@@ @@765444333333333222222222222222 |
|||
1111334444444455555567789@@ @@@@ @855444333333333222222222222222 |
|||
11114444444455555668@99@@@ @ @@655444433333333322222222222222 |
|||
11134555556666677789@@@ @ @86655444433333333322222222222222 |
|||
111 @@876555444433333333322222222222222 |
|||
11134555556666677789@@@ @ @86655444433333333322222222222222 |
|||
11114444444455555668@99@@@ @ @@655444433333333322222222222222 |
|||
1111334444444455555567789@@ @@@@ @855444333333333222222222222222 |
|||
1111333344444444455556679@@@@@@@@@@@99@@@ @@765444333333333222222222222222 |
|||
111123333333344444455568@887789@8777788@@@ @@@@65443333333332222222222222222 |
|||
1111123333333333333444466666555556666778@@@@ @@87655443333333332222222222222222 |
|||
1111122333333333333333334445555555555666789@@@ @86554433333333322222222222222222 |
|||
1111112233333333333333333334444455555556678@@ @@ @@@@@@@8544333333333222222222222222222 |
|||
111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@87777@95443333333322222222222222222222 |
|||
1111111122233333333333333333333344444444445566667778@@ @987666555544433333333222222222222222222222 |
|||
1111111122222333333333333333333333344444444445556668@@@ @@@@76555544444333333322222222222222222222222 |
|||
1111111112222223333333333333333333333444444444455556789@@@@98655544444433333332222222222222222222222222 |
|||
11111111111222222333333333333333333333334444444445555678@@@@7654444443333332222222222222222222222222222 |
|||
1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 |
|||
1111111111111222222222233333333333333333333333344444457655544443333332222222222222222222222222222222222 |
|||
1111111111111112222222222222333333333333333333333333333333333333322222222222222222222222222222222222222 |
|||
1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 |
|||
1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 |
|||
1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 |
|||
</pre> |
|||
</small> |
|||
=={{header|V (Vlang)}}== |
|||
Graphical |
|||
<syntaxhighlight lang="Go"> |
|||
// updates and contributors at: github.com/vlang/v/blob/master/examples/gg/mandelbrot.v |
|||
// graphics are moveable by keyboard or mouse and resizable with window |
|||
import gg |
|||
import gx |
|||
import runtime |
|||
import time |
|||
const ( |
|||
pwidth = 800 |
|||
pheight = 600 |
|||
chunk_height = 2 // image recalculated in chunks, each chunk processed in separate thread |
|||
zoom_factor = 1.1 |
|||
max_iterations = 255 |
|||
) |
|||
struct ViewRect { |
|||
mut: |
|||
x_min f64 |
|||
x_max f64 |
|||
y_min f64 |
|||
y_max f64 |
|||
} |
|||
fn (v &ViewRect) width() f64 { |
|||
return v.x_max - v.x_min |
|||
} |
|||
fn (v &ViewRect) height() f64 { |
|||
return v.y_max - v.y_min |
|||
} |
|||
struct AppState { |
|||
mut: |
|||
gg &gg.Context = unsafe { nil } |
|||
iidx int |
|||
pixels &u32 = unsafe { vcalloc(pwidth * pheight * sizeof(u32)) } |
|||
npixels &u32 = unsafe { vcalloc(pwidth * pheight * sizeof(u32)) } // drawings here, results swapped at the end |
|||
view ViewRect = ViewRect{-3.0773593290970673, 1.4952456603855397, -2.019938598189011, 2.3106642054225945} |
|||
scale int = 1 |
|||
ntasks int = runtime.nr_jobs() |
|||
} |
|||
const colors = [gx.black, gx.blue, gx.red, gx.green, gx.yellow, gx.orange, gx.purple, gx.white, |
|||
gx.indigo, gx.violet, gx.black, gx.blue, gx.orange, gx.yellow, gx.green].map(u32(it.abgr8())) |
|||
struct MandelChunk { |
|||
cview ViewRect |
|||
ymin f64 |
|||
ymax f64 |
|||
} |
|||
fn (mut state AppState) update() { |
|||
mut chunk_channel := chan MandelChunk{cap: state.ntasks} |
|||
mut chunk_ready_channel := chan bool{cap: 1000} |
|||
mut threads := []thread{cap: state.ntasks} |
|||
defer { |
|||
chunk_channel.close() |
|||
threads.wait() |
|||
} |
|||
for t in 0 .. state.ntasks { |
|||
threads << spawn state.worker(t, chunk_channel, chunk_ready_channel) |
|||
} |
|||
// |
|||
mut oview := ViewRect{} |
|||
mut sw := time.new_stopwatch() |
|||
for { |
|||
sw.restart() |
|||
cview := state.view |
|||
if oview == cview { |
|||
time.sleep(5 * time.millisecond) |
|||
continue |
|||
} |
|||
// schedule chunks, describing the work: |
|||
mut nchunks := 0 |
|||
for start := 0; start < pheight; start += chunk_height { |
|||
chunk_channel <- MandelChunk{ |
|||
cview: cview |
|||
ymin: start |
|||
ymax: start + chunk_height |
|||
} |
|||
nchunks++ |
|||
} |
|||
// wait for all chunks to be processed: |
|||
for _ in 0 .. nchunks { |
|||
_ := <-chunk_ready_channel |
|||
} |
|||
// everything is done, swap the buffer pointers |
|||
state.pixels, state.npixels = state.npixels, state.pixels |
|||
println('${state.ntasks:2} threads; ${sw.elapsed().milliseconds():3} ms / frame; scale: ${state.scale:4}') |
|||
oview = cview |
|||
} |
|||
} |
|||
[direct_array_access] |
|||
fn (mut state AppState) worker(id int, input chan MandelChunk, ready chan bool) { |
|||
for { |
|||
chunk := <-input or { break } |
|||
yscale := chunk.cview.height() / pheight |
|||
xscale := chunk.cview.width() / pwidth |
|||
mut x, mut y, mut iter := 0.0, 0.0, 0 |
|||
mut y0 := chunk.ymin * yscale + chunk.cview.y_min |
|||
mut x0 := chunk.cview.x_min |
|||
for y_pixel := chunk.ymin; y_pixel < chunk.ymax && y_pixel < pheight; y_pixel++ { |
|||
yrow := unsafe { &state.npixels[int(y_pixel * pwidth)] } |
|||
y0 += yscale |
|||
x0 = chunk.cview.x_min |
|||
for x_pixel := 0; x_pixel < pwidth; x_pixel++ { |
|||
x0 += xscale |
|||
x, y = x0, y0 |
|||
for iter = 0; iter < max_iterations; iter++ { |
|||
x, y = x * x - y * y + x0, 2 * x * y + y0 |
|||
if x * x + y * y > 4 { |
|||
break |
|||
} |
|||
} |
|||
unsafe { |
|||
yrow[x_pixel] = colors[iter & 15] |
|||
} |
|||
} |
|||
} |
|||
ready <- true |
|||
} |
|||
} |
|||
fn (mut state AppState) draw() { |
|||
mut istream_image := state.gg.get_cached_image_by_idx(state.iidx) |
|||
istream_image.update_pixel_data(unsafe { &u8(state.pixels) }) |
|||
size := gg.window_size() |
|||
state.gg.draw_image(0, 0, size.width, size.height, istream_image) |
|||
} |
|||
fn (mut state AppState) zoom(zoom_factor f64) { |
|||
c_x, c_y := (state.view.x_max + state.view.x_min) / 2, (state.view.y_max + state.view.y_min) / 2 |
|||
d_x, d_y := c_x - state.view.x_min, c_y - state.view.y_min |
|||
state.view.x_min = c_x - zoom_factor * d_x |
|||
state.view.x_max = c_x + zoom_factor * d_x |
|||
state.view.y_min = c_y - zoom_factor * d_y |
|||
state.view.y_max = c_y + zoom_factor * d_y |
|||
state.scale += if zoom_factor < 1 { 1 } else { -1 } |
|||
} |
|||
fn (mut state AppState) center(s_x f64, s_y f64) { |
|||
c_x, c_y := (state.view.x_max + state.view.x_min) / 2, (state.view.y_max + state.view.y_min) / 2 |
|||
d_x, d_y := c_x - state.view.x_min, c_y - state.view.y_min |
|||
state.view.x_min = s_x - d_x |
|||
state.view.x_max = s_x + d_x |
|||
state.view.y_min = s_y - d_y |
|||
state.view.y_max = s_y + d_y |
|||
} |
|||
// gg callbacks: |
|||
fn graphics_init(mut state AppState) { |
|||
state.iidx = state.gg.new_streaming_image(pwidth, pheight, 4, pixel_format: .rgba8) |
|||
} |
|||
fn graphics_frame(mut state AppState) { |
|||
state.gg.begin() |
|||
state.draw() |
|||
state.gg.end() |
|||
} |
|||
fn graphics_click(x f32, y f32, btn gg.MouseButton, mut state AppState) { |
|||
if btn == .right { |
|||
size := gg.window_size() |
|||
m_x := (x / size.width) * state.view.width() + state.view.x_min |
|||
m_y := (y / size.height) * state.view.height() + state.view.y_min |
|||
state.center(m_x, m_y) |
|||
} |
|||
} |
|||
fn graphics_move(x f32, y f32, mut state AppState) { |
|||
if state.gg.mouse_buttons.has(.left) { |
|||
size := gg.window_size() |
|||
d_x := (f64(state.gg.mouse_dx) / size.width) * state.view.width() |
|||
d_y := (f64(state.gg.mouse_dy) / size.height) * state.view.height() |
|||
state.view.x_min -= d_x |
|||
state.view.x_max -= d_x |
|||
state.view.y_min -= d_y |
|||
state.view.y_max -= d_y |
|||
} |
|||
} |
|||
fn graphics_scroll(e &gg.Event, mut state AppState) { |
|||
state.zoom(if e.scroll_y < 0 { zoom_factor } else { 1 / zoom_factor }) |
|||
} |
|||
fn graphics_keydown(code gg.KeyCode, mod gg.Modifier, mut state AppState) { |
|||
s_x := state.view.width() / 5 |
|||
s_y := state.view.height() / 5 |
|||
// movement |
|||
mut d_x, mut d_y := 0.0, 0.0 |
|||
if code == .enter { |
|||
println('> ViewRect{${state.view.x_min}, ${state.view.x_max}, ${state.view.y_min}, ${state.view.y_max}}') |
|||
} |
|||
if state.gg.pressed_keys[int(gg.KeyCode.left)] { |
|||
d_x -= s_x |
|||
} |
|||
if state.gg.pressed_keys[int(gg.KeyCode.right)] { |
|||
d_x += s_x |
|||
} |
|||
if state.gg.pressed_keys[int(gg.KeyCode.up)] { |
|||
d_y -= s_y |
|||
} |
|||
if state.gg.pressed_keys[int(gg.KeyCode.down)] { |
|||
d_y += s_y |
|||
} |
|||
state.view.x_min += d_x |
|||
state.view.x_max += d_x |
|||
state.view.y_min += d_y |
|||
state.view.y_max += d_y |
|||
// zoom in/out |
|||
if state.gg.pressed_keys[int(gg.KeyCode.left_bracket)] |
|||
|| state.gg.pressed_keys[int(gg.KeyCode.z)] { |
|||
state.zoom(1 / zoom_factor) |
|||
return |
|||
} |
|||
if state.gg.pressed_keys[int(gg.KeyCode.right_bracket)] |
|||
|| state.gg.pressed_keys[int(gg.KeyCode.x)] { |
|||
state.zoom(zoom_factor) |
|||
return |
|||
} |
|||
} |
|||
fn main() { |
|||
mut state := &AppState{} |
|||
state.gg = gg.new_context( |
|||
width: 800 |
|||
height: 600 |
|||
create_window: true |
|||
window_title: 'The Mandelbrot Set' |
|||
init_fn: graphics_init |
|||
frame_fn: graphics_frame |
|||
click_fn: graphics_click |
|||
move_fn: graphics_move |
|||
keydown_fn: graphics_keydown |
|||
scroll_fn: graphics_scroll |
|||
user_data: state |
|||
) |
|||
spawn state.update() |
|||
state.gg.run() |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|Wren}}== |
|||
{{trans|Kotlin}} |
|||
{{libheader|DOME}} |
|||
<syntaxhighlight lang="wren">import "graphics" for Canvas, Color |
|||
import "dome" for Window |
|||
var MaxIters = 570 |
|||
var Zoom = 150 |
|||
class MandelbrotSet { |
|||
construct new(width, height) { |
|||
Window.title = "Mandelbrot Set" |
|||
Window.resize(width, height) |
|||
Canvas.resize(width, height) |
|||
_w = width |
|||
_h = height |
|||
} |
|||
init() { |
|||
createMandelbrot() |
|||
} |
|||
createMandelbrot() { |
|||
for (x in 0..._w) { |
|||
for (y in 0..._h) { |
|||
var zx = 0 |
|||
var zy = 0 |
|||
var cX = (x - 400) / Zoom |
|||
var cY = (y - 300) / Zoom |
|||
var i = MaxIters |
|||
while (zx * zx + zy * zy < 4 && i > 0) { |
|||
var tmp = zx * zx - zy * zy + cX |
|||
zy = 2 * zx * zy + cY |
|||
zx = tmp |
|||
i = i - 1 |
|||
} |
|||
var r = i * 255 / MaxIters |
|||
Canvas.pset(x, y, Color.rgb(r, r, r)) |
|||
} |
|||
} |
|||
} |
|||
update() {} |
|||
draw(alpha) {} |
|||
} |
|||
var Game = MandelbrotSet.new(800, 600)</syntaxhighlight> |
|||
{{out}} |
|||
[[File:Wren-Mandelbrot_set.png|400px]] |
|||
=={{header|XPL0}}== |
|||
<syntaxhighlight lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations |
|||
int X, Y, \screen coordinates of current point |
|||
Cnt; \iteration counter |
|||
real Cx, Cy, \coordinates scaled to +/-2 range |
|||
Zx, Zy, \complex accumulator |
|||
Temp; \temporary scratch |
|||
[SetVid($112); \set 640x480x24 graphics mode |
|||
for Y:= 0 to 480-1 do \for all points on the screen... |
|||
for X:= 0 to 640-1 do |
|||
[Cx:= (float(X)/640.0 - 0.5) * 4.0; \range: -2.0 to +2.0 |
|||
Cy:= (float(Y-240)/240.0) * 1.5; \range: -1.5 to +1.5 |
|||
Cnt:= 0; Zx:= 0.0; Zy:= 0.0; \initialize |
|||
loop [if Zx*Zx + Zy*Zy > 2.0 then \Z heads toward infinity |
|||
[Point(X, Y, Cnt<<21+Cnt<<10+Cnt<<3); \set color of pixel to |
|||
quit; \ rate it approached infinity |
|||
]; \move on to next point |
|||
Temp:= Zx*Zy; |
|||
Zx:= Zx*Zx - Zy*Zy + Cx; \calculate next iteration of Z |
|||
Zy:= 2.0*Temp + Cy; |
|||
Cnt:= Cnt+1; \count number of iterations |
|||
if Cnt >= 1000 then quit; \assume point is in Mandelbrot |
|||
]; \ set and leave it colored black |
|||
]; |
|||
X:= ChIn(1); \wait for keystroke |
|||
SetVid($03); \restore normal text display |
|||
]</syntaxhighlight> |
|||
{{out}} |
|||
[[File:MandelXPL0.png]] |
|||
=={{header|XSLT}}== |
=={{header|XSLT}}== |
||
The fact that you can create an image of the Mandelbrot Set with XSLT is sometimes under-appreciated. |
The fact that you can create an image of the Mandelbrot Set with XSLT is sometimes under-appreciated. |
||
However, it has been discussed extensively [http://thedailywtf.com/Articles/Stupid-Coding-Tricks-XSLT-Mandelbrot.aspx on the internet] so is best reproduced here, and the code can be executed directly in your browser at that site. |
|||
{{omit from|M4}} |
{{omit from|M4}} |
||
<syntaxhighlight lang="xml"> |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
|||
<!-- XSLT Mandelbrot - written by Joel Yliluoma 2007, http://iki.fi/bisqwit/ --> |
|||
<xsl:output method="html" indent="no" |
|||
doctype-public="-//W3C//DTD HTML 4.01//EN" |
|||
doctype-system="http://www.w3.org/TR/REC-html40/strict.dtd" |
|||
/> |
|||
<xsl:template match="/fractal"> |
|||
<html> |
|||
<head> |
|||
<title>XSLT fractal</title> |
|||
<style type="text/css"> |
|||
body { color:#55F; background:#000 } |
|||
pre { font-family:monospace; font-size:7px } |
|||
pre span { background:<xsl:value-of select="background" /> } |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div style="position:absolute;top:20px;left:20em"> |
|||
Copyright © 1992,2007 Joel Yliluoma |
|||
(<a href="http://iki.fi/bisqwit/">http://iki.fi/bisqwit/</a>) |
|||
</div> |
|||
<h1 style="margin:0px">XSLT fractal</h1> |
|||
<pre><xsl:call-template name="bisqwit-mandelbrot" /></pre> |
|||
</body> |
|||
</html> |
|||
</xsl:template> |
|||
<xsl:template name="bisqwit-mandelbrot" |
|||
><xsl:call-template name="bisqwit-mandelbrot-line"> |
|||
<xsl:with-param name="y" select="y/min"/> |
|||
</xsl:call-template |
|||
></xsl:template> |
|||
<xsl:template name="bisqwit-mandelbrot-line" |
|||
><xsl:param name="y" |
|||
/><xsl:call-template name="bisqwit-mandelbrot-column"> |
|||
<xsl:with-param name="x" select="x/min"/> |
|||
<xsl:with-param name="y" select="$y"/> |
|||
</xsl:call-template |
|||
><xsl:if test="$y < y/max" |
|||
><br |
|||
/><xsl:call-template name="bisqwit-mandelbrot-line"> |
|||
<xsl:with-param name="y" select="$y + y/step"/> |
|||
</xsl:call-template |
|||
></xsl:if |
|||
></xsl:template> |
|||
<xsl:template name="bisqwit-mandelbrot-column" |
|||
><xsl:param name="x" |
|||
/><xsl:param name="y" |
|||
/><xsl:call-template name="bisqwit-mandelbrot-slot"> |
|||
<xsl:with-param name="x" select="$x" /> |
|||
<xsl:with-param name="y" select="$y" /> |
|||
<xsl:with-param name="zr" select="$x" /> |
|||
<xsl:with-param name="zi" select="$y" /> |
|||
</xsl:call-template |
|||
><xsl:if test="$x < x/max" |
|||
><xsl:call-template name="bisqwit-mandelbrot-column"> |
|||
<xsl:with-param name="x" select="$x + x/step"/> |
|||
<xsl:with-param name="y" select="$y" /> |
|||
</xsl:call-template |
|||
></xsl:if |
|||
></xsl:template> |
|||
<xsl:template name="bisqwit-mandelbrot-slot" |
|||
><xsl:param name="x" |
|||
/><xsl:param name="y" |
|||
/><xsl:param name="zr" |
|||
/><xsl:param name="zi" |
|||
/><xsl:param name="iter" select="0" |
|||
/><xsl:variable name="zrsqr" select="($zr * $zr)" |
|||
/><xsl:variable name="zisqr" select="($zi * $zi)" |
|||
/><xsl:choose> |
|||
<xsl:when test="(4*scale*scale >= $zrsqr + $zisqr) and (maxiter > $iter+1)" |
|||
><xsl:call-template name="bisqwit-mandelbrot-slot"> |
|||
<xsl:with-param name="x" select="$x" /> |
|||
<xsl:with-param name="y" select="$y" /> |
|||
<xsl:with-param name="zi" select="(2 * $zr * $zi) div scale + $y" /> |
|||
<xsl:with-param name="zr" select="($zrsqr - $zisqr) div scale + $x" /> |
|||
<xsl:with-param name="iter" select="$iter + 1" /> |
|||
</xsl:call-template |
|||
></xsl:when> |
|||
<xsl:otherwise |
|||
><xsl:variable name="magnitude" select="magnitude[@value=$iter]" |
|||
/><span style="color:{$magnitude/color}" |
|||
><xsl:value-of select="$magnitude/symbol" |
|||
/></span></xsl:otherwise> |
|||
</xsl:choose |
|||
></xsl:template> |
|||
</xsl:stylesheet> |
|||
</syntaxhighlight> |
|||
=={{header|Z80 Assembly}}== |
|||
<syntaxhighlight lang="z80"> |
|||
; |
|||
; Compute a Mandelbrot set on a simple Z80 computer. |
|||
; |
|||
; Porting this program to another Z80 platform should be easy and straight- |
|||
; forward: The only dependencies on my homebrew machine are the system-calls |
|||
; used to print strings and characters. These calls are performed by loading |
|||
; IX with the number of the system-call and performing an RST 08. To port this |
|||
; program to another operating system just replace these system-calls with |
|||
; the appropriate versions. Only three system-calls are used in the following: |
|||
; _crlf: Prints a CR/LF, _puts: Prints a 0-terminated string (the adress of |
|||
; which is expected in HL), and _putc: Print a single character which is |
|||
; expected in A. RST 0 give control back to the monitor. |
|||
; |
|||
#include "mondef.asm" |
|||
org ram_start |
|||
scale equ 256 ; Do NOT change this - the |
|||
; arithmetic routines rely on |
|||
; this scaling factor! :-) |
|||
divergent equ scale * 4 |
|||
ld hl, welcome ; Print a welcome message |
|||
ld ix, _puts |
|||
rst 08 |
|||
; for (y = <initial_value> ; y <= y_end; y += y_step) |
|||
; { |
|||
outer_loop ld hl, (y_end) ; Is y <= y_end? |
|||
ld de, (y) |
|||
and a ; Clear carry |
|||
sbc hl, de ; Perform the comparison |
|||
jp m, mandel_end ; End of outer loop reached |
|||
; for (x = x_start; x <= x_end; x += x_step) |
|||
; { |
|||
ld hl, (x_start) ; x = x_start |
|||
ld (x), hl |
|||
inner_loop ld hl, (x_end) ; Is x <= x_end? |
|||
ld de, (x) |
|||
and a |
|||
sbc hl, de |
|||
jp m, inner_loop_end ; End of inner loop reached |
|||
; z_0 = z_1 = 0; |
|||
ld hl, 0 |
|||
ld (z_0), hl |
|||
ld (z_1), hl |
|||
; for (iteration = iteration_max; iteration; iteration--) |
|||
; { |
|||
ld a, (iteration_max) |
|||
ld b, a |
|||
iteration_loop push bc ; iteration -> stack |
|||
; z2 = (z_0 * z_0 - z_1 * z_1) / SCALE; |
|||
ld de, (z_1) ; Compute DE HL = z_1 * z_1 |
|||
ld bc, de |
|||
call mul_16 |
|||
ld (z_0_square_low), hl ; z_0 ** 2 is needed later again |
|||
ld (z_0_square_high), de |
|||
ld de, (z_0) ; Compute DE HL = z_0 * z_0 |
|||
ld bc, de |
|||
call mul_16 |
|||
ld (z_1_square_low), hl ; z_1 ** 2 will be also needed |
|||
ld (z_1_square_high), de |
|||
and a ; Compute subtraction |
|||
ld bc, (z_0_square_low) |
|||
sbc hl, bc |
|||
ld (scratch_0), hl ; Save lower 16 bit of result |
|||
ld hl, de |
|||
ld bc, (z_0_square_high) |
|||
sbc hl, bc |
|||
ld bc, (scratch_0) ; HL BC = z_0 ** 2 - z_1 ** 2 |
|||
ld c, b ; Divide by scale = 256 |
|||
ld b, l ; Discard the rest |
|||
push bc ; We need BC later |
|||
; z3 = 2 * z0 * z1 / SCALE; |
|||
ld hl, (z_0) ; Compute DE HL = 2 * z_0 * z_1 |
|||
add hl, hl |
|||
ld de, hl |
|||
ld bc, (z_1) |
|||
call mul_16 |
|||
ld b, e ; Divide by scale (= 256) |
|||
ld c, h ; BC contains now z_3 |
|||
; z1 = z3 + y; |
|||
ld hl, (y) |
|||
add hl, bc |
|||
ld (z_1), hl |
|||
; z_0 = z_2 + x; |
|||
pop bc ; Here BC is needed again :-) |
|||
ld hl, (x) |
|||
add hl, bc |
|||
ld (z_0), hl |
|||
; if (z0 * z0 / SCALE + z1 * z1 / SCALE > 4 * SCALE) |
|||
ld hl, (z_0_square_low) ; Use the squares computed |
|||
ld de, (z_1_square_low) ; above |
|||
add hl, de |
|||
ld bc, hl ; BC contains lower word of sum |
|||
ld hl, (z_0_square_high) |
|||
ld de, (z_1_square_high) |
|||
adc hl, de |
|||
ld h, l ; HL now contains (z_0 ** 2 + |
|||
ld l, b ; z_1 ** 2) / scale |
|||
ld bc, divergent |
|||
and a |
|||
sbc hl, bc |
|||
; break; |
|||
jp c, iteration_dec ; No break |
|||
pop bc ; Get latest iteration counter |
|||
jr iteration_end ; Exit loop |
|||
; iteration++; |
|||
iteration_dec pop bc ; Get iteration counter |
|||
djnz iteration_loop ; We might fall through! |
|||
; } |
|||
iteration_end |
|||
; printf("%c", display[iteration % 7]); |
|||
ld a, b |
|||
and $7 ; lower three bits only (c = 0) |
|||
sbc hl, hl |
|||
ld l, a |
|||
ld de, display ; Get start of character array |
|||
add hl, de ; address and load the |
|||
ld a, (hl) ; character to be printed |
|||
ld ix, _putc ; Print the character |
|||
rst 08 |
|||
ld de, (x_step) ; x += x_step |
|||
ld hl, (x) |
|||
add hl, de |
|||
ld (x), hl |
|||
jp inner_loop |
|||
; } |
|||
; printf("\n"); |
|||
inner_loop_end ld ix, _crlf ; Print a CR/LF pair |
|||
rst 08 |
|||
ld de, (y_step) ; y += y_step |
|||
ld hl, (y) |
|||
add hl, de |
|||
ld (y), hl ; Store new y-value |
|||
jp outer_loop |
|||
; } |
|||
mandel_end ld hl, finished ; Print finished-message |
|||
ld ix, _puts |
|||
rst 08 |
|||
rst 0 ; Return to the monitor |
|||
welcome defb "Generating a Mandelbrot set" |
|||
defb cr, lf, eos |
|||
finished defb "Computation finished.", cr, lf, eos |
|||
iteration_max defb 10 ; How many iterations |
|||
x defw 0 ; x-coordinate |
|||
x_start defw -2 * scale ; Minimum x-coordinate |
|||
x_end defw 5 * scale / 10 ; Maximum x-coordinate |
|||
x_step defw 4 * scale / 100 ; x-coordinate step-width |
|||
y defw -1 * scale ; Minimum y-coordinate |
|||
y_end defw 1 * scale ; Maximum y-coordinate |
|||
y_step defw 1 * scale / 10 ; y-coordinate step-width |
|||
z_0 defw 0 |
|||
z_1 defw 0 |
|||
scratch_0 defw 0 |
|||
z_0_square_high defw 0 |
|||
z_0_square_low defw 0 |
|||
z_1_square_high defw 0 |
|||
z_1_square_low defw 0 |
|||
display defb " .-+*=#@" ; 8 characters for the display |
|||
; |
|||
; Compute DEHL = BC * DE (signed): This routine is not too clever but it |
|||
; works. It is based on a standard 16-by-16 multiplication routine for unsigned |
|||
; integers. At the beginning the sign of the result is determined based on the |
|||
; signs of the operands which are negated if necessary. Then the unsigned |
|||
; multiplication takes place, followed by negating the result if necessary. |
|||
; |
|||
mul_16 xor a ; Clear carry and A (-> +) |
|||
bit 7, b ; Is BC negative? |
|||
jr z, bc_positive ; No |
|||
sub c ; A is still zero, complement |
|||
ld c, a |
|||
ld a, 0 |
|||
sbc a, b |
|||
ld b, a |
|||
scf ; Set carry (-> -) |
|||
bc_positive bit 7, D ; Is DE negative? |
|||
jr z, de_positive ; No |
|||
push af ; Remember carry for later! |
|||
xor a |
|||
sub e |
|||
ld e, a |
|||
ld a, 0 |
|||
sbc a, d |
|||
ld d, a |
|||
pop af ; Restore carry for complement |
|||
ccf ; Complement Carry (-> +/-?) |
|||
de_positive push af ; Remember state of carry |
|||
and a ; Start multiplication |
|||
sbc hl, hl |
|||
ld a, 16 ; 16 rounds |
|||
mul_16_loop add hl, hl |
|||
rl e |
|||
rl d |
|||
jr nc, mul_16_exit |
|||
add hl, bc |
|||
jr nc, mul_16_exit |
|||
inc de |
|||
mul_16_exit dec a |
|||
jr nz, mul_16_loop |
|||
pop af ; Restore carry from beginning |
|||
ret nc ; No sign inversion necessary |
|||
xor a ; Complement DE HL |
|||
sub l |
|||
ld l, a |
|||
ld a, 0 |
|||
sbc a, h |
|||
ld h, a |
|||
ld a, 0 |
|||
sbc a, e |
|||
ld e, a |
|||
ld a, 0 |
|||
sbc a, d |
|||
ld d, a |
|||
ret |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Generating a Mandelbrot set |
|||
....... @@@@@@@@@@@@@@@@@@@@########===*+ . *######@@@@@ |
|||
...... @@@@@@@@@@@@@@@@@@@@#########====+-. -*===#####@@@@ |
|||
..... @@@@@@@@@@@@@@@@@@@@#########===**+- +*====####@@ |
|||
.... @@@@@@@@@@@@@@@@@@@########==*+-.-+-.. .-+****+*##@ |
|||
... @@@@@@@@@@@@@@@@@#####=====**+- -=# |
|||
.. @@@@@@@@@@@@@@@###=========***+- -*== |
|||
..@@@@@@@@@@####==- +*******++++- -+= |
|||
. @@@@#######===**- ... -* |
|||
.@@#######======++- += |
|||
.#######=****+- +*= |
|||
.=**++ .-.... .+*== |
|||
.#=====****+++. -*== |
|||
.@#######=====*--- .*= |
|||
.@@@########====*++. += |
|||
. @@@@@@@######==*+ .-++- --++--. = |
|||
.. @@@@@@@@@@@@@##==*=======****+ -+*= |
|||
... @@@@@@@@@@@@@@@@####=======***+- +== |
|||
... @@@@@@@@@@@@@@@@@@@######====*- . --+- *## |
|||
.... @@@@@@@@@@@@@@@@@@@@########==****++- .-+**====###@ |
|||
..... @@@@@@@@@@@@@@@@@@@@##########===*+ *===#####@@@ |
|||
....... @@@@@@@@@@@@@@@@@@@@@########===*+-. .+*=######@@@@@ |
|||
Computation finished. |
|||
</pre> |
|||
=={{header|zkl}}== |
|||
Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl |
|||
{{trans|XPL0}} |
|||
[[File:Mandelbrot.zkl.jpg|300px|thumb|right]] |
|||
<syntaxhighlight lang="zkl">fcn mandelbrot{ // lord this is slooooow |
|||
bitmap:=PPM(640,480); |
|||
foreach y,x in ([0..479],[0..639]){ |
|||
cx:=(x.toFloat()/640 - 0.5)*4.0; //range: -2.0 to +2.0 |
|||
cy:=((y-240).toFloat()/240.0)*1.5; //range: -1.5 to +1.5 |
|||
cnt:=0; zx:=0.0; zy:=0.0; |
|||
do(1000){ |
|||
if(zx*zx + zy*zy > 2.0){ //z heads toward infinity |
|||
//set color of pixel to rate it approaches infinity |
|||
bitmap[x,y]=cnt.shiftLeft(21) + cnt.shiftLeft(10) + cnt*8; |
|||
break; |
|||
} |
|||
temp:=zx*zy; |
|||
zx=zx*zx - zy*zy + cx; //calculate next iteration of z |
|||
zy=2.0*temp + cy; |
|||
cnt+=1; |
|||
} |
|||
} |
|||
bitmap.write(File("foo.ppm","wb")); |
|||
}();</syntaxhighlight> |
|||
{{omit from|Lilypond}} |
|||
{{omit from|ML/I}} |
|||
[[Category:Geometry]] |
Latest revision as of 15:55, 13 August 2024
This page uses content from Wikipedia. The original article was at Mandelbrot_set. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance) |
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Generate and draw the Mandelbrot set.
Note that there are many algorithms to draw Mandelbrot set and there are many functions which generate it .
11l
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"))
ACL2
(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)))
- Output:
> (draw-mandelbrot 60 100) # .. .#### . # .##. ##*###############. #.################## .######################. ######. ####################### ##########.###################### ############################################## ##########.###################### ######. ####################### .######################. #.################## ##*###############. . # .##. .#### ..
AArch64 Assembly
Compiler: GNU Compiler Collection (v12.2.0)
The size of the drawn image is adjustable through xsize and ysize, and the precision through limit.
#include <stdio.h>
.globl main
.section .text
.macro NEWLINE
mov x0, #10
stp x9, x10, [sp, #-16]!
bl putchar
ldp x9, x10, [sp], 16
.endm
.macro PRINTCHAR p
mov x1, \p
mov x0, #64
sub x0, x0, x1
stp x9, x10, [sp, #-16]!
bl putchar
ldp x9, x10, [sp], 16
.endm
xsize .req x9
xsize_w .req w9
ysize .req x10
ysize_w .req w10
min_imag .req s8
max_imag .req s9
min_real .req s10
max_real .req s9
imag .req s11
real .req s12
step_x .req s13
step_y .req s14
zi .req s15
zr .req s16
a .req s17
b .req s18
ftemp_1 .req s19
ftemp_2 .req s20
y .req x19
y_w .req w19
x .req x20
x_w .req w20
n .req x21
limit .req x22
itemp_1 .req x23
itemp_1w .req w23
/*
redefining register names
for easier implementation
*/
main:
stp xzr, lr, [sp, #-16]!
stp d8, d9, [sp, #-16]!
stp d10, d11,[sp, #-16]!
stp d12, d13,[sp, #-16]!
stp d14, d15,[sp, #-16]!
stp x19, x20,[sp, #-16]!
stp x21, x22,[sp, #-16]!
stp x23, x24,[sp, #-16]!
mov xsize, #108
mov ysize, #72
mov limit, #32
fmov min_imag, #-1.0
fmov max_imag, #1.0
fmov min_real, #-2.0
// fmov max_real #1.0
fsub step_x, max_real, min_real
scvtf ftemp_1, xsize_w
fdiv step_x, step_x, ftemp_1
fsub step_y, max_imag, min_imag
scvtf ftemp_1, ysize_w
fdiv step_y, step_y, ftemp_1
mov y, #0
1:
cmp y, ysize
b.eq 20f
scvtf ftemp_1, y_w
fmadd imag, step_y, ftemp_1, min_imag
mov x, #0
2:
cmp x, xsize
b.eq 15f
scvtf ftemp_1, x_w
fmadd real, step_y, ftemp_1, min_real
fmov zr, real
fmov zi, imag
mov n, #0
3:
cmp n, limit
b.eq 10f
fmul a, zr, zr
fmul b, zi, zi
fadd ftemp_1, a, b
fmov ftemp_2, #4.0
fcmp ftemp_1, ftemp_2
b.gt 10f
fmul zi, zi, zr
fmov ftemp_2, #2.0
fmadd zi, zi, ftemp_2, imag
fsub zr, a, b
fadd zr, zr, real
add n, n, #1
b 3b
10:
add x, x, #1
PRINTCHAR n
b 2b
15:
add y, y, #1
NEWLINE
b 1b
20:
ldp x23, x24,[sp], 16
ldp x21, x22,[sp], 16
ldp x19, x20,[sp], 16
ldp d14, d15,[sp], 16
ldp d12, d13,[sp], 16
ldp d10, d11,[sp], 16
ldp d8, d9, [sp], 16
ldp xzr, lr, [sp], 16
ret
- Output:
@@@@@@@@@@?????????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<<;;9827873 ;<========>>>>>>>?????????????????? @@@@@@@@@@????????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<<<;:984-047:;<<========>>>>>>>????????????????? @@@@@@@@@???????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<;::9861479:;<<<========>>>>>>>>??????????????? @@@@@@@@@??????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<;;:9964*469:;;<<<=======>>>>>>>>>?????????????? @@@@@@@@??????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<<;:7871 ,489:;<<<<=======>>>>>>>>>????????????? @@@@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<<<;;:74441 3663;<<<<<=======>>>>>>>>>???????????? @@@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<<<;;:821.- 3 7:;<<<<<<======>>>>>>>>>??????????? @@@@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<;;;;::970 ,+::;<<<<<<=====>>>>>>>>>>?????????? @@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<;;;;;:::97' 379:;;<<<<<<<====>>>>>>>>>?????????? @@@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<;;;;;;:::983+ 79::;;;;<<<<<====>>>>>>>>>????????? @@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<;::::::::98862 3799::;;;;;;;<<===>>>>>>>>>>???????? @@@@@???>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<<:899*8999887764' 467888::;;;::3;<===>>>>>>>>>>??????? @@@@@???>>>>>>>>>>>>>>>>>>>>>>>>>==========<<<<;;9242 6887/'5 31/% '/24-63 79::::929;<==>>>>>>>>>>??????? @@@@???>>>>>>>>>>>>>>>>>>>>>>>>>========<<<<<<;;::60"00465, . " 1 889887$9;<===>>>>>>>>>>?????? @@@@??>>>>>>>>>>>>>>>>>>>>>>>>>=======<<<<<<<;;;::#2( #*30+ 4674+55(*6<<==>>>>>>>>>>>????? @@@@??>>>>>>>>>>>>>>>>>>>>>>>======<<<<<<<<<;;;;:984+ . 4 + +39<<===>>>>>>>>>>????? @@@??>>>>>>>>>>>>>>>>>>>>>>>=====<<<<<<<<<<;;;;::98( / 36:;<<==>>>>>>>>>>>???? @@@??>>>>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<;;;;;:9875* '29;;<<==>>>>>>>>>>>???? @@@?>>>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<<;;;;;:97 62. /6:;;<<===>>>>>>>>>>>??? @@@?>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<<<;;;;;:9/#/2 058::;<<===>>>>>>>>>>>??? @@??>>>>>>>>>>>>>>>>====<<:;;;;;;<<<<;;;;;;::98 % 369:;;<<==>>>>>>>>>>>??? @@?>>>>>>>>>>>>>>======<<:48:;;;;;;;;;;::::::9861 899;<<===>>>>>>>>>>>?? @@?>>>>>>>>>>>=======<<<;:929:::::9,9:::::::99742 3/74:<<===>>>>>>>>>>>?? @@>>>>>>>>>=========<<<;;;75899:995 799:::9998- 1-9<<===>>>>>>>>>>>>? @@>>>>>>>==========<<<<;;:8/5)67885068889998874 /:;<====>>>>>>>>>>>? @?>>>>>==========<<<<<<;;:974$/2 652 341788877 ' 39;;<====>>>>>>>>>>>? @?>>>>==========<<<<<<<;::9862&& 11& ,0 437765 79;<<====>>>>>>>>>>>? @>>>>==========<<<<<<<;;::9850 ..5654 064;<<====>>>>>>>>>>>> @>>>==========<<<<<<<<;:::8752 )442" .7;<<====>>>>>>>>>>>> @>>==========<<<<<<<<;:::9 52* 020 -%9;<<=====>>>>>>>>>>> @>==========<<<<<<<<;999885 /- 27:;<<=====>>>>>>>>>>> @>==========<<<;;;;:95788762 )* 8;<<<=====>>>>>>>>>>> @==========<;;;;;;::9726543 $ #6:;<<<=====>>>>>>>>>>> @===<====<;;;;;;::::8730//0# 29:;<<<=====>>>>>>>>>>> @<<<<;;;9:::;;;:::98853 8:;;<<<=====>>>>>>>>>>> @<<;;;::77999889986562* 79:;;<<<=====>>>>>>>>>>> 7 ""! 0589:;;<<<=====>>>>>>>>>>> @<<;;;::77999889986562* 79:;;<<<=====>>>>>>>>>>> @<<<<;;;9:::;;;:::98853 8:;;<<<=====>>>>>>>>>>> @===<====<;;;;;;::::8730//0# 29:;<<<=====>>>>>>>>>>> @==========<;;;;;;::9726543 $ #6:;<<<=====>>>>>>>>>>> @>==========<<<;;;;:95788762 )* 8;<<<=====>>>>>>>>>>> @>==========<<<<<<<<;999885 /- 27:;<<=====>>>>>>>>>>> @>>==========<<<<<<<<;:::9 52* 020 -%9;<<=====>>>>>>>>>>> @>>>==========<<<<<<<<;:::8752 )442" .7;<<====>>>>>>>>>>>> @>>>>==========<<<<<<<;;::9850 ..5654 064;<<====>>>>>>>>>>>> @?>>>>==========<<<<<<<;::9862&& 11& ,0 437765 79;<<====>>>>>>>>>>>? @?>>>>>==========<<<<<<;;:974$/2 652 341788877 ' 39;;<====>>>>>>>>>>>? @@>>>>>>>==========<<<<;;:8/5)67885068889998874 /:;<====>>>>>>>>>>>? @@>>>>>>>>>=========<<<;;;75899:995 799:::9998- 1-9<<===>>>>>>>>>>>>? @@?>>>>>>>>>>>=======<<<;:929:::::9,9:::::::99742 3/74:<<===>>>>>>>>>>>?? @@?>>>>>>>>>>>>>>======<<:48:;;;;;;;;;;::::::9861 899;<<===>>>>>>>>>>>?? @@??>>>>>>>>>>>>>>>>====<<:;;;;;;<<<<;;;;;;::98 % 369:;;<<==>>>>>>>>>>>??? @@@?>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<<<;;;;;:9/#/2 058::;<<===>>>>>>>>>>>??? @@@?>>>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<<;;;;;:97 62. /6:;;<<===>>>>>>>>>>>??? @@@??>>>>>>>>>>>>>>>>>>>>>====<<<<<<<<<<<<;;;;;:9875* '29;;<<==>>>>>>>>>>>???? @@@??>>>>>>>>>>>>>>>>>>>>>>>=====<<<<<<<<<<;;;;::98( / 36:;<<==>>>>>>>>>>>???? @@@@??>>>>>>>>>>>>>>>>>>>>>>>======<<<<<<<<<;;;;:984+ . 4 + +39<<===>>>>>>>>>>????? @@@@??>>>>>>>>>>>>>>>>>>>>>>>>>=======<<<<<<<;;;::#2( #*30+ 4674+55(*6<<==>>>>>>>>>>>????? @@@@???>>>>>>>>>>>>>>>>>>>>>>>>>========<<<<<<;;::60"00465, . " 1 889887$9;<===>>>>>>>>>>?????? @@@@@???>>>>>>>>>>>>>>>>>>>>>>>>>==========<<<<;;9242 6887/'5 31/% '/24-63 79::::929;<==>>>>>>>>>>??????? @@@@@???>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<<:899*8999887764' 467888::;;;::3;<===>>>>>>>>>>??????? @@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<;::::::::98862 3799::;;;;;;;<<===>>>>>>>>>>???????? @@@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<;;;;;;:::983+ 79::;;;;<<<<<====>>>>>>>>>????????? @@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<;;;;;:::97' 379:;;<<<<<<<====>>>>>>>>>?????????? @@@@@@@????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<;;;;::970 ,+::;<<<<<<=====>>>>>>>>>>?????????? @@@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<<<;;:821.- 3 7:;<<<<<<======>>>>>>>>>??????????? @@@@@@@@?????>>>>>>>>>>>>>>>>>>>>>>>>>>>>=============<<<<<;;:74441 3663;<<<<<=======>>>>>>>>>???????????? @@@@@@@@??????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<<;:7871 ,489:;<<<<=======>>>>>>>>>????????????? @@@@@@@@@??????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<;;:9964*469:;;<<<=======>>>>>>>>>?????????????? @@@@@@@@@???????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>============<<<<<;::9861479:;<<<========>>>>>>>>??????????????? @@@@@@@@@@????????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>===========<<<<<;:984-047:;<<========>>>>>>>?????????????????
Ada
mandelbrot.adb:
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;
mandelbrot.ads:
with Lumen.Image;
package Mandelbrot is
function Create_Image (Width, Height : Natural) return Lumen.Image.Descriptor;
end Mandelbrot;
test_mandelbrot.adb:
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;
- Output:
ALGOL 68
Plot part of the Mandelbrot set as a pseudo-gif image.
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)
ALGOL W
Generates an ASCII Mandelbrot Set. Translated from the sample program in the Compiler/AST Interpreter task.
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.
- Output:
1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 1111111111111112222222222222333333333333333333333333333333333333222222222222222222222222222222222222222 1111111111111222222222233333333333333333333333344444456655544443333332222222222222222222222222222222222 1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 11111111111222222333333333333333333333334444444445555679@@@@7654444443333333222222222222222222222222222 1111111112222223333333333333333333333444444444455556789@@@@98755544444433333332222222222222222222222222 1111111122223333333333333333333333344444444445556668@@@ @@@76555544444333333322222222222222222222222 1111111222233333333333333333333344444444455566667778@@ @987666555544433333333222222222222222222222 111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@877779@5443333333322222222222222222222 1111112233333333333333333334444455555556679@ @@@ @@@@@@ 8544333333333222222222222222222 1111122333333333333333334445555555556666789@@@ @86554433333333322222222222222222 1111123333333333333444456666555556666778@@ @ @@87655443333333332222222222222222 111123333333344444455568@887789@8777788@@@ @@@@65444333333332222222222222222 111133334444444455555668@@@@@@@@@@@@99@@@ @@765444333333333222222222222222 111133444444445555556778@@@ @@@@ @855444333333333222222222222222 11124444444455555668@99@@ @ @655444433333333322222222222222 11134555556666677789@@ @86655444433333333322222222222222 111 @@876555444433333333322222222222222 11134555556666677789@@ @86655444433333333322222222222222 11124444444455555668@99@@ @ @655444433333333322222222222222 111133444444445555556778@@@ @@@@ @855444333333333222222222222222 111133334444444455555668@@@@@@@@@@@@99@@@ @@765444333333333222222222222222 111123333333344444455568@887789@8777788@@@ @@@@65444333333332222222222222222 1111123333333333333444456666555556666778@@ @ @@87655443333333332222222222222222 1111122333333333333333334445555555556666789@@@ @86554433333333322222222222222222 1111112233333333333333333334444455555556679@ @@@ @@@@@@ 8544333333333222222222222222222 111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@877779@5443333333322222222222222222222 1111111222233333333333333333333344444444455566667778@@ @987666555544433333333222222222222222222222 1111111122223333333333333333333333344444444445556668@@@ @@@76555544444333333322222222222222222222222 1111111112222223333333333333333333333444444444455556789@@@@98755544444433333332222222222222222222222222 11111111111222222333333333333333333333334444444445555679@@@@7654444443333333222222222222222222222222222 1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 1111111111111222222222233333333333333333333333344444456655544443333332222222222222222222222222222222222 1111111111111112222222222222333333333333333333333333333333333333222222222222222222222222222222222222222 1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111
The entry for m4 also is based on Rosetta Code's "compiler" task suite.
Amazing Hopper
El siguiente programa genera el conjunto de Mandelbrot directamente en pantalla. Ha sido adaptado desde Wikipedia.
Se ejecutó con:
rxvt -g 500x250 -fn "xft:FantasqueSansMono-Regular:pixelsize=1" -e hopper3 jm/mandel.jambo
#!/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
- Output:
Arturo
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 ]
- Output:
** ****** ******** ****** ******** ** * *** ***************** ************************ *** **************************** ****************************** ******************************* ************************************ * ********************************** ** ***** * ********************************** *********** ************************************ ************** ************************************ *************************************************** ****************************************************** ************************************************************************ ****************************************************** *************************************************** ************** ************************************ *********** ************************************ ** ***** * ********************************** * ********************************** ************************************ ******************************* ****************************** **************************** ************************ *** *** ***************** ******** ** * ****** ******** ****** **
ATS
A non-interactive program that writes a PPM image
(* 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
- Output:
![The Mandelbrot set, displayed in colors.](http://static.miraheze.org/rosettacodewiki/thumb/9/9b/Mandelbrot_task_ATS.png/300px-Mandelbrot_task_ATS.png)
An interactive program that can write PAM images
(*-*- 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
(*------------------------------------------------------------------*)
- Output:
A snapshot image of part of the set:
![A portion of the Mandelbrot set, in shades of gray and black.](http://static.miraheze.org/rosettacodewiki/thumb/6/60/Mantelbrot_task_interactive_dats_sampleimage.png/300px-Mantelbrot_task_interactive_dats_sampleimage.png)
AutoHotkey
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
}
AWK
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;
}
- Output:
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<========== >>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======= >>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== >>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== >>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== >>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== >=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= ><<<<;;;;;:::972456-567763 +9;;<<<<<<< ><;;;;;;::::9875& .3 *9;;;<<<<<< >;;;;;;::997564' ' 8:;;;<<<<<< >::988897735/ &89:;;;<<<<<< >::988897735/ &89:;;;<<<<<< >;;;;;;::997564' ' 8:;;;<<<<<< ><;;;;;;::::9875& .3 *9;;;<<<<<< ><<<<;;;;;:::972456-567763 +9;;<<<<<<< >=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= >>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== >>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== >>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== >>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== >>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<=======
B
This implements a 16bit fixed point arithmetic Mandelbrot set calculation.
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);
}
- Output:
!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" !!!!!!!!!!!!!"""""""""#######################$$$$$$$%'+)%%%$$$$$#####""""""""""" !!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(+,)++&%$$$$$$######"""""" !!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*5:/+('&%%$$$$$$#######""" !!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@,'&%%%%%$$$$######## !!!!!!!"""####################$$$$$$$$%%%&'())((())*,@@@@@@/+))('&&&&)'%$$###### !!!!!!""###################$$$$$%%%%%%&&&'+.@@=/<@@@@@@@@@@@@@@@/++@..93%%$##### !!!!!"################$$$%%%%%%%%%%&&&&'),+2@@@@@@@@@@@@@@@@@@@@@@@@@1(&&%$$#### !!!!"##########$$$$$%%&(-(''''''''''''(*,5@@@@@@@@@@@@@@@@@@@@@@@@@@@@+)-&%$$### !!!!####$$$$$$$$%%%%%&'(*-@1.+.@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4-(&%$$$## !!!!#$$$$$$$$$%%%%%%'''++.6@@@@@@@@@8/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3(%%$$$$# !!!#$$$$$$$%&&&&''()/-5.5@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?'&%%$$$$# !!!(**+/+<523/80/46@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+)'&&%%$$$$# !!!#$$$$$$$%&&&&''().-2.@@@@@@@@@@@@@@?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$# !!!!#$$$$$$$$$%%%%%&'''/,.7@@@@@@@@@;/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@0'%%$$$$# !!!!####$$$$$$$$%%%%%&'(*-:2.,/?-5+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+(&%$$$## !!!!"##########$$$$$%%&(-(''''(''''''((*,4@@@@@@@@@@@@@@@@@@@@@@@@@@@4+).&%$$### !!!!!"################$$$%%%%%%%%%%&&&&')<,4@@@@@@@@@@@@@@@@@@@@@@@@@/('&%%$#### !!!!!!""##################$$$$$$%%%%%%&&&'*.@@@0@@@@@@@@@@@@@@@@1,,@//9)%%$##### !!!!!!!"""####################$$$$$$$$%%%&(())((()**-@@@@@@/+)))'&&&')'%$$###### !!!!!!!!""""#####################$$$$$$$$$$%%%&&&''(,@@@@@@@+'&&%%%%%$$$######## !!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*7@0+('&%%%$$$$$#######""" !!!!!!!!!!!"""""""######################$$$$$$$$$%%%&&(+-).*&%$$$$$$######"""""" !!!!!!!!!!!!!"""""""""#######################$$$$$$%%'3(%%%$$$$$######"""""""""" !!!!!!!!!!!!!!!""""""""""""#####################################""""""""""""""""
bc
Producing a PGM image.
To work properly, this needs to run with the environment variable BC_LINE_LENGTH set to 0.
max_iter = 50
width = 400; height = 401
scale = 10
xmin = -2; xmax = 1/2
ymin = -5/4; ymax = 5/4
define mandelbrot(c_re, c_im) {
auto i
# z = 0
z_re = 0; z_im = 0
z2_re = 0; z2_im = 0
for (i=0; i<max_iter; i++) {
# z *= z
z_im = 2*z_re*z_im
z_re = z2_re - z2_im
# z += c
z_re += c_re
z_im += c_im
# z2 = z.*z
z2_re = z_re*z_re
z2_im = z_im*z_im
if (z2_re + z2_im > 4) return i
}
return 0
}
print "P2\n", width, " ", height, "\n255\n"
for (i = 0; i < height; i++) {
y = ymin + (ymax - ymin) / height * i
for (j = 0; j < width; j++) {
x = xmin + (xmax - xmin) / width * j
tmp_scale = scale
scale = 0
m = (255 * mandelbrot(x, y) + max_iter + 1) / max_iter
print m
if ( j < width - 1 ) print " "
scale = tmp_scale
}
print "\n"
}
quit
BASIC
AmigaBASIC
![](http://static.miraheze.org/rosettacodewiki/thumb/a/a1/Amigabasic_mandelbrot.png/300px-Amigabasic_mandelbrot.png)
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
Applesoft BASIC
This version takes into account the Apple II's funky 280×192 6-color display, which has an effective resolution of only 140×192 in color.
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
By making the following modifications, the same code will render the Mandelbrot set in monochrome at full 280×192 resolution.
150 FOR XS = 0 TO 279
301 C = (C - INT(C/2)*2)*3
310 HCOLOR = C: HPLOT XS, YS
ARM BBC BASIC
The ARM development second processor for the BBC series of microcomputers came with ARM BBC Basic V. In version 1.0 this included a built-in MANDEL function that uses D% (depth) to update C% (colour) at given coordinates x and y. Presumably this was for benchmarking/demo purposes; it was removed from later versions. This can be run in BeebEm. Select BBC model as Master 128 with ARM Second Processor. Load disc armdisc3.adl and switch to ADFS. At the prompt load ARM Basic by running the AB command.
10MODE5:VDU5
20D%=100 : REM adjust for speed/precision
30FORX%=0 TO 1279 STEP8
40FORY%=0 TO 1023 STEP4
50MANDEL (Y%-512)/256, (X%-640)/256
51REM (not sure why X and Y need to be swapped to correct orientation)
60GCOL0,C%
70PLOT69,X%,Y%
80NEXT
90NEXT
BASIC256
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"
- Image generated by the script:
BBC BASIC
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%
Commander X16 BASIC
10 CLS
20 SCREEN $80
30 FOR X=1 TO 199:
40 FOR Y=1 TO 99:
50 LET I=0
60 LET CX=(X-100)/50
70 LET CY=(Y-100)/50
80 LET VX=0
90 LET VY=0
100 REM START OF THE CALCULATION LOOP
110 LET I=I+1
120 LET X2 = VX*VX
130 LET Y2 = VY*VY
140 LET VY = CY + (VX+VX)*VY
150 LET VX = CX + X2-Y2
160 IF I<32 AND (X2+Y2)<4 THEN GOTO 100
170 LET YR = 199-Y
180 PSET X,Y,I
190 PSET X,YR,I
200 :NEXT:NEXT
Commodore BASIC
The standard version 2.0 of BASIC that came with the VIC-20 and C-64 had no built-in support for graphics (though you could use POKE statements to put values in the VIC chip's registers and the RAM being used for video). However, Commodore sold add-on cartridges that provided such support, which was also included in later versions of BASIC (3.5 on the C-16 and Plus/4, 7.0 on the C-128). In all of these cases the programs are very slow; rendering the Mandelbrot set even with the escape threshold set to just 20 iterations takes hours. The fastest is the VIC-20, because it has only a 160x160-pixel bitmap display.
VIC-20 with Super Expander cartridge
Runs in about 90 minutes.
100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS
110 COLOR 1,3,0,0:GRAPHIC 2:TH=20
120 FOR PY=0 TO 80
130 : SY=INT(PY*6.4)
140 : IM=1.12-PY/160*2.24
150 : FOR PX=0 TO 160
160 : SX=INT(PX*6.4)
170 : RE=PX/160*2.47-2
180 : X=0:Y=0:IT=0
190 : XT=X*X-Y*Y+RE
200 : Y = 2*X*Y+IM
210 : X=XT
220 : IT=IT+1
230 : IF(X*X+Y*Y<=4)AND(IT<TH) THEN 190
240 : IF IT<TH THEN 270
250 : DRAW 1,SX,SY TO SX,SY
260 : DRAW 1,SX,1024-SY TO SX,1024-SY
270 : NEXT PX
280 NEXT PY
290 GET K$:IF K$="" THEN 290
300 GRAPHIC 4
C-64 with Super Expander 64
Runs in about 4.5 hours.
100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS
110 COLOR 6,0,0,0,6:GRAPHIC 2,1
120 FOR PY=0 TO 100
140 : IM=1.12-PY/200*2.24
150 : FOR PX=0 TO 319
170 : RE=PX/320*2.47-2
180 : X=0:Y=0:IT=0
190 : XT=X*X-Y*Y+RE
200 : Y = 2*X*Y+IM
210 : X=XT
220 : IT=IT+1
230 : IF(X*X+Y*Y<=4)AND(IT<TH) THEN 190
240 : IF IT<TH THEN 270
250 : DRAW 1,PX,PY
260 : DRAW 1,PX,200-PY
270 : NEXT PX
280 NEXT PY
290 GET K$:IF K$="" THEN 290
300 GRAPHIC 0
Commodore-16 / 116 / Plus/4
Despite the faster clock on the TED systems compared to the C-64, this takes almost six hours to run.
100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS
110 COLOR 0,2:COLOR 1,1:GRAPHIC 1,1
120 FOR PY=0 TO 100
130 : IM = 1.12-PY*2.24/200
140 : FOR PX=0 TO 319
150 : RE=PX/320*2.47-2
160 : X=0:Y=0:IT=0
170 : DO WHILE (X*X+Y*Y<=4) AND (IT<TH)
180 : XT = X*X-Y*Y+RE
190 : Y = 2*X*Y+IM
200 : X = XT
210 : IT = IT +1
220 : LOOP
230 : IF IT=TH THEN DRAW 1,PX,PY:DRAW 1,PX,199-PY
240 : NEXT PX
250 NEXT PY
260 GETKEY K$
270 GRAPHIC 0
Commodore 128 (40-column display)
With the switch to FAST (2MHz) mode, this runs in about 2.5 hours, but you get to stare at a blank screen until it's done rendering. Without that switch it takes about 5.5 hours, splitting the difference between the Super Expander 64 and Plus/4 versions.
100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS
110 COLOR 0,12:GRAPHIC 1,1:COLOR 1,1:GRAPHIC0:FAST
120 FOR PY=0 TO 100
130 : IM = 1.12-PY*2.24/200
140 : FOR PX=0 TO 319
150 : RE=PX/320*2.47-2
160 : X=0:Y=0:IT=0
170 : DO WHILE (X*X+Y*Y<=4) AND (IT<TH)
180 : XT = X*X-Y*Y+RE
190 : Y = 2*X*Y+IM
200 : X = XT
210 : IT = IT +1
220 : LOOP
230 : IF IT=TH THEN DRAW 1,PX,PY:DRAW 1,PX,199-PY
240 : NEXT PX
250 NEXT PY
260 SLOW:GRAPHIC 1
270 GETKEY K$
280 GRAPHIC 0
Commodore 128 (80-column display)
This uses BASIC 8 to create a 640x200 render on the C-128's 80-column display. The doubled resolution comes with a commensurate increase in run time; this takes about 5h20m using FAST 2MHz mode.
100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS
110 @MODE,0:@COLOR,15,0,0:@SCREEN,0,0:@CLEAR,0:FAST
120 FOR PY=0 TO 100
130 : IM = 1.12-PY*2.24/200
140 : FOR PX=0 TO 639
150 : RE=PX/640*2.47-2
160 : X=0:Y=0:IT=0
170 : DO WHILE (X*X+Y*Y<=4) AND (IT<20)
180 : XT = X*X-Y*Y+RE
190 : Y = 2*X*Y+IM
200 : X = XT
210 : IT = IT +1
220 : LOOP
230 : IF IT=20 THEN @DOT,PX,PY,0:@DOT,PX,199-PY,0
240 : NEXT PX
250 NEXT PY
260 GETKEY K$
270 @TEXT
- Output:
Screen shots of all of the above running in the VICE emulator can be found here.
Commodore PET
Here's a version using mostly ASCII and some PETSCII (could probably improve the tile set for PETSCII) inspired by the Perl solution. Designed for a PET with an 80-column display.
100 TH=20:REM ESCAPE THRESHOLD IN ITERATIONS
110 CH$=" .:-=+*#@"+CHR$(255)
120 FOR Y=1 TO -1 STEP -0.08
130 : FOR X = -2 TO 0.5 STEP 0.0315
140 : GOSUB 200:IF I=20 THEN PRINT CHR$(18);" ";CHR$(146);:GOTO 160
150 : PRINT MID$(CH$,I/2+1,1);
160 : NEXT X:IF PEEK(198) THEN PRINT
170 NEXT Y
180 GET K$:IF K$=""THEN 180
190 END
200 CX=X:CY=Y:ZX=X:ZY=Y
210 FOR I=1 TO TH
220 : TX=ZX*ZX-ZY*ZY
230 : TY=ZX*ZY*2
240 : ZX = TX + CX
250 : ZY = TY + CY
260 : IF ZX*ZX+ZY*ZY > 4 THEN 280
270 NEXT I
280 IF I>TH THEN I=TH
290 RETURN
- Output:
VICE screenshot here.
DEC BASIC-PLUS
Works under RSTS/E v7.0 on the simh PDP-11 emulator. For installation procedures for RSTS/E, see here.
10 X1=59\Y1=21
20 I1=-1.0\I2=1.0\R1=-2.0\R2=1.0
30 S1=(R2-R1)/X1\S2=(I2-I1)/Y1
40 FOR Y=0 TO Y1
50 I3=I1+S2*Y
60 FOR X=0 TO X1
70 R3=R1+S1*X\Z1=R3\Z2=I3
80 FOR N=0 TO 30
90 A=Z1*Z1\B=Z2*Z2
100 IF A+B>4.0 THEN GOTO 130
110 Z2=2*Z1*Z2+I3\Z1=A-B+R3
120 NEXT N
130 PRINT STRING$(1%,62%-N);
140 NEXT X
150 PRINT
160 NEXT Y
170 END
- Output:
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<=========== >>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== >>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= >>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== >>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== >>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== >=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== ><<<<;;;;;:::972456-567763 +9;;<<<<<<<= ><;;;;;;::::9875& .3 *9;;;<<<<<<= >;;;;;;::997564' ' 8:;;;<<<<<<= >::988897735/ &89:;;;<<<<<<= >::988897735/ &89:;;;<<<<<<= >;;;;;;::997564' ' 8:;;;<<<<<<= ><;;;;;;::::9875& .3 *9;;;<<<<<<= ><<<<;;;;;:::972456-567763 +9;;<<<<<<<= >=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== >>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== >>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== >>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== >>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= >>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== >>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<===========
FreeBASIC
#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
GW-BASIC
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
Liberty BASIC
Any words of description go outside of lang tags.
nomainwin
WindowWidth =440
WindowHeight =460
open "Mandelbrot Set" for graphics_nsb_nf as #w
#w "trapclose [quit]"
#w "down"
for x0 = -2 to 1 step .0033
for y0 = -1.5 to 1.5 step .0075
x = 0
y = 0
iteration = 0
maxIteration = 255
while ( ( x *x +y *y) <=4) 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
call pSet x0, y0, c
scan
next
next
#w "flush"
wait
sub pSet x, y, c
xScreen = 10 +( x +2) /3 *400
yScreen = 10 +( y +1.5) /3 *400
if c =0 then
col$ ="red"
else
if c mod 2 =1 then col$ ="lightgray" else col$ ="white"
end if
#w "color "; col$
#w "set "; xScreen; " "; yScreen
end sub
[quit]
close #w
end
Locomotive Basic
![](http://static.miraheze.org/rosettacodewiki/thumb/b/b7/Cpcbasic_mandelbrot.png/300px-Cpcbasic_mandelbrot.png)
This program is meant for use in CPCBasic specifically, where it draws a 16-color 640x400 image in less than a minute. (Real CPC hardware would take far longer than that and has lower resolution.)
1 MODE 3 ' Note the CPCBasic-only screen mode!
2 FOR xp = 0 TO 639
3 FOR yp = 0 TO 399
4 x = 0 : y = 0
5 x0 = xp / 213 - 2 : y0 = yp / 200 - 1
6 iteration = 0
7 maxIteration = 100
8 WHILE (x * x + y * y <= (2 * 2) AND iteration < maxIteration)
9 xtemp = x * x - y * y + x0
10 y = 2 * x * y + y0
11 x = xtemp
12 iteration = iteration + 1
13 WEND
14 IF iteration <> maxIteration THEN c = iteration ELSE c = 0
15 PLOT xp, yp, c MOD 16
16 NEXT
17 NEXT
Microsoft Small Basic
GraphicsWindow.Show()
size = 500
half = 250
GraphicsWindow.Width = size * 1.5
GraphicsWindow.Height = size
GraphicsWindow.Title = "Mandelbrot"
For px = 1 To size * 1.5
x_0 = px/half - 2
For py = 1 To size
y_0 = py/half - 1
x = x_0
y = y_0
i = 0
While(c <= 2 AND i<100)
x_1 = Math.Power(x, 2) - Math.Power(y, 2) + x_0
y_1 = 2 * x * y + y_0
c = Math.Power(Math.Power(x_1, 2) + Math.Power(y_1, 2), 0.5)
x = x_1
y = y_1
i = i + 1
EndWhile
If i < 99 Then
GraphicsWindow.SetPixel(px, py, GraphicsWindow.GetColorFromRGB((255/25)*i, (255/25)*i, (255/5)*i))
Else
GraphicsWindow.SetPixel(px, py, "black")
EndIf
c=0
EndFor
EndFor
Microsoft Super Extended Color BASIC (Tandy Color Computer 3)
1 REM MANDELBROT SET - TANDY COCO 3
2 POKE 65497,1
10 HSCREEN 2
20 HCLS
30 X1=319:Y1=191
40 I1=-1.0:I2=1.0:R1=-2:R2=1.0
50 S1=(R2-R1)/X1:S2=(I2-I1)/Y1
60 FOR Y=0 TO Y1
70 I3=I1+S2*Y
80 FOR X=0 TO X1
90 R3=R1+S1*X:Z1=R3:Z2=I3
100 FOR N=0 TO 30
110 A=Z1*Z1:B=Z2*Z2
120 IF A+B>4.0 GOTO 150
130 Z2=2*Z1*Z2+I3:Z1=A-B+R3
140 NEXT N
150 HSET(X,Y,N-16*INT(N/16))
160 NEXT X
170 NEXT Y
180 GOTO 180
MSX Basic
100 SCREEN 2
110 CLS
120 x1 = 256 : y1 = 192
130 i1 = -1 : i2 = 1
140 r1 = -2 : r2 = 1
150 s1 = (r2-r1)/x1 : s2 = (i2-i1)/y1
160 FOR y = 0 TO y1
170 i3 = i1+s2*y
180 FOR x = 0 TO x1
190 r3 = r1+s1*x
200 z1 = r3 : z2 = i3
210 FOR n = 0 TO 30
220 a = z1*z1 : b = z2*z2
230 IF a+b > 4 GOTO 270
240 z2 = 2*z1*z2+i3
250 z1 = a-b+r3
260 NEXT n
270 PSET (x,y),n-16*INT(n/16)
280 NEXT x
290 NEXT y
300 GOTO 300
- Output:
Nascom BASIC
In fact, it is based on the ZX81 version, but some optimizations are done to shorten the execution time (though they lengthen the code):
- The variables
X2
andY2
forXA*XA
andYA*YA
respectively are introduced in order to calculate the squares only once. - The value of
X
does not depend onJ
, so it is calculated before theFOR J
loop. - The symmetry of the shape is taken into account in order to calculate symmetric values only once. It is the most significant optimization. The case
X=0
(corresponding to the line 22 on the screen grid) is treated separately.
Only a fragment of the shape is drawn because of low resolution of block graphics. Like in the ZX81 version, you can adjust the constants in lines 40 and 70 to zoom in on a particular area, if you like.
10 REM Mandelbrot set
20 CLS
30 FOR I=0 TO 95
40 LET X=(I-78)/48
50 REM ** When X<>0
60 FOR J=1 TO 22
70 LET Y=(22-J)/30
80 LET XA=0:X2=0
90 LET YA=0:Y2=0
100 LET ITER=0
110 LET XTEMP=X2-Y2+X
120 LET YA=2*XA*YA+Y:Y2=YA*YA
130 LET XA=XTEMP:X2=XA*XA
140 LET ITER=ITER+1
150 IF X2+Y2<=4 AND ITER<200 THEN 110
160 IF ITER=200 THEN SET(I,J):SET(I,44-J)
170 NEXT J
180 REM ** When X=0
190 LET XA=0:X2=0
200 LET ITER=0
210 LET XA=X2+X:X2=XA*XA
220 LET ITER=ITER+1
230 IF X2<=4 AND ITER<200 THEN 210
240 IF ITER=200 THEN SET(I,22)
250 NEXT I
290 REM ** Set up machine code INKEY$ command
300 IF PEEK(1)<>0 THEN RESTORE 510
310 DOKE 4100,3328:FOR A=3328 TO 3342 STEP 2
320 READ B:DOKE A,B:NEXT A
400 SCREEN 1,15
410 PRINT "Hit any key to exit.";
420 A=USR(0):IF A<0 THEN 420
430 CLS
440 END
490 REM ** Data for machine code INKEY$
500 DATA 25055,1080,-53,536,-20665,3370,-5664,0
510 DATA 27085,14336,-13564,6399,18178,10927
520 DATA -8179,233
OS/8 BASIC
Works under BASIC on a PDP-8 running OS/8. Various emulators exist including simh's PDP-8 emulator and the PDP-8/E Simulator for Classic Macintosh and OS X.
10 X1=59\Y1=21
20 I1=-1.0\I2=1.0\R1=-2.0\R2=1.0
30 S1=(R2-R1)/X1\S2=(I2-I1)/Y1
40 FOR Y=0 TO Y1
50 I3=I1+S2*Y
60 FOR X=0 TO X1
70 R3=R1+S1*X\Z1=R3\Z2=I3
80 FOR N=0 TO 30
90 A=Z1*Z1\B=Z2*Z2
100 IF A+B>4.0 GOTO 130
110 Z2=2*Z1*Z2+I3\Z1=A-B+R3
120 NEXT N
130 PRINT CHR$(62-N);
140 NEXT X
150 PRINT
160 NEXT Y
170 END
- Output:
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<=========== >>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== >>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= >>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== >>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== >>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== >=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== ><<<<;;;;;:::972456-567763 +9;;<<<<<<<= ><;;;;;;::::9875& .3 *9;;;<<<<<<= >;;;;;;::997564' ' 8:;;;<<<<<<= >::988897735/ &89:;;;<<<<<<= >::988897735/ &89:;;;<<<<<<= >;;;;;;::997564' ' 8:;;;<<<<<<= ><;;;;;;::::9875& .3 *9;;;<<<<<<= ><<<<;;;;;:::972456-567763 +9;;<<<<<<<= >=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== >>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== >>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== >>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== >>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= >>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== >>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<===========
PureBasic
PureBasic forum: discussion
EnableExplicit
#Window1 = 0
#Image1 = 0
#ImgGadget = 0
#max_iteration = 64
#width = 800
#height = 600
Define.d x0 ,y0 ,xtemp ,cr, ci
Define.i i, n, x, y ,Event ,color
Dim Color.l (255)
For n = 0 To 63
Color( 0 + n ) = RGB( n*4+128, 4 * n, 0 )
Color( 64 + n ) = RGB( 64, 255, 4 * n )
Color( 128 + n ) = RGB( 64, 255 - 4 * n , 255 )
Color( 192 + n ) = RGB( 64, 0, 255 - 4 * n )
Next
If OpenWindow(#Window1, 0, 0, #width, #height, "'Mandelbrot set' PureBasic Example", #PB_Window_SystemMenu )
If CreateImage(#Image1, #width, #height)
ImageGadget(#ImgGadget, 0, 0, #width, #height, ImageID(#Image1))
For y.i = 1 To #height -1
StartDrawing(ImageOutput(#Image1))
For x.i = 1 To #width -1
x0 = 0
y0 = 0;
cr = (x / #width)*2.5 -2
ci = (y / #height)*2.5 -1.25
i = 0
While (x0*x0 + y0*y0 <= 4.0) And i < #max_iteration
i +1
xtemp = x0*x0 - y0*y0 + cr
y0 = 2*x0*y0 + ci
x0 = xtemp
Wend
If i >= #max_iteration
Plot(x, y, 0 )
Else
Plot(x, y, Color(i & 255))
EndIf
Next
StopDrawing()
SetGadgetState(#ImgGadget, ImageID(#Image1))
Repeat
Event = WindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until Event = 0
Next
EndIf
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Example:
QBasic
This is almost exactly the same as the pseudocode from the Wikipedia entry's "For programmers" section (which it's closely based on, of course). The image generated is very blocky ("low-res") due to the selected video mode, but it's fairly accurate.
SCREEN 13
WINDOW (-2, 1.5)-(2, -1.5)
FOR x0 = -2 TO 2 STEP .01
FOR y0 = -1.5 TO 1.5 STEP .01
x = 0
y = 0
iteration = 0
maxIteration = 223
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
PSET (x0, y0), c + 32
NEXT
NEXT
Quite BASIC
1000 REM Mandelbrot Set Project
1010 REM Quite BASIC Math Project
1015 REM 'http://www.quitebasic.com/prj/math/mandelbrot/
1020 REM ------------------------
1030 CLS
1040 PRINT "This program plots a graphical representation of the famous Mandelbrot set. It takes a while to finish so have patience and don't have too high expectations; the graphics resolution is not very high on our canvas."
2000 REM Initialize the color palette
2010 GOSUB 3000
2020 REM L is the maximum iterations to try
2030 LET L = 100
2040 FOR I = 0 TO 100
2050 FOR J = 0 TO 100
2060 REM Map from pixel coordinates (I,J) to math (U,V)
2060 LET U = I / 50 - 1.5
2070 LET V = J / 50 - 1
2080 LET X = U
2090 LET Y = V
2100 LET N = 0
2110 REM Inner iteration loop starts here
2120 LET R = X * X
2130 LET Q = Y * Y
2140 IF R + Q > 4 OR N >= L THEN GOTO 2190
2150 LET Y = 2 * X * Y + V
2160 LET X = R - Q + U
2170 LET N = N + 1
2180 GOTO 2120
2190 REM Compute the color to plot
2200 IF N < 10 THEN LET C = "black" ELSE LET C = P[ROUND(8 * (N-10) / (L-10))]
2210 PLOT I, J, C
2220 NEXT J
2230 NEXT I
2240 END
3000 REM Subroutine -- Set up Palette
3010 ARRAY P
3020 LET P[0] = "black"
3030 LET P[1] = "magenta"
3040 LET P[2] = "blue"
3050 LET P[3] = "green"
3060 LET P[4] = "cyan"
3070 LET P[5] = "red"
3080 LET P[6] = "orange"
3090 LET P[7] = "yellow"
3090 LET P[8] = "white"
3100 RETURN
Run BASIC
'Mandelbrot V4 for RunBasic
'Based on LibertyBasic solution
'copy the code and go to runbasic.com
'http://rosettacode.org/wiki/Mandelbrot_set#Liberty_BASIC
'May 2015 (updated 29 Apr 2018)
'
'Note - we only get so much processing time on the server, so the
'graph is computed in three or four pieces
'
WindowWidth = 320 'RunBasic max size 800 x 600
WindowHeight = 320
'print zone -2 to 1 (X)
'print zone -1.5 to 1.5 (Y)
a = -1.5 'graph -1.5 to -0.75, first "loop"
b = -0.75 'adjust for max processor time (y0 for loop below)
'open "Mandelbrot Set" for graphics_nsb_nf as #w not used in RunBasic
graphic #w, WindowWidth, WindowHeight
'#w "trapclose [quit]" not used in RunBasic
'#w "down" not used in RunBasic
cls
'#w flush()
#w cls("black")
render #w
'#w flush()
input "OK, hit enter to continue"; guess
cls
[man_calc]
'3/screen size 3/800 = 0.00375 ** 3/790 = 0.0037974
'3/screen size (y) 3/600 = .005 ** 3/590 = 0.0050847
'3/215 = .0139 .0068 = 3/440
cc = 3/299
'
for x0 = -2 to 1 step cc
for y0 = a to b step cc
x = 0
y = 0
iteration = 0
maxIteration = 255
while ( ( x *x +y *y) <=4) 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
call pSet x0, y0, c
'scan why scan? (wait for user input) with RunBasic ?
next
next
'#w flush() 'what is flush? RunBasic uses the render command.
render #w
input "OK, hit enter to continue"; guess
cls
a = a + 0.75
b = b + 0.75
if b > 1.6 then goto[quit] else goto[man_calc]
sub pSet x, y, c
xScreen = 5+(x +2) /3 * 300 'need positive screen number
yScreen = 5+(y +1.5) /3 * 300 'and 5x5 boarder
if c =0 then
col$ ="red"
else
if c mod 2 =1 then col$ ="lightgray" else col$ ="white"
end if
#w "color "; col$
#w "set "; xScreen; " "; yScreen
end sub
[quit]
'cls
print
print "This is a Mandelbrot Graph output from www.runbasic.com"
render #w
print "All done, good bye."
end
Sinclair ZX81 BASIC
Requires at least 2k of RAM.
Glacially slow, but does eventually produce a tolerable low-resolution image (screenshot here). You can adjust the constants in lines 30 and 40 to zoom in on a particular area, if you like.
10 FOR I=0 TO 63
20 FOR J=43 TO 0 STEP -1
30 LET X=(I-52)/31
40 LET Y=(J-22)/31
50 LET XA=0
60 LET YA=0
70 LET ITER=0
80 LET XTEMP=XA*XA-YA*YA+X
90 LET YA=2*XA*YA+Y
100 LET XA=XTEMP
110 LET ITER=ITER+1
120 IF XA*XA+YA*YA<=4 AND ITER<200 THEN GOTO 80
130 IF ITER=200 THEN PLOT I, J
140 NEXT J
150 NEXT I
SmileBASIC
Generates the points at random, gradually building up the image.
X = RNDF()*4-2
Y = RNDF()*4-2@N
N = N+16
I = X+S*S-T*T
T = Y+S*T*2
S = I
IF N < #L&&S*S+T*T < 4 GOTO @N
GPSET X*50+99, Y*50+99, RGB(99 XOR N,N,N)
EXEC.
Alternative, based on the QBasic and other BASIC samples.
The 3DS screen is 400 x 240 pixels. SmileBASIC doesn't have +=, -=, etc. but there are INC and DEC statements.
OPTION STRICT
VAR XP, YP, X, Y, X0, Y0, X2, Y2
VAR NEXT_X, IT, C
FOR XP = -200 TO 199
FOR YP = -120 TO 119
X = 0: Y = 0
X0 = XP / 100: Y0 = YP / 100
IT = 0
X2 = X * X: Y2 = Y * Y
WHILE X2 + Y2 <= 4 AND IT < 100
NEXT_X = X2 - Y2 + X0
Y = 2 * X * Y + Y0
X = NEXT_X
X2 = X * X: Y2 = Y * Y
INC IT
WEND
IF IT == 100 THEN C = 0 ELSE C = IT
GPSET XP + 200, YP + 120, RGB((C * 3) MOD 200 + 50, FLOOR(C * 1.2) + 20, C)
NEXT
NEXT
TI-Basic Color
ClrDraw
~2->Xmin:1->Xmax:~1->Ymin:1->Ymax
AxesOff
FnOff
For(A,~2,1,.034
For(B,~1,1,.036
A+B[i]->C
DelVar Z9->N
While abs(Z)<=2 and N<24
Z^^2+C->Z
N+1->N
End
Pt-On(real(C),imag(C),N
End
End
True BASIC
SET WINDOW 0, 256, 0, 192
LET x1 = 256/2
LET y1 = 192/2
LET i1 = -1
LET i2 = 1
LET r1 = -2
LET r2 = 1
LET s1 = (r2-r1) / x1
LET s2 = (i2-i1) / y1
FOR y = 0 TO y1 STEP .05
LET i3 = i1 + s2 * y
FOR x = 0 TO x1 STEP .05
LET r3 = r1 + s1 * x
LET z1 = r3
LET z2 = i3
FOR n = 0 TO 30
LET a = z1 * z1
LET b = z2 * z2
IF a+b > 4 THEN EXIT FOR
LET z2 = 2 * z1 * z2 + i3
LET z1 = a - b + r3
NEXT n
SET COLOR n - 16*INT(n/16)
PLOT POINTS: x,y
NEXT x
NEXT y
END
Visual BASIC for Applications on Excel
Based on the BBC BASIC version. Create a spreadsheet with -2 to 2 in row 1 and -2 to 2 in the A column (in steps of your choosing). In the cell B2, call the function with =mandel(B$1,$A2) and copy the cell to all others in the range. Conditionally format the cells to make the colours pleasing (eg based on values, 3-color scale, min value 2 [colour red], midpoint number 10 [green] and highest value black. Then format the cells with the custom type "";"";"" to remove the numbers.
Function mandel(xi As Double, yi As Double)
maxiter = 256
x = 0
y = 0
For i = 1 To maxiter
If ((x * x) + (y * y)) > 4 Then Exit For
xt = xi + ((x * x) - (y * y))
y = yi + (2 * x * y)
x = xt
Next
mandel = i
End Function
File:Vbamandel.png Edit: I don't seem to be able to upload the screenshot, so I've shared it here: https://goo.gl/photos/LkezpuQziJPAtdnd9
Yabasic
open window 640, 320
wid = 4
xcenter = -1: ycenter = 0
ms = 0
for xcoord = 0 to 639
for ycoord = 0 to 160
ms = 0
ca =(xcoord-320)/640*wid+xcenter
cb =(ycoord-160)/640*wid+ycenter
x = 0: y=0
for t = 1 to 20
xnew = x*x-y*y+ca
ynew = 2*x*y+cb
x=xnew:y=ynew
magnitudesquared=x*x+y*y
ms = magnitudesquared
if (magnitudesquared > 100) break
//if(magnitudesquared < 100) then : color 0,0,0 : dot xcoord, ycoord : end if
next t
ms = ms+1
if(ms > 250) then
color 32,64,mod(ms,255)
dot xcoord, ycoord
dot xcoord, 320- ycoord
elseif (ms > 150) then
color mod(ms,255),64,32
dot xcoord, ycoord
dot xcoord, 320-ycoord
else
color 0,0,0
dot xcoord, ycoord
dot xcoord, 320-ycoord
end if
next ycoord
next xcoord
Befunge
Using 14-bit fixed point arithmetic for simplicity and portability. It should work in most interpreters, but the exact output is implementation dependent, and some will be unbearably slow.
X scale is (-2.0, 0.5); Y scale is (-1, 1); Max iterations 94 with the ASCII character set as the "palette".
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<^
- Output:
}}}}}}}}}|||||||{{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzyyyyxwusjuthwyzzzzzzz{{{{{{{ }}}}}}}}|||||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzyyyyxwwvtqptvwxyyzzzzzzz{{{{{ }}}}}}}||||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyyxwvuqaZlnvwxyyyzzzzzzz{{{{ }}}}}}|||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyyxxvqXp^g Ynslvxyyyyyzzzzz{{{ }}}}}}||||{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyxxxxwvtp 6puwxyyyyyyzzzz{{ }}}}}||||{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzyyyxxxxxwwvvqc &8uvwxxxyyyyyzzz{ }}}}|||{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzyyyywwvtvvvvuutsp Hrtuuvwxxxxwqxyzz }}}}||{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzyyyyyxwvqemrttj m id+ PRUiPp_rvvvvudwxyz }}}||{{{{{{{{{{{{{{{{{{{{{zzzzzzyyyyyyyxxxwurf ZnW 4nrslnobgwyy }}}||{{{{{{{{{{{{{{{{{{{zzzzyyyyyyyyyyxxxwvusg N Uquxyy }}||{{{{{{{{{{{{{{{{{zzzzyyyyyyyyyyyxxxxwvrrrkC grwxxy }}|{{{{{{{{{{{{{{{zzzzyxxxxxyyyyyxxxxxwwukM!f ptvwxy }}|{{{{{{{{{{zzzzzzyyxwsuwwwwwwwwwwwwwvvurn[ ptuox }|{{{{{{{zzzzzzzzyyyxxvptuuvvumsuvvvvvvu` hjx }|{{{{zzzzzzzzzyyyyyxxwusogoqsqg]pptuuttlc ntwx }{{{zzzzzzzzzyyyyyyxxwwuto - O jpssrO nsvx }{{zzzzzzzzzyyyyyyxwwwvrrT4 TonR Ufwy }{zzzzzzzzyyyyyxxwttuutqe Dj $uxy }zzzzzzzzyxxxxxwwvuppnpn ` twxy }yyyxxwvwwwxwvvvrtppc Y auwxxy dqtvwxyy }yyyxxwvwwwxwvvvrtppc Y auwxxy }zzzzzzzzyxxxxxwwvuppnpn ` twxy }{zzzzzzzzyyyyyxxwttuutqe Dj $uxy }{{zzzzzzzzzyyyyyyxwwwvrrT4 TonR Ufwy }{{{zzzzzzzzzyyyyyyxxwwuto - O jpssrO nsvx }|{{{{zzzzzzzzzyyyyyxxwusogoqsqg]pptuuttlc ntwx }|{{{{{{{zzzzzzzzyyyxxvptuuvvumsuvvvvvvu` hjx }}|{{{{{{{{{{zzzzzzyyxwsuwwwwwwwwwwwwwvvurn[ ptuox }}|{{{{{{{{{{{{{{{zzzzyxxxxxyyyyyxxxxxwwukM!f ptvwxy }}||{{{{{{{{{{{{{{{{{zzzzyyyyyyyyyyyxxxxwvrrrkC grwxxy }}}||{{{{{{{{{{{{{{{{{{{zzzzyyyyyyyyyyxxxwvusg N Uquxyy }}}||{{{{{{{{{{{{{{{{{{{{{zzzzzzyyyyyyyxxxwurf ZnW 4nrslnobgwyy }}}}||{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzyyyyyxwvqemrttj m id+ PRUiPp_rvvvvudwxyz }}}}|||{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzyyyywwvtvvvvuutsp Hrtuuvwxxxxwqxyzz }}}}}||||{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzyyyxxxxxwwvvqc &8uvwxxxyyyyyzzz{ }}}}}}||||{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyxxxxwvtp 6puwxyyyyyyzzzz{{ }}}}}}|||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyyxxvqXp^g Ynslvxyyyyyzzzzz{{{ }}}}}}}||||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzyyyyxwvuqaZlnvwxyyyzzzzzzz{{{{ }}}}}}}}|||||||{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzyyyyxwwvtqptvwxyyzzzzzzz{{{{{ }}}}}}}}}|||||||{{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzyyyyxwusjuthwyzzzzzzz{{{{{{{
Brace
This is a simple Mandelbrot plotter. A longer version based on this smooths colors, and avoids calculating the time-consuming black pixels: http://sam.ai.ki/brace/examples/mandelbrot.d/1
#!/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
An example plot from the longer version:
Brainf***
A mandelbrot set fractal viewer in brainf*ck written by Erik Bosman
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[
>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+
<<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>>
>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+[>>>>>>[>>>>>>>[-]>>]<<<<<<<<<[<<<<<<<<<]>>
>>>>>[-]+<<<<<<++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<+++++++[-[->>>
>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[[-]>>>>>>[>>>>>
>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>
[>>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<
<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>+++++++++++++++[[
>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[
>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[
-<<+>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<
<<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<
[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>
>>>>[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+
<<<<<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>
>>>>>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<
+>>>>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<
<]<+<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<
<<<]>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->
>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<
<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++++++++++++++++
+++++++>>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>[<<<<<<<+<[-<+>>>>+<<[-]]>[-<<[->+>>>-
<<<<]>>>]>>>>>>>>>>>>>[>>[-]>[-]>[-]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>>>>>>[>>>>>
[-<<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>[-<<<<<<<<
<+>>>>>>>>>]>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>>]+>[-
]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>>>>>>>]<<<
<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+>>]<
<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[->>>>
>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-]<->>>
[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<
<<<<+>>>>>]<<<<<[->>>>>+<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+>>>>>>>>
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++
+++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-<<<<<<<+
>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[
-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>>]>[-<<<<<<[->>>>>+<++<<<<]>>>>>[-<
<<<<+>>>>>]<->+>]<[->+<]<<<<<[->>>>>+<<<<<]>>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<
[->>>>->>>>>[>>[-<<->>]+<<[->>->[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]
+>>>>>>[>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<<<<<<<<<<[<<<<<
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<
[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<
<<<+<[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<
<<<<<+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<
<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+<]>>>>>>>>]<<<
<<<<<+<[>[->>>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>[->>>>+<<<<]>]<[->>>>-<<<<<<<
<<<<<<<+>>>>>>>>>>]<]>>[->>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>>+<<<<
]<<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>>>>>>>>>]<<<<<<<<<
[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<<<<<<
+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<<<<<<
<<<<<]]>[-]>>[-]>[-]>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<
<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[
[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>
[-<<+>>]<<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<
<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[
>[-]<->>>[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[
>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>
>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>[-]>>>>+++++++++++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<
<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<
<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-
<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>
>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>>>
[-<<<->>>]<<<[->>>+<<<]>>>>>>>>]<<<<<<<<+<[>[->+>[-<-<<<<<<<<<<+>>>>>>>>>>>>[-<<
+>>]<]>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<<<]>>[-<+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<]>
[-<<+>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>
>>>>>>]<<<<<<<<+<[>[->+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>[-<+>]>]<[-<-<<<<<<<<<<+>>>>
>>>>>>>]<<]>>>[-<<+>[-<-<<<<<<<<<<+>>>>>>>>>>>]>]<[-<+>]<<<<<<<<<<<<]>>>>>+<<<<<
]>>>>>>>>>[>>>[-]>[-]>[-]>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>>>[-<<<<<
<+>>>>>>]<<<<<<[->>>>>>+<<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>
>]>>[-<<<<<<<[->>>>>+<++<<<<]>>>>>[-<<<<<+>>>>>]<->+>>]<<[->>+<<]<<<<<[->>>>>+<<
<<<]+>>>>[-<<<<->>>>]+<<<<[->>>>->>>>>[>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<
<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>[-<<->>]+<<[->>->[-<<<+>>>]<
<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<
<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+
<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>[->>>+<<<]>]<[->>>-
<<<<<<<<<<<<<+>>>>>>>>>>]<]>>[->>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>+<<<
]<<<<<<<<<<<]>>>>>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]]>>>>[-<<<<+>
>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<<[->>>-
<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[
->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>
>>]<<<<[->>>>+>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>[>>>>>>
>>>]<<<<<<<<<[>[->>>>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<
<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<
<<<<]]>>>>>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>[-<<<<+
>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<+>>>>>
]<<<<<[->>>>>+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>
>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[-<<+
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<
<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>
>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<+>>>
>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+
<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<<<<]
>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<
]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->>>+<
<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>
>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>->>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>]<<+>>>>[-<<<<
->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[-<<<<<<<.>>>>>>>]<<<[-]>[-]>[-]>[-]>[-]>[-]>>>[
>[-]>[-]>[-]>[-]>[-]>[-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]>>>>]<<<<<<<<<
[<<<<<<<<<]>+++++++++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+>>>>>>>>>+<<<<<<<<
<<<<<<[<<<<<<<<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+[-]>>[>>>>>>>>>]<<<<<
<<<<[>>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<[<<<<<<<<<]>>>>>>>[-]+>>>]<<<<
<<<<<<]]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+>>[>+>>>>[-<<<<->>>>]<<<<[->>>
>+<<<<]>>>>>>>>]<<+<<<<<<<[>>>>>[->>+<<]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<
<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<<<<<[->>>>>>+<<<<<<]<
+<<<<<<<<<]>>>>>>>-<<<<[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>->>[>>
>>>[->>+<<]>>>>]<<<<<<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<
<<<<[->>>>>>+<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+<<<
<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>->>[-<<<<<<<+>>>>>>>]<<<<
<<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>[-<
<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<
<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<
<<[<<<<<<<<<]>>>>[-]<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>-<<<<<[<<<<<<<
<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++[-[->>>>>>>>
>+<<<<<<<<<]>>>>>>>>>]>>>>>+>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<
<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+[-]>[>>>>>>>>>]<<<<<<<<<[>>>>>>>>[-<<<<<<<+>>>>>>
>]<<<<<<<[->>>>>>>+<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<
<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+>[>+>>>>>[-<<<<<->>>>>]<<<<<[->>>>>+<<<<<]>>>>>>
>>]<+<<<<<<<<[>>>>>>[->>+<<]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<-
>>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<
<<<]>>>>>>>>-<<<<<[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>->[>>>
>>>[->>+<<]>>>]<<<<<<<<<[>[-]<->>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<
<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>
+>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<->>>>>>]+<
<<<<<[->>>>>>->>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<
<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>
-<<[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>
>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<++++
+[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>->>>>>>>>>>>>>>>>>>>>>>>>>>>-<<<<<<[<<<<
<<<<<]]>>>]
- Output:
AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDEGFFEEEEDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB AAAAAAAAAAAAAAABBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDEEEFGIIGFFEEEDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBB AAAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDEEEEFFFI KHGGGHGEDDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBB AAAAAAAAAAAABBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEEFFGHIMTKLZOGFEEDDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBB AAAAAAAAAAABBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEEEFGGHHIKPPKIHGFFEEEDDDDDDDDDCCCCCCCCCCBBBBBBBBBBBBBBBBBB AAAAAAAAAABBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEEFFGHIJKS X KHHGFEEEEEDDDDDDDDDCCCCCCCCCCBBBBBBBBBBBBBBBB AAAAAAAAABBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEEFFGQPUVOTY ZQL[MHFEEEEEEEDDDDDDDCCCCCCCCCCCBBBBBBBBBBBBBB AAAAAAAABBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEFFFFFGGHJLZ UKHGFFEEEEEEEEDDDDDCCCCCCCCCCCCBBBBBBBBBBBB AAAAAAABBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEFFFFFFGGGGHIKP KHHGGFFFFEEEEEEDDDDDCCCCCCCCCCCBBBBBBBBBBB AAAAAAABBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDEEEEEFGGHIIHHHHHIIIJKMR VMKJIHHHGFFFFFFGSGEDDDDCCCCCCCCCCCCBBBBBBBBB AAAAAABBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDEEEEEEFFGHK MKJIJO N R X YUSR PLV LHHHGGHIOJGFEDDDCCCCCCCCCCCCBBBBBBBB AAAAABBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDEEEEEEEEEFFFFGH O TN S NKJKR LLQMNHEEDDDCCCCCCCCCCCCBBBBBBB AAAAABBCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDEEEEEEEEEEEEFFFFFGHHIN Q UMWGEEEDDDCCCCCCCCCCCCBBBBBB AAAABBCCCCCCCCCCCCCCCCCCCCCCCCCDDDDEEEEEEEEEEEEEEEFFFFFFGHIJKLOT [JGFFEEEDDCCCCCCCCCCCCCBBBBB AAAABCCCCCCCCCCCCCCCCCCCCCCDDDDEEEEEEEEEEEEEEEEFFFFFFGGHYV RQU QMJHGGFEEEDDDCCCCCCCCCCCCCBBBB AAABCCCCCCCCCCCCCCCCCDDDDDDDEEFJIHFFFFFFFFFFFFFFGGGGGGHIJN JHHGFEEDDDDCCCCCCCCCCCCCBBB AAABCCCCCCCCCCCDDDDDDDDDDEEEEFFHLKHHGGGGHHMJHGGGGGGHHHIKRR UQ L HFEDDDDCCCCCCCCCCCCCCBB AABCCCCCCCCDDDDDDDDDDDEEEEEEFFFHKQMRKNJIJLVS JJKIIIIIIJLR YNHFEDDDDDCCCCCCCCCCCCCBB AABCCCCCDDDDDDDDDDDDEEEEEEEFFGGHIJKOU O O PR LLJJJKL OIHFFEDDDDDCCCCCCCCCCCCCCB AACCCDDDDDDDDDDDDDEEEEEEEEEFGGGHIJMR RMLMN NTFEEDDDDDDCCCCCCCCCCCCCB AACCDDDDDDDDDDDDEEEEEEEEEFGGGHHKONSZ QPR NJGFEEDDDDDDCCCCCCCCCCCCCC ABCDDDDDDDDDDDEEEEEFFFFFGIPJIIJKMQ VX HFFEEDDDDDDCCCCCCCCCCCCCC ACDDDDDDDDDDEFFFFFFFGGGGHIKZOOPPS HGFEEEDDDDDDCCCCCCCCCCCCCC ADEEEEFFFGHIGGGGGGHHHHIJJLNY TJHGFFEEEDDDDDDDCCCCCCCCCCCCC A PLJHGGFFEEEDDDDDDDCCCCCCCCCCCCC ADEEEEFFFGHIGGGGGGHHHHIJJLNY TJHGFFEEEDDDDDDDCCCCCCCCCCCCC ACDDDDDDDDDDEFFFFFFFGGGGHIKZOOPPS HGFEEEDDDDDDCCCCCCCCCCCCCC ABCDDDDDDDDDDDEEEEEFFFFFGIPJIIJKMQ VX HFFEEDDDDDDCCCCCCCCCCCCCC AACCDDDDDDDDDDDDEEEEEEEEEFGGGHHKONSZ QPR NJGFEEDDDDDDCCCCCCCCCCCCCC AACCCDDDDDDDDDDDDDEEEEEEEEEFGGGHIJMR RMLMN NTFEEDDDDDDCCCCCCCCCCCCCB AABCCCCCDDDDDDDDDDDDEEEEEEEFFGGHIJKOU O O PR LLJJJKL OIHFFEDDDDDCCCCCCCCCCCCCCB AABCCCCCCCCDDDDDDDDDDDEEEEEEFFFHKQMRKNJIJLVS JJKIIIIIIJLR YNHFEDDDDDCCCCCCCCCCCCCBB AAABCCCCCCCCCCCDDDDDDDDDDEEEEFFHLKHHGGGGHHMJHGGGGGGHHHIKRR UQ L HFEDDDDCCCCCCCCCCCCCCBB AAABCCCCCCCCCCCCCCCCCDDDDDDDEEFJIHFFFFFFFFFFFFFFGGGGGGHIJN JHHGFEEDDDDCCCCCCCCCCCCCBBB AAAABCCCCCCCCCCCCCCCCCCCCCCDDDDEEEEEEEEEEEEEEEEFFFFFFGGHYV RQU QMJHGGFEEEDDDCCCCCCCCCCCCCBBBB AAAABBCCCCCCCCCCCCCCCCCCCCCCCCCDDDDEEEEEEEEEEEEEEEFFFFFFGHIJKLOT [JGFFEEEDDCCCCCCCCCCCCCBBBBB AAAAABBCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDEEEEEEEEEEEEFFFFFGHHIN Q UMWGEEEDDDCCCCCCCCCCCCBBBBBB AAAAABBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDEEEEEEEEEFFFFGH O TN S NKJKR LLQMNHEEDDDCCCCCCCCCCCCBBBBBBB AAAAAABBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDEEEEEEFFGHK MKJIJO N R X YUSR PLV LHHHGGHIOJGFEDDDCCCCCCCCCCCCBBBBBBBB AAAAAAABBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDEEEEEFGGHIIHHHHHIIIJKMR VMKJIHHHGFFFFFFGSGEDDDDCCCCCCCCCCCCBBBBBBBBB AAAAAAABBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEFFFFFFGGGGHIKP KHHGGFFFFEEEEEEDDDDDCCCCCCCCCCCBBBBBBBBBBB AAAAAAAABBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEFFFFFGGHJLZ UKHGFFEEEEEEEEDDDDDCCCCCCCCCCCCBBBBBBBBBBBB AAAAAAAAABBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEEFFGQPUVOTY ZQL[MHFEEEEEEEDDDDDDDCCCCCCCCCCCBBBBBBBBBBBBBB AAAAAAAAAABBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDEEEEEEFFGHIJKS X KHHGFEEEEEDDDDDDDDDCCCCCCCCCCBBBBBBBBBBBBBBBB AAAAAAAAAAABBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEEEFGGHHIKPPKIHGFFEEEDDDDDDDDDCCCCCCCCCCBBBBBBBBBBBBBBBBBB AAAAAAAAAAAABBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDEEEEEFFGHIMTKLZOGFEEDDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBB AAAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDEEEEFFFI KHGGGHGEDDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBB AAAAAAAAAAAAAAABBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDEEEFGIIGFFEEEDDDDDDDDCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBB
C
PPM non interactive
Here is one file program. It directly creates ppm file.
/*
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;
}
PPM Interactive
![](http://static.miraheze.org/rosettacodewiki/thumb/e/ef/Mandel-C-GL.png/400px-Mandel-C-GL.png)
Infinitely zoomable OpenGL program. Adjustable colors, max iteration, black and white, screen dump, etc. Compile with gcc mandelbrot.c -lglut -lGLU -lGL -lm
- OpenBSD users, install freeglut package, and compile with
make mandelbrot CPPFLAGS='-I/usr/local/include `pkg-config glu --cflags`' LDLIBS='-L/usr/local/lib -lglut `pkg-config glu --libs` -lm'
The following version should work on architectures (such as x86/x86-64) that allow unaligned pointers.
#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;
}
Here is a variant that hopefully will work on a broader range of architectures, although it has been tested only on x86-64.
#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:
(PLEASE FIXME: Does resizing work correctly, in either version?)
ASCII
Not mine, found it on Ken Perlin's homepage, this deserves a place here to illustrate how awesome C can be:
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);}
There may be warnings on compiling but disregard them, the output will be produced nevertheless. Such programs are called obfuscated and C excels when it comes to writing such cryptic programs. Google IOCCC for more.
.............::::::::::::::::::::::::::::::::::::::::::::::::....................... .........::::::::::::::::::::::::::::::::::::::::::::::::::::::::................... .....::::::::::::::::::::::::::::::::::-----------:::::::::::::::::::............... ...:::::::::::::::::::::::::::::------------------------:::::::::::::::............. :::::::::::::::::::::::::::-------------;;;!:H!!;;;--------:::::::::::::::.......... ::::::::::::::::::::::::-------------;;;;!!/>&*|I !;;;--------::::::::::::::........ ::::::::::::::::::::-------------;;;;;;!!/>)|.*#|>/!!;;;;-------::::::::::::::...... ::::::::::::::::-------------;;;;;;!!!!//>|: !:|//!!!;;;;-----::::::::::::::..... ::::::::::::------------;;;;;;;!!/>)I>>)||I# H&))>////*!;;-----:::::::::::::.... ::::::::----------;;;;;;;;;;!!!//)H: #| IH&*I#/;;-----:::::::::::::... :::::---------;;;;!!!!!!!!!!!//>|.H: #I>/!;;-----:::::::::::::.. :----------;;;;!/||>//>>>>//>>)|% %|&/!;;----::::::::::::::. --------;;;;;!!//)& .;I*-H#&||&/ *)/!;;-----:::::::::::::: -----;;;;;!!!//>)IH:- ## #&!!;;-----:::::::::::::: ;;;;!!!!!///>)H%.** * )/!;;;------::::::::::::: &)/!!;;;------::::::::::::: ;;;;!!!!!///>)H%.** * )/!;;;------::::::::::::: -----;;;;;!!!//>)IH:- ## #&!!;;-----:::::::::::::: --------;;;;;!!//)& .;I*-H#&||&/ *)/!;;-----:::::::::::::: :----------;;;;!/||>//>>>>//>>)|% %|&/!;;----::::::::::::::. :::::---------;;;;!!!!!!!!!!!//>|.H: #I>/!;;-----:::::::::::::.. ::::::::----------;;;;;;;;;;!!!//)H: #| IH&*I#/;;-----:::::::::::::... ::::::::::::------------;;;;;;;!!/>)I>>)||I# H&))>////*!;;-----:::::::::::::.... ::::::::::::::::-------------;;;;;;!!!!//>|: !:|//!!!;;;;-----::::::::::::::..... ::::::::::::::::::::-------------;;;;;;!!/>)|.*#|>/!!;;;;-------::::::::::::::...... ::::::::::::::::::::::::-------------;;;;!!/>&*|I !;;;--------::::::::::::::........ :::::::::::::::::::::::::::-------------;;;!:H!!;;;--------:::::::::::::::.......... ...:::::::::::::::::::::::::::::------------------------:::::::::::::::............. .....::::::::::::::::::::::::::::::::::-----------:::::::::::::::::::............... .........::::::::::::::::::::::::::::::::::::::::::::::::::::::::................... .............::::::::::::::::::::::::::::::::::::::::::::::::.......................
Fixed point 16 bit arithmetic
/**
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;
}
$ gcc fixedPoint.c -lm && ./a.out PRECISION=6 aaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcdcccbbbbbb aaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccddcbbbbb aaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbegfcdbbb aaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdccedbb aaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdcccb aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbcfdddcccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdded aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbcccccddfcccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccc aaaaaaaaaaaaaaaaaabbbbbbbbbbbbbcccccdeccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbcc aaaaaaaaaaaaaaaaabbbbbbbbbbfcccccddeccccccccccccccccdddddeeeddddccccccbbbbbbbbbbbbbbbbbbbbbbbbbe aaaaaaaaaaaaaaaabbbbbbbbbbcccccdddccccccccccccccdeddddeefigeeeddddecccccbbbbbbbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaaaabbbbbbbecccccdddcccccccccccccdddddddddeefhmgfffddddedcccccbbbbbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaaabbbbbbbcccccccdcccccccccccccccdgddddddfeefgjpijjfdddddedccccccbbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaaabbbbbccccccdedccccccccccccccdddddddddeeefgkj ojgfedddddeccccccbbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaabbbbbcccccegeccccccccccccccdeedddddddeeeeghhkp hgheefddddecccccccbbbbbbbbbbbbbbbbb aaaaaaaaaaaaabbbbccccceddcccccccccccccccfddddddddeeeeefmlkr ihheeeedddddgccccccbbbbbbbbbbbbbbbb aaaaaaaaaaaaabbbccccddfcccccccccccccccedddddddddeeegffhnp rpjffeeeiddddcccccccbbbbbbbbbbbbbbb aaaaaaaaaaaabbbcccddecccccccccccccccddddddddddeeffffgghm jgffeeeegdddccccccccbbbbbbbbbbbbb aaaaaaaaaaabbbccdedccccccccccccccccdddddddddeefffffgghil khggffffeeeddccccccccbbbbbbbbbbbb aaaaaaaaaaabbccdeccccccccccccccccddddddddeeef ijjhhhkijlo qkihjhgffgngeddcccccccbbbbbbbbbbbb aaaaaaaaaabbcddccccccccccccccccdddddddfeeeefgjq lkk p n khhhiqifedcccccccdbbbbbbbbbbb aaaaaaaaaabbccccccccccccccccccddddddefeeeeffgilq plk rrqgeddcccccccdbbbbbbbbbb aaaaaaaaaabdccccccccccccccccdddhegeeeeeefffghiq mfeeddcccccccdbbbbbbbbb aaaaaaaaaaccccccccccccccccdddeeeeeeeeeeffffhjklp phfeeddcccccccdcbbbbbbbb aaaaaaaaabcccccccccccccddddegeeeeeeeeeffffhppp jgggedddccccccccbbbbbbbb aaaaaaaaabccccccccccddddeefpifffffffffggggik hgfedddcccccccdcbbbbbbb aaaaaaaaaccccccceddddddeeifl hgggjrhggggghj p qjnfdddcccccccdcbbbbbbb aaaaaaaabccccddedddddefeefghqnokkloqiqhhhik ifdddcccccccdcbbbbbbb aaaaaaaaccceddddddddgfeeffghir o n qmjiijo igfedddcccccccccbbbbbb aaaaaaaaccddedddddeeeeeefgghkq lll lgfddddcccccccdcbbbbbb aaaaaaaacddddddddeeeeeefhgjol rn geddddcccccccdcbbbbbb aaaaaaaaedddddddeeeffggojjll hfeddddeccccccdcbbbbbb aaaaaaaaddddddefffffggmkopmop ngfefdddfccccccdcbbbbbb aaaaaaaaeeffgihggiihikk hfeefdddeccccccddbbbbbb aaaaaaaa kigfgefdddecccccceebbbbbb aaaaaaaaeeffhgjggghhhklqm ligfhefdddeccccccddbbbbbb aaaaaaaaddddddefffffgggirq hffefdddeccccccdebbbbbb aaaaaaaahdddddddeefgfggilkjk hfeedddeccccccddbbbbbb aaaaaaaacddddddddeeeeeefhhhkl lfefdddeccccccdcbbbbbb aaaaaaaaccddedddddefeeeeffgijo on qfedddcccccccdcbbbbbb aaaaaaaabcceddddddddegeeefggik r kko jhfedddcccccccdcbbbbbb aaaaaaaabccccddddddddefeeefijmk jkp kmiijlq qhfedddcccccccccbbbbbb aaaaaaaaacccccccdddddddeeefh hhghi kjggghil r geddcccccccdcbbbbbbb aaaaaaaaabccccccccccdddddefgnfgffghggggggghjm lj feddcccccccdcbbbbbbb aaaaaaaaabccccccccccccccdddeffggeeeefffffggm igfefddcccccccdbbbbbbbb aaaaaaaaaaccccccccccccccccdddeeeeeeeeeeffffhjm kgfeddcccccccdcbbbbbbbb aaaaaaaaaabdccccccccccccccccdddfeeeeeeeegffgiikq feeddcccccccebbbbbbbbb aaaaaaaaaabbccccccccccccccccccdddddegeeeegffgho p nheeddcccccchfbbbbbbbbb aaaaaaaaaabbbddcccccccccccccccccdddddeeeeeefhm l ki jlnjeddcccccccdbbbbbbbbbb aaaaaaaaaaabbccecccccccccccccccccdddddddfeeefir jii npm k ohgggineedcccccccdbbbbbbbbbbb aaaaaaaaaaabbbccdddccccccccccccccccddddddddeeefggggggiik mjhhgfffffedddcccccccbbbbbbbbbbbb aaaaaaaaaaaabbbcccedfcccccccccccccccdddddddddeegffffgghp hgffgeeeedddccccccccbbbbbbbbbbbb aaaaaaaaaaaabbbbccccdddcccccccccccccccgdddddddddeegffgil ggfeeeeddddcccccccbbbbbbbbbbbbbb aaaaaaaaaaaaabbbbbccccdddccccccccccccccfeddddddddeeeefgi l nkqgeeegeddddcccccccbbbbbbbbbbbbbbb aaaaaaaaaaaaabbbbbbcccccdedccccccccccccccdedddddddeeeeeghik khhfeefdddddeccccccbbbbbbbbbbbbbbbb aaaaaaaaaaaaaabbbbbbccccccdddcccccccccccccddedddddddeeefigil jggfedddddddcccccbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaaabbbbbbbcccccccdccccccccccccccdefdddddeeeffhlliimfdddddedccccccbbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaaaabbbbbbbccccccdddccccccccccccccdddddddeeefg jggheddddedccccccbbbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaaaabbbbbbbbbccccccdddccccccccccccccdedddddefgiffeeddddeccccccbbbbbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaaaaabbbbbbbbbbecccccdeeccccccccccccccceddddeffegddddgcccccbbbbbbbbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaaaaaabbbbbbbbbbbbcccccdddcccccccccccccccccddddddddccccccbbbbbbbbbbbbbbbbbbbbbbbbbbc aaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbccccddeccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbed aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbccceddcccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccd aaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbdcccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbecccc aaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccdebb aaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdfccbbb aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcgdccbbbb
C#
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;
}
}
C++
This generic function assumes that the image can be accessed like a two-dimensional array of colors. It may be passed a true array (in which case the Mandelbrot set will simply be drawn into that array, which then might be saved as image file), or a class which maps the subscript operator to the pixel drawing routine of some graphics library. In the latter case, there must be functions get_first_dimension and get_second_dimension defined for that type, to be found by argument dependent lookup. The code provides those functions for built-in arrays.
#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;
}
}
Note this code has not been executed.
A Simple version in CPP. Definitely not as crazy good as the ASCII one in C above.
#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");
}
C3
This program produces a BMP as output.
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;
}
}
}
}
Cixl
Displays a zooming Mandelbrot using ANSI graphics.
use: cx;
define: max 4.0;
define: max-iter 570;
let: (max-x max-y) screen-size;
let: max-cx $max-x 2.0 /;
let: max-cy $max-y 2.0 /;
let: rows Stack<Str> new;
let: buf Buf new;
let: zoom 0 ref;
func: render()()
$rows clear
$max-y 2 / {
let: y;
$buf 0 seek
$max-x {
let: x;
let: (zx zy) 0.0 ref %%;
let: cx $x $max-cx - $zoom deref /;
let: cy $y $max-cy - $zoom deref /;
let: i #max-iter ref;
{
let: nzx $zx deref ** $zy deref ** - $cx +;
$zy $zx deref *2 $zy deref * $cy + set
$zx $nzx set
$i &-- set-call
$nzx ** $zy deref ** + #max < $i deref and
} while
let: c $i deref % -7 bsh bor 256 mod;
$c {$x 256 mod $y 256 mod} {0 0} if-else $c new-rgb $buf set-bg
@@s $buf print
} for
$rows $buf str push
} for
1 1 #out move-to
$rows {#out print} for
$rows riter {#out print} for;
#out hide-cursor
raw-mode
let: poll Poll new;
let: is-done #f ref;
$poll #in {
#in read-char _
$is-done #t set
} on-read
{
$zoom &++ set-call
render
$poll 0 wait _
$is-done deref !
} while
#out reset-style
#out clear-screen
1 1 #out move-to
#out show-cursor
normal-mode
Clojure
Inspired by the Ruby and Perl below
(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 ""))
- Output:
harold@freeside:~/src/mandelbrot$ clj -M mandelbrot.clj * * *** * ******** ********* ****** ** ** ************ * *** ******************* * * ***************************** **************************** ******************************** ******************************** ************************************ * * * *********************************** *********** *********************************** ************ ************************************** ************** ************************************ **************************************************** ******************************************************* ************************************************************************ ******************************************************* **************************************************** ************** ************************************ ************ ************************************** *********** *********************************** * * *********************************** ************************************ * ******************************** ******************************** **************************** ***************************** *** ******************* * * ** ** ************ * ****** ********* ******** * *** * *
COBOL
EBCDIC art.
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.
- Output:
################################################################ ################################# ############################ ################################ ########################### ############################## ## ############################ ######################## # ###################### ######################## ################## ##################### ################# #################### ############### ######## ## ##### ################ ####### # ################ ###### # ################# #################### ###### # ################# ####### # ################ ######## ## ##### ################ #################### ############### ##################### ################# ######################## ################## ######################## # ###################### ############################## ## ############################ ################################ ########################### ################################# ############################ ################################################################ ################################################################
Common Lisp
(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)))
Cowgol
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;
- Output:
!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" !!!!!!!!!!!!!"""""""""#######################$$$$$$$%'+)%%%$$$$$#####""""""""""" !!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(+,)++&%$$$$$$######"""""" !!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*5:/+('&%%$$$$$$#######""" !!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@,'&%%%%%$$$$######## !!!!!!!"""####################$$$$$$$$%%%&'())((())*,@@@@@@/+))('&&&&)'%$$###### !!!!!!""###################$$$$$%%%%%%&&&'+.@@=/<@@@@@@@@@@@@@@@/++@..93%%$##### !!!!!"################$$$%%%%%%%%%%&&&&'),+2@@@@@@@@@@@@@@@@@@@@@@@@@1(&&%$$#### !!!!"##########$$$$$%%&(-(''''''''''''(*,5@@@@@@@@@@@@@@@@@@@@@@@@@@@@+)-&%$$### !!!!####$$$$$$$$%%%%%&'(*-@1.+.@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4-(&%$$$## !!!!#$$$$$$$$$%%%%%%'''++.6@@@@@@@@@8/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3(%%$$$$# !!!#$$$$$$$%&&&&''()/-5.5@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?'&%%$$$$# !!!(**+/+<523/80/46@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+)'&&%%$$$$# !!!#$$$$$$$%&&&&''().-2.@@@@@@@@@@@@@@?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$# !!!!#$$$$$$$$$%%%%%&'''/,.7@@@@@@@@@;/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@0'%%$$$$# !!!!####$$$$$$$$%%%%%&'(*-:2.,/?-5+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+(&%$$$## !!!!"##########$$$$$%%&(-(''''(''''''((*,4@@@@@@@@@@@@@@@@@@@@@@@@@@@4+).&%$$### !!!!!"################$$$%%%%%%%%%%&&&&')<,4@@@@@@@@@@@@@@@@@@@@@@@@@/('&%%$#### !!!!!!""##################$$$$$$%%%%%%&&&'*.@@@0@@@@@@@@@@@@@@@@1,,@//9)%%$##### !!!!!!!"""####################$$$$$$$$%%%&(())((()**-@@@@@@/+)))'&&&')'%$$###### !!!!!!!!""""#####################$$$$$$$$$$%%%&&&''(,@@@@@@@+'&&%%%%%$$$######## !!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*7@0+('&%%%$$$$$#######""" !!!!!!!!!!!"""""""######################$$$$$$$$$%%%&&(+-).*&%$$$$$$######"""""" !!!!!!!!!!!!!"""""""""#######################$$$$$$%%'3(%%%$$$$$######"""""""""" !!!!!!!!!!!!!!!""""""""""""#####################################""""""""""""""""
Craft Basic
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
D
Textual Version
This uses std.complex
because D built-in complex numbers are deprecated.
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;
}
}
- Output:
....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ................................................................##..................... .............................................................######.................... .............................................................#######................... ..............................................................######................... ..........................................................#.#.###..#.#................. ...................................................##....################.............. ..................................................###.######################.###....... ...................................................############################........ ................................................###############################........ ................................................################################....... .............................................#####################################..... ..............................................###################################...... ..............................##.####.#......####################################...... ..............................###########....####################################...... ............................###############.######################################..... ............................###############.#####################################...... ........................##.#####################################################....... ......#.#####################################################################.......... ........................##.#####################################################....... ............................###############.#####################################...... ............................###############.######################################..... ..............................###########....####################################...... ..............................##.####.#......####################################...... ..............................................###################################...... .............................................#####################################..... ................................................################################....... ................................................###############################........ ...................................................############################........ ..................................................###.######################.###....... ...................................................##....################.............. ..........................................................#.#.###..#.#................. ..............................................................######................... .............................................................#######................... .............................................................######.................... ................................................................##..................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... .......................................................................................
More Functional Textual Version
The output is similar.
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;
}
Graphical Version
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; }
}
Dart
Implementation in Dart, works on https://dartpad.dev The implementation uses an incomplete Complex class supporting operator overloading.
class Complex {
double _r, _i;
Complex(this._r, this._i);
get r => _r;
get i => _i;
toString() => "($r,$i)";
operator +(Complex other) => Complex(r + other.r, i + other.i);
operator *(Complex other) =>
Complex(r * other.r - i * other.i, r * other.i + other.r * i);
abs() => r * r + i * i;
}
void main() {
const startX = -1.5;
const startY = -1.0;
const stepX = 0.03;
const stepY = 0.1;
for (int y = 0; y < 20; y++) {
String line = "";
for (int x = 0; x < 70; x++) {
var c = Complex(startX + stepX * x, startY + stepY * y);
var z = 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);
}
}
Dc
ASCII output
This can be done in a more Dc-ish way, e.g. by moving the loop macros' definitions to the initialisations in the top instead of saving the macro definition of inner loops over and over again in outer loops.
_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
- Output:
!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" !!!!!!!!!!!!!"""""""""#######################$$$$$$$%'0(%%%$$$$$#####""""""""""" !!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(++)++&$$$$$$$######"""""" !!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*@;/*('&%%$$$$$$#######""" !!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@+'&%%%%%$$$$######## !!!!!!!"""####################$$$$$$$$%%%&'())((())*-@@@@@@.+))('&&&&+&%$$###### !!!!!!""###################$$$$$%%%%%%&&&'+.@@@08@@@@@@@@@@@@@@@/+,@//@)%%$##### !!!!!"################$$$%%%%%%%%%%&&&&')-+7@@@@@@@@@@@@@@@@@@@@@@@@@4(&&%$$#### !!!!"##########$$$$$%%&(,('''''''''''((*-5@@@@@@@@@@@@@@@@@@@@@@@@@@@3+)4&%$$### !!!!####$$$$$$$$%%%%%&'(*-@1.+/@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3+'&%$$$## !!!!#$$$$$$$$$%%%%%%'''++.7@@@@@@@@@9/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<6'%%$$$$# !!!#$$$$$$$%&&&&''().-2.6@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$# !!!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2+)'&&%%$$$$# !!!#$$$$$$$%&&&&''().-2.6@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$# !!!!#$$$$$$$$$%%%%%%'''++.7@@@@@@@@@9/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<6'%%$$$$# !!!!####$$$$$$$$%%%%%&'(*-@1.+/@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3+'&%$$$## !!!!"##########$$$$$%%&(,('''''''''''((*-5@@@@@@@@@@@@@@@@@@@@@@@@@@@3+)4&%$$### !!!!!"################$$$%%%%%%%%%%&&&&')-+7@@@@@@@@@@@@@@@@@@@@@@@@@4(&&%$$#### !!!!!!""###################$$$$$%%%%%%&&&'+.@@@08@@@@@@@@@@@@@@@/+,@//@)%%$##### !!!!!!!"""####################$$$$$$$$%%%&'())((())*-@@@@@@.+))('&&&&+&%$$###### !!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@+'&%%%%%$$$$######## !!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*@;/*('&%%$$$$$$#######""" !!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(++)++&$$$$$$$######"""""" !!!!!!!!!!!!!"""""""""#######################$$$$$$$%'0(%%%$$$$$#####""""""""""" !!!!!!!!!!!!!!!"""""""""""""####################################""""""""""""""""
PGM (P5) output
This is a condensed version of the ASCII output variant modified to generate a PGM (P5) image.
_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
Delphi
See Pascal.
DWScript
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;
EasyLang
res = 4
maxiter = 200
#
# better but slower:
# res = 8
# maxiter = 300
#
#
mid = res * 50
center_x = 3 * mid / 2
center_y = mid
scale = mid
#
background 000
textsize 2
#
fastfunc iter cx cy maxiter .
while xx + yy < 4 and it < maxiter
y = 2 * x * y + cy
x = xx - yy + cx
xx = x * x
yy = y * y
it += 1
.
return it
.
proc draw . .
clear
for scr_y = 0 to 2 * mid - 1
cy = (scr_y - center_y) / scale
for scr_x = 0 to 2 * mid - 1
cx = (scr_x - center_x) / scale
it = iter cx cy maxiter
if it < maxiter
color3 it / 20 it / 100 it / 150
move scr_x / res scr_y / res
rect 1 / res 1 / res
.
.
.
color 990
move 1 1
text "Short press to zoom in, long to zoom out"
.
on mouse_down
time0 = systime
.
on mouse_up
center_x += mid - mouse_x * res
center_y += mid - mouse_y * res
if systime - time0 < 0.3
center_x -= mid - center_x
center_y -= mid - center_y
scale *= 2
else
center_x += (mid - center_x) * 3 / 4
center_y += (mid - center_y) * 3 / 4
scale /= 4
.
draw
.
draw
eC
Drawing code:
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;
}
}
}
Interactive class with Rubberband Zoom:
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 {};
EchoLisp
(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]
Elixir
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
- Output:
??????=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<=========== ?????===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== ????===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= ???==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== ??==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== ??=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== ?=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== ?<<<<;;;;;:::972456-567763 +9;;<<<<<<<= ?<;;;;;;::::9875& .3 *9;;;<<<<<<= ?;;;;;;::997564' ' 8:;;;<<<<<<= ?::988897735/ &89:;;;<<<<<<= ?::988897735/ &89:;;;<<<<<<= ?;;;;;;::997564' ' 8:;;;<<<<<<= ?<;;;;;;::::9875& .3 *9;;;<<<<<<= ?<<<<;;;;;:::972456-567763 +9;;<<<<<<<= ?=<<<<<<<<;;;:599999999886 %78:;;<<<<<<== ??=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<=== ??==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<==== ???==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<===== ????===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======= ?????===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======== ??????=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<===========
Emacs Lisp
Text mode
; === 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)
- Output:
---------------------------------------------------------------------------- ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- ---------------------------------------------------------*------------------ ---------------------------------------------------------------------------- ----------------------------------------------------**--***--*-------------- -----------------------------------------------------********--------------- ------------------------------------------------------*******--------------- --------------------------------------------*-*--******************--------- --------------------------------------------****************************---- -----------------------------------------*-****************************----- -----------------------------------------*******************************---- ---------------------------------------************************************- --------------------------**--**-*-----**********************************--- -------------------------***********---************************************- ------------------*-----**************************************************-- -------------------*****************************************************---- -*********************************************************************------ -------------------*****************************************************---- ------------------*-----**************************************************-- -------------------------***********---************************************- --------------------------**--**-*-----**********************************--- ---------------------------------------************************************- -----------------------------------------*******************************---- -----------------------------------------*-****************************----- --------------------------------------------****************************---- --------------------------------------------*-*--******************--------- ------------------------------------------------------*******--------------- -----------------------------------------------------********--------------- ----------------------------------------------------**--***--*-------------- ---------------------------------------------------------------------------- ---------------------------------------------------------*------------------ ---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Graphical version
![](http://static.miraheze.org/rosettacodewiki/thumb/6/65/Mandelbrot_emacs_lisp.png/300px-Mandelbrot_emacs_lisp.png)
With a few modifications (mandel-size, mandel-iter, string-to-image, mandel-pic), the code above can also render the Mandelbrot fractal to an XPM image and display it directly in the buffer. (You might have to scroll up in Emacs after the function has run to see its output.)
; === 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)
Erlang
Function seq_float/2 is copied from Andrew Fecheyr's GitHubGist.
Using module complex from Geoff Hulette's GitHub repository
Geoff Hulette's GitHub repository provides two alternative implementations which are very interesting.
-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, []).
% **************************************************
Output:
** ****** ******** ****** ******** ** * *** ***************** ************************ *** **************************** ****************************** ****************************** ************************************ * ********************************** ** ***** * ********************************** *********** ************************************ ************** ************************************ *************************************************** ***************************************************** ***************************************************** ***************************************************** *************************************************** ************** ************************************ *********** ************************************ ** ***** * ********************************** * ********************************** ************************************ ****************************** ****************************** **************************** ************************ *** *** ***************** ******** ** * ****** ******** ****** **
ERRE
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
Note: This is a PC version which uses EGA 16-color 320x200. Graphic commands are taken from PC.LIB library.
F#
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)
Alternate version, applicable to text and GUI
Basic generation code
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))
Text display
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")
Results:
- Output:
................................................................................ ................................................................................ ................................................. ............................. ................................................ ........................... ................................................. ........................... ....................................... . ...................... ........................................ ................. .................................... .................. .................................... ................. .......................... ...... ................ ....................... ... ................ ..................... . ................ ................. ................. ................. ................. ..................... . ................ ....................... ... ................ .......................... ...... ................ .................................... ................. .................................... .................. ........................................ ................. ....................................... . ...................... ................................................. ........................... ................................................ ........................... ................................................. ............................. ................................................................................
Graphics display
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))
Factor
! 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
- Output:
bbbbbbbcccccdddddddddddddddddddeeeeeeeffghjpjl feeeeedddddcccccccccccc bbbbbbccccddddddddddddddddddeeeeeeeefffghikopjhgffeeeeedddddcccccccccc bbbbbcccddddddddddddddddddeeeeeeeefffggjotx etiigfffeeeeddddddcccccccc bbbbccddddddddddddddddddeeeeeeeffgggghhjq iihgggfffeedddddddcccccc bbbccddddddddddddddddeeeeeefffghvasjjqqyqt upqlrjhhhkhfedddddddccccc bbbcdddddddddddddddeeeeffffffgghks c qnbpfmgfedddddddcccc bbcdddddddddddddeefffffffffgggipmt qhgfeedddddddccc bbdddddddddeeeefhlggggggghhhhils ljigfeedddddddcc bcddddeeeeeefffghmllkjiljjiijle yhfeedddddddcc bddeeeeeeeffffghhjoj do clmq qlgfeeedddddddc bdeeeeeefffffhiijpu sm ohffeeedddddddc beffeefgggghhjocsu higffeeedddddddc cmihgffeeedddddddd beffeefgggghhjocsu higffeeedddddddc bdeeeeeefffffhiijpu sd ohffeeedddddddc bddeeeeeeeffffghhjoj do clmq qlgfeeedddddddc bcddddeeeeeefffghmllkjiljjiijle yhfeedddddddcc bbdddddddddeeeefhlggggggghhhhils ljigfeedddddddcc bbcdddddddddddddeefffffffffgggipmt qhgfeedddddddccc bbbcdddddddddddddddeeeeffffffgghks c qnbpfmgfedddddddcccc bbbccddddddddddddddddeeeeeefffghvasjjqqyqt upqlrjhhhkhfedddddddccccc bbbbccddddddddddddddddddeeeeeeeffgggghhjq iihgggfffeedddddddcccccc bbbbbcccddddddddddddddddddeeeeeeeefffggjotx etiigfffeeeeddddddcccccccc bbbbbbccccddddddddddddddddddeeeeeeeefffghikopjhgffeeeeedddddcccccccccc bbbbbbbcccccdddddddddddddddddddeeeeeeeffghjpjl feeeeedddddcccccccccccc
Fennel
#!/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))
FOCAL
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
- Output:
********************************************************************** ********************************************************************** **************************************************** ***************** ************************************************* *************** ************************************************* *************** **************************************** * ********** *************************************** * ****** ************************************* ***** ********************** **** ******* **** *********************** ** ** ********************* **** *** * ******* ********************* **** *********************** ** ** ********************** **** ******* **** ************************************* ***** *************************************** * ****** **************************************** * ********** ************************************************* *************** ************************************************* *************** **************************************************** ***************** ********************************************************************** ********************************************************************** **********************************************************************
Forth
This uses grayscale image utilities.
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
This is a completely integer version without local variables, which uses 4tH's native graphics library.
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
Fortran
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
bs
Frink
This draws a graphical Mandelbrot set using Frink's built-in graphics and complex arithmetic.
// 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[]
Furor
###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” }
Futhark
Computes escapes for each pixel, but not the colour.
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))
FutureBasic
_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
- Output:
!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" !!!!!!!!!!!!!"""""""""#######################$$$$$$$%'+)%%%$$$$$#####""""""""""" !!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(+,)++&%$$$$$$######"""""" !!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*5:/+('&%%$$$$$$#######""" !!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@,'&%%%%%$$$$######## !!!!!!!"""####################$$$$$$$$%%%&'())((())*,@@@@@@/+))('&&&&)'%$$###### !!!!!!""###################$$$$$%%%%%%&&&'+.@@=/<@@@@@@@@@@@@@@@/++@..93%%$##### !!!!!"################$$$%%%%%%%%%%&&&&'),+2@@@@@@@@@@@@@@@@@@@@@@@@@1(&&%$$#### !!!!"##########$$$$$%%&(-(''''''''''''(*,5@@@@@@@@@@@@@@@@@@@@@@@@@@@@+)-&%$$### !!!!####$$$$$$$$%%%%%&'(*-@1.+.@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4-(&%$$$## !!!!#$$$$$$$$$%%%%%%'''++.6@@@@@@@@@8/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3(%%$$$$# !!!#$$$$$$$%&&&&''()/-5.5@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?'&%%$$$$# !!!(**+/+<523/80/46@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+)'&&%%$$$$# !!!#$$$$$$$%&&&&''().-2.@@@@@@@@@@@@@@?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$# !!!!#$$$$$$$$$%%%%%&'''/,.7@@@@@@@@@;/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@0'%%$$$$# !!!!####$$$$$$$$%%%%%&'(*-:2.,/?-5+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+(&%$$$## !!!!"##########$$$$$%%&(-(''''(''''''((*,4@@@@@@@@@@@@@@@@@@@@@@@@@@@4+).&%$$### !!!!!"################$$$%%%%%%%%%%&&&&')<,4@@@@@@@@@@@@@@@@@@@@@@@@@/('&%%$#### !!!!!!""##################$$$$$$%%%%%%&&&'*.@@@0@@@@@@@@@@@@@@@@1,,@//9)%%$##### !!!!!!!"""####################$$$$$$$$%%%&(())((()**-@@@@@@/+)))'&&&')'%$$###### !!!!!!!!""""#####################$$$$$$$$$$%%%&&&''(,@@@@@@@+'&&%%%%%$$$######## !!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*7@0+('&%%%$$$$$#######""" !!!!!!!!!!!"""""""######################$$$$$$$$$%%%&&(+-).*&%$$$$$$######"""""" !!!!!!!!!!!!!"""""""""#######################$$$$$$%%'3(%%%$$$$$######"""""""""" !!!!!!!!!!!!!!!""""""""""""#####################################"""""""""""""""
Fōrmulæ
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.
Programs in Fōrmulæ are created/edited online in its website.
In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.
Solution
We need first to generate a color palette, this is, a list of colors:
The following function draw the Mandelbrot set:
Test Case 1. Grayscale palette
Test case 2. Black & white palette
GLSL
Uses smooth coloring.
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));
}
gnuplot
The output from gnuplot is controlled by setting the appropriate values for the options terminal
and output
.
set terminal png
set output 'mandelbrot.png'
The following script draws an image of the number of iterations it takes to escape the circle with radius rmax
with a maximum of nmax
.
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
- Output:
Go
- Text
Prints an 80-char by 41-line depiction.
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("")
}
}
- Graphical
![](http://static.miraheze.org/rosettacodewiki/thumb/b/b6/GoMandelbrot.png/300px-GoMandelbrot.png)
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)
}
}
Golfscript
Código sacado de https://codegolf.stackexchange.com/
20{40{0.1{.{;..*2$.*\-
20/3$-@@*10/3$-..*2$.*+1600<}*}32*'
*'=\;\;@@(}60*;(n\}40*;]''+
- Output:
000000000000000000000000000000000000000010000000000000000000 000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000001000000000000000000000000 000000000000000000000000000000000000001000000000000000000000 000000000000000000000000000000000000111000000000000000000000 000000000000000000000000000000000000111110000000000000000000 000000000000000000000000000000000000011100000000000000000000 000000000000000000000000000001000110111100010000000000000000 000000000000000000000000000000100111111111110000000000000000 000000000000000000000000000001011111111111110111000000000000 000000000000000000000000000001111111111111111110000000000000 000000000000000000000000000000111111111111111110000000000000 000000000000001000000000000011111111111111111111000000000000 000000000000000000000000000011111111111111111111000000000000 000000000000000000000000000111111111111111111111000000000000 000000000000000000000000001111111111111111111111100000000000 000000000000000001111110001111111111111111111111100000000000 000000000000000011111111101111111111111111111111100000000000 000000000000100111111111111111111111111111111111000000000000 000000000001101111111111111111111111111111111111000000000000 011111111111111111111111111111111111111111111100000000000000 000000000000001111111111111111111111111111111110000000000000 000000000000000111111111111111111111111111111111000000000000 000000000000000001111111111111111111111111111111100000000000 000000000000000001111111101111111111111111111111000000000000 000000000000000001011100000111111111111111111111100000000000 000000000000000000000100000111111111111111111111000000000000 000000000000000100000000001111111111111111111111100000000000 000000000000000100000000000011111111111111111111000000000000 000000000000000000000000000011111111111111111110000000000000 000000000000000000000000000001111111111111111111000000000000 000000000000000000000000000000111111111111111111000000000000 000000000000000000000000000001101111111111111000000000000000 000000000000000000000000000011000011111110100000000000000000 000000000000000000000000000000000000111100000000000000000000 000000000000000000000000000000000000111110000000000000000000 000000000000000000000000000000000000111100000000000000000000 000000000000000000000000000000000000011000000000000000000000 000000000000000000000000000000000000001000000000000000000000 000000000000000000000000000000000000000000000000000000000000
Hare
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);
};
- Output:
....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ................................................................##..................... .............................................................######.................... .............................................................#######................... ..............................................................######................... ..........................................................#.#.###..#.#................. ...................................................##....################.............. ..................................................###.######################.###....... ...................................................############################........ ................................................###############################........ ................................................################################....... .............................................#####################################..... ..............................................###################################...... ..............................##.####.#......####################################...... ..............................###########....####################################...... ............................###############.######################################..... ............................###############.#####################################...... ........................##.#####################################################....... ......#.###...#.#############################################################.......... ........................##.#####################################################....... ............................###############.#####################################...... ............................###############.######################################..... ..............................###########....####################################...... ..............................##.####.#......####################################...... ..............................................###################################...... .............................................#####################################..... ................................................################################....... ................................................###############################........ ...................................................############################........ ..................................................###.######################.###....... ...................................................##....################.............. ..........................................................#.#.###..#.#................. ..............................................................######................... .............................................................#######................... .............................................................######.................... ................................................................##..................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... ....................................................................................... .......................................................................................
Haskell
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]
]
- Output:
** ****** ******** ****** ******** ** * *** ***************** ************************ *** **************************** ****************************** ****************************** ************************************ * ********************************** ** ***** * ********************************** *********** ************************************ ************** ************************************ *************************************************** ***************************************************** *********************************************************************** ***************************************************** *************************************************** ************** ************************************ *********** ************************************ ** ***** * ********************************** * ********************************** ************************************ ****************************** ****************************** **************************** ************************ *** *** ***************** ******** ** * ****** ******** ****** **
haskell one-liners :
-- 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
A legible variant of the first of the "one-liner" contributions above:
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]
)
[".", "\'", ":", "!", "|", "}", "#", " "]
)
- Output:
# ## # }}}}}}} #}}}}}}}} }}}}}}}}} }}}}}}}}} }}}}}}}}}# }}}}}}}}}} }}}}}}}} }}}}}}} |||}} } ||||||||||| } ||||||||||||||||||| | . ' ||||||||||||||||||||||||| ..' |||||||||||||||||||||||||||| '... ||||||||||||||||||||||||||||||| '.': '':|||||||||||||||||||||||||||||||||| :...' ||||||||||||||||||||||||||||||||||||:'..' |||||||||||||||||||||||||||||||||||||||:'' }||||||||||||||||||||||||||||||||||||||||| ||||||||||||||||||||||||||||||||||||||||||| || ||||||||||||||||||||||||||||||||||||||||||||! ||}||||||||||||||||||||||||||||||||||||||||||||| ||||||||||||||||||||||||||||||||||||||||||||||| ||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||||||||||||||!!!!!|||||||||||||||||| : |||||||||||||||||||||||||!!!!!!!!!!!!|||||||||||||||'.' ||||||||||||||||||||||!!!!!!!!!!!!!!!!||||||||||||| . .||||||||||||||||||||!!!!!!!!!!!!!!!!!!!!|||||||||||| | |||||||||||||||||||||!!!!!!!!!!!!!!!!!!!!!!||||||||||| | | |||||||||||||||||||!!!!!!!!!!!!!!!!!!!!!!!!|||||||||| ||! .:::!!!!. ||||||||||||||||||||!!!!!!!!!!!!!:::!!!!!!!!!|||||||||| !'::::::::!!! ||||||||||||||||||!!!!!!!!!!!:::::::::!!!!!!!||||||||||| ::::::::::::!!!| |||||||||||||||||||!!!!!!!!!:::::::::::::!!!!!!|||||||| !::::::::::::::!!!! ||||||||||||||||||!!!!!!!!!:::::::::::::::!!!!!|||||||| . ::::::''''::::::!!! |||||||||||||||||!!!!!!!!!:::::::''''::::::!!!!|||||||| :::::'''''''''::::!!! |||||||||||||||||!!!!!!!!::::::'''''''''::::!!!!|||||||| !::::''''''''''':::!!! ||||||||||||||||||!!!!!!!::::::''''''''''':::!!!!||||||! ::::''''''..''''':::!!! |||||||||||||||||!!!!!!!!:::::''''''..''''':::!!!||||||} :::'''''......''':::!!! |||||||||||||||||!!!!!!!:::::'''''......''':::!!!|||||| ::::''''........'''::!!!||||||||||||||||||!!!!!!!:::::''''........'''::!!!||||| .... ::::'''..........''::!!!||||||||||||||||||!!!!!!!:::::'''..........''::!!|||||| .....':::''''..........''::!!|||||||||||||||||||!!!!!!!::::''''..........''::!!|||| ## | ::.....':::''''..........''::!!|||||||||||||||||||!!!!!!!::::''''..........''::!!|| .....':::''''..........''::!!|||||||||||||||||||!!!!!!!::::''''..........''::!!|||| .... ::::'''..........''::!!!||||||||||||||||||!!!!!!!:::::'''..........''::!!|||||| ::::''''........'''::!!!||||||||||||||||||!!!!!!!:::::''''........'''::!!!||||| :::'''''......''':::!!! |||||||||||||||||!!!!!!!:::::'''''......''':::!!!|||||| ::::''''''..''''':::!!! |||||||||||||||||!!!!!!!!:::::''''''..''''':::!!!||||||} !::::''''''''''':::!!! ||||||||||||||||||!!!!!!!::::::''''''''''':::!!!!||||||! :::::'''''''''::::!!! |||||||||||||||||!!!!!!!!::::::'''''''''::::!!!!|||||||| . ::::::''''::::::!!! |||||||||||||||||!!!!!!!!!:::::::''''::::::!!!!|||||||| !::::::::::::::!!!! ||||||||||||||||||!!!!!!!!!:::::::::::::::!!!!!|||||||| ::::::::::::!!!| |||||||||||||||||||!!!!!!!!!:::::::::::::!!!!!!|||||||| !'::::::::!!! ||||||||||||||||||!!!!!!!!!!!:::::::::!!!!!!!||||||||||| ||! .:::!!!!. ||||||||||||||||||||!!!!!!!!!!!!!:::!!!!!!!!!|||||||||| | | |||||||||||||||||||!!!!!!!!!!!!!!!!!!!!!!!!|||||||||| | |||||||||||||||||||||!!!!!!!!!!!!!!!!!!!!!!||||||||||| .||||||||||||||||||||!!!!!!!!!!!!!!!!!!!!|||||||||||| ||||||||||||||||||||||!!!!!!!!!!!!!!!!||||||||||||| . |||||||||||||||||||||||||!!!!!!!!!!!!|||||||||||||||'.' |||||||||||||||||||||||||||!!!!||||||||||||||||||| : ||||||||||||||||||||||||||||||||||||||||||||||||| ||||||||||||||||||||||||||||||||||||||||||||||| ||}||||||||||||||||||||||||||||||||||||||||||||| || ||||||||||||||||||||||||||||||||||||||||||||! ||||||||||||||||||||||||||||||||||||||||||| }||||||||||||||||||||||||||||||||||||||||| |||||||||||||||||||||||||||||||||||||||:'' ||||||||||||||||||||||||||||||||||||:'..' '':|||||||||||||||||||||||||||||||||| :...' '... ||||||||||||||||||||||||||||||| '.': ..' |||||||||||||||||||||||||||| . ' ||||||||||||||||||||||||| } ||||||||||||||||||| | } ||||||||||| |||}} }}}}}}} }}}}}}}} }}}}}}}}}} }}}}}}}}}# }}}}}}}}} }}}}}}}}} #}}}}}}}} }}}}}}} # ## #
and a legible variant of the last of the "one-liner" contributions above:
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 ' '
]
]
Haxe
This version compiles for flash version 9 or greater. The compilation command is
haxe -swf mandelbrot.swf -main Mandelbrot
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);
}
}
Huginn
#! /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 ) );
}
- Output:
........................:::::::::::::::::::------------------------------------------------------:::::::::::::::::::::::::::::::::::: ......................::::::::::::::::------------------------------------++++++++++++++++++++---------:::::::::::::::::::::::::::::: ....................:::::::::::::-----------------------------------+++++++++++++*******+++++++++++--------:::::::::::::::::::::::::: ...................:::::::::::----------------------------------++++++++++++++++****%%******++++++++++---------:::::::::::::::::::::: .................:::::::::----------------------------------++++++++++++++++++++******% %****++++++++++++---------::::::::::::::::::: ................::::::::---------------------------------+++++++++++++++++++++******%%%%%*****+++++++++++++----------:::::::::::::::: ...............::::::---------------------------------++++++++++++++++++++*****%%%%% @%%%@***++++++++++++++----------:::::::::::::: ..............:::::--------------------------------++++++++++++++++++***********@% @%******+++++++++++++-----------::::::::::: .............::::-------------------------------+++++++++++++++++****************@ %%***************+++++------------::::::::: ............:::------------------------------+++++++++++++++++****@%%%****%@@%@% %%@ @%%%% %*% ********%**++++------------:::::::: ...........:::----------------------------+++++++++++++++++********% @%@@ %%%**%@%%@@**+++++------------:::::: ..........:::-------------------------+++++++++++++++++++**********% @ %%***++++++------------::::: ..........:----------------------+++++++++++++++++++++*********%%%% %%******++++++------------:::: .........:-----------------++++++++**************************** %*****+++++-------------::: .........----------+++++++++++++++****%********%%*********** @%% % %%**++++++-------------:: ........:------++++++++++++++++++*******%@@%%**%% %%%*******%% %%***+++++++-------------: ........---+++++++++++++++++++++********%@ @%%%**% %%***+++++++-------------: .......:-+++++++++++++++++++++*******%%%% @%% @****++++++++------------- .......-+++++++++++++***********%**@*%@ % %***+++++++++------------- .......++++++*******************%% @ %*****+++++++++------------- ....... %%******++++++++++------------- .......++++++*******************%% @ %*****+++++++++------------- .......-+++++++++++++***********%**@*%@ % %***+++++++++------------- .......:-+++++++++++++++++++++*******%%%% @%% @****++++++++------------- ........---+++++++++++++++++++++********%@ @%%%**% %%***+++++++-------------: ........:------++++++++++++++++++*******%@@%%**%% %%%*******%% %%***+++++++-------------: .........----------+++++++++++++++****%********%%*********** @%% % %%**++++++-------------:: .........:-----------------++++++++**************************** %*****+++++-------------::: ..........:----------------------+++++++++++++++++++++*********%%%% %%******++++++------------:::: ..........:::-------------------------+++++++++++++++++++**********% @ %%***++++++------------::::: ...........:::----------------------------+++++++++++++++++********% @%@@ %%%**%@%%@@**+++++------------:::::: ............:::------------------------------+++++++++++++++++****@%%%****%@@%@% %%@ @%%%% %*% ********%**++++------------:::::::: .............::::-------------------------------+++++++++++++++++****************@ %%***************+++++------------::::::::: ..............:::::--------------------------------++++++++++++++++++***********@% @%******+++++++++++++-----------::::::::::: ...............::::::---------------------------------++++++++++++++++++++*****%%%%% @%%%@***++++++++++++++----------:::::::::::::: ................::::::::---------------------------------+++++++++++++++++++++******%%%%%*****+++++++++++++----------:::::::::::::::: .................:::::::::----------------------------------++++++++++++++++++++******% %****++++++++++++---------::::::::::::::::::: ...................:::::::::::----------------------------------++++++++++++++++****%%******++++++++++---------:::::::::::::::::::::: ....................:::::::::::::-----------------------------------+++++++++++++*******+++++++++++--------:::::::::::::::::::::::::: ......................::::::::::::::::------------------------------------++++++++++++++++++++---------::::::::::::::::::::::::::::::
Icon and Unicon
IDL
IDL - Interactive Data Language (free implementation: GDL - GNU Data Language http://gnudatalanguage.sourceforge.net)
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
from the command line:
GDL>.run mandelbrot
or
GDL> Mandelbrot,[-1.,2.3],[-1.3,1.3],640,512,200
Inform 7
"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;
-).
Newer Glulx interpreters provide 32-bit floating-point operations, but this solution also supports fixed-point math which is more widely supported and accurate enough for a zoomed-out view. Inform 6 inclusions are used for the low-level math functions in either case. The rendering process is extremely slow, since the graphics system is not optimized for pixel-by-pixel drawing, so this solution includes an optimization for vertical symmetry (as in the default view) and also includes extra logic to draw the lines in a more immediately useful order.
Insitux
(function mandelbrot width height depth
(.. str
(for yy (range height)
xx (range width)
(let c_re (/ (* (- xx (/ width 2)) 4) width)
c_im (/ (* (- yy (/ height 2)) 4) width)
x 0 y 0 i 0)
(while (and (<= (+ (** x) (** y)) 4)
(< i depth))
(let x2 (+ c_re (- (** x) (** y)))
y (+ c_im (* 2 x y))
x x2
i (inc i)))
(strn ((zero? xx) "\n") (i "ABCDEFGHIJ ")))))
(mandelbrot 48 24 10)
- Output:
BBBBCCCDDDDDDDDDEEEEFGJJ EEEDDCCCCCCCCCCCCCCCBBB BBBCCDDDDDDDDDDEEEEFFH HFEEEDDDCCCCCCCCCCCCCCBB BBBCDDDDDDDDDDEEEEFFH GFFEEDDDCCCCCCCCCCCCCBB BBCCDDDDDDDDDEEEEGGHI HGFFEDDDCCCCCCCCCCCCCCB BBCDDDDDDDDEEEEFG HIGEDDDCCCCCCCCCCCCCB BBDDDDDDDDEEFFFGH IEDDDDCCCCCCCCCCCCB BCDDDDDDEEFFFFGG GFEDDDCCCCCCCCCCCCC BDDDDDEEFJGGGHHI IFEDDDDCCCCCCCCCCCC BDDEEEEFG J JI GEDDDDCCCCCCCCCCCC BDEEEFFFHJ FEDDDDCCCCCCCCCCCC BEEEFFFIJ FEEDDDCCCCCCCCCCCC BEEFGGH HFEEDDDCCCCCCCCCCCC JGFEEDDDDCCCCCCCCCCC BEEFGGH HFEEDDDCCCCCCCCCCCC BEEEFFFIJ FEEDDDCCCCCCCCCCCC BDEEEFFFHJ FEDDDDCCCCCCCCCCCC BDDEEEEFG J JI GEDDDDCCCCCCCCCCCC BDDDDDEEFJGGGHHI IFEDDDDCCCCCCCCCCCC BCDDDDDDEEFFFFGG GFEDDDCCCCCCCCCCCCC BBDDDDDDDDEEFFFGH IEDDDDCCCCCCCCCCCCB BBCDDDDDDDDEEEEFG HIGEDDDCCCCCCCCCCCCCB BBCCDDDDDDDDDEEEEGGHI HGFFEDDDCCCCCCCCCCCCCCB BBBCDDDDDDDDDDEEEEFFH GFFEEDDDCCCCCCCCCCCCCBB BBBCCDDDDDDDDDDEEEEFFH HFEEEDDDCCCCCCCCCCCCCCBB
J
The characteristic function of the Mandelbrot can be defined as follows:
mcf=. (<: 2:)@|@(] ((*:@] + [)^:((<: 2:)@|@])^:1000) 0:) NB. 1000 iterations test
The Mandelbrot set can be drawn as follows:
domain=. |.@|:@({.@[ + ] *~ j./&i.&>/@+.@(1j1 + ] %~ -~/@[))&>/
load 'viewmat'
viewmat mcf "0 @ domain (_2j_1 1j1) ; 0.01 NB. Complex interval and resolution
A smaller version, based on a black&white implementation of viewmat (and paraphrased, from html markup to wiki markup), is shown here (The output is HTML-heavy and was split out to make editing this page easier):
viewmat mcf "0 @ domain (_2j_1 1j1) ; 0.1 NB. Complex interval and resolution
Java
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);
}
}
Interactive
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)
;
}
}
JavaScript
This needs the canvas tag of HTML 5 (it will not run on IE8 and lower or old browsers).
The code can be run directly from the Javascript console in modern browsers by copying and pasting it.
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);
- Output:
with default parameters
ES6/WebAssembly
With ES6 and WebAssembly, the program can run faster. Of course, this requires a compiled WASM file, but one can easily build one for instance with the WebAssembly explorer
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);
// ...
}
jq
![](http://static.miraheze.org/rosettacodewiki/thumb/2/2a/Mandelbrot-Javascript.png/300px-Mandelbrot-Javascript.png)
The Mandelbrot function as defined here is similar to the JavaScript implementation but generates SVG. The resulting picture is the same.
Preliminaries
# 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;
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>";
Example:
Mandelbrot( {"xmin": -2, "xmax": 1, "ymin": -1, "ymax":1}; 900; 600; 1000 )
Execution:
$ jq -n -r -f mandelbrot.jq > mandelbrot.svg
The output can be viewed in a web browser such as Chrome, Firefox, or Safari.
Julia
Generates an ASCII representation:
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
This generates a PNG image file:
using Images
@inline function hsv2rgb(h, s, v)
c = v * s
x = c * (1 - abs(((h/60) % 2) - 1))
m = v - c
r,g,b = if h < 60 (c, x, 0)
elseif h < 120 (x, c, 0)
elseif h < 180 (0, c, x)
elseif h < 240 (0, x, c)
elseif h < 300 (x, 0, c)
else (c, 0, x) end
(r + m), (b + m), (g + m)
end
function mandelbrot()
w = 1600
h = 1200
zoom = 0.5
moveX = -0.5
moveY = 0
maxIter = 30
img = Array{RGB{Float64},2}(undef,h,w)
for x in 1:w
for y in 1:h
i = maxIter
z = c = Complex( (2*x - w) / (w * zoom) + moveX,
(2*y - h) / (h * zoom) + moveY )
while abs(z) < 2 && (i -= 1) > 0
z = z^2 + c
end
r,g,b = hsv2rgb(i / maxIter * 360, 1, i / maxIter)
img[y,x] = RGB{Float64}(r, g, b)
end
end
return img
end
img = mandelbrot()
save("mandelbrot.png", img)
Mandelbrot Set with Julia Animation
This is an extension of the corresponding R section: e^(-|z|)-smoothing was added. See Javier Barrallo & Damien M. Jones: Coloring Algorithms for Dynamical Systems in the Complex Plane (II. Distance Estimators).
using Plots
gr(aspect_ratio=:equal, legend=false, axis=false, ticks=false, dpi=100)
d, h = 400, 300 # pixel density (= image width) and image height
n, r = 40, 1000 # number of iterations and escape radius (r > 2)
x = range(-1.0, 1.0, length=d+1)
y = range(-h/d, h/d, length=h+1)
C = 2.0 .* (x' .+ y .* im) .- 0.5
Z, S = zero(C), zeros(size(C))
animation = Animation()
smoothing = Animation()
for k in 1:n
M = abs.(Z) .< r
S[M] = S[M] .+ exp.(.-abs.(Z[M]))
Z[M] = Z[M] .^ 2 .+ C[M]
heatmap(exp.(.-abs.(Z)), c=:jet)
frame(animation)
heatmap(S .+ exp.(.-abs.(Z)), c=:jet)
frame(smoothing)
end
gif(animation, "Mandelbrot_animation.gif", fps=2)
gif(smoothing, "Mandelbrot_smoothing.gif", fps=2)
Normal Map Effect, Mercator Projection and Perturbation Theory
Normalization, Distance Estimation and Boundary Detection
This is a translation of the corresponding Python section: see there for more explanations. The e^(-|z|)-smoothing, normalized iteration count and exterior distance estimation algorithms are used. Partial antialiasing is used for boundary detection.
using Plots
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
d, h = 800, 500 # pixel density (= image width) and image height
n, r = 200, 500 # number of iterations and escape radius (r > 2)
x = range(0, 2, length=d+1)
y = range(0, 2 * h / d, length=h+1)
A, B = collect(x) .- 1, collect(y) .- h / d
C = 2.0 .* (A' .+ B .* im) .- 0.5
Z, dZ = zero(C), zero(C)
D, S, T = zeros(size(C)), zeros(size(C)), zeros(size(C))
for k in 1:n
M = abs.(Z) .< r
S[M], T[M] = S[M] .+ exp.(.- abs.(Z[M])), T[M] .+ 1
Z[M], dZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1
end
heatmap(S .^ 0.1, c=:balance)
savefig("Mandelbrot_set_1.png")
N = abs.(Z) .>= r # normalized iteration count
T[N] = T[N] .- log2.(log.(abs.(Z[N])) ./ log(r))
heatmap(T .^ 0.1, c=:balance)
savefig("Mandelbrot_set_2.png")
N = abs.(Z) .> 2 # exterior distance estimation
D[N] = log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N])
heatmap(D .^ 0.1, c=:balance)
savefig("Mandelbrot_set_3.png")
N, thickness = D .> 0, 0.01 # boundary detection
D[N] = max.(1 .- D[N] ./ thickness, 0)
heatmap(D .^ 2.0, c=:binary)
savefig("Mandelbrot_set_4.png")
Normal Map Effect and Stripe Average Coloring
The Mandelbrot set is represented using Normal Maps and Stripe Average Coloring by Jussi Härkönen (cf. Arnaud Chéritat: Normal map effect). See also the picture in section Mixing it all and Julia Stripes on Shadertoy. To get a stripe pattern similar to that of Arnaud Chéritat, one can increase the density of the stripes, use cos instead of sin, and set the colormap to binary.
using Plots
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
d, h = 800, 500 # pixel density (= image width) and image height
n, r = 200, 500 # number of iterations and escape radius (r > 2)
direction, height = 45.0, 1.5 # direction and height of the light
density, intensity = 4.0, 0.5 # density and intensity of the stripes
x = range(0, 2, length=d+1)
y = range(0, 2 * h / d, length=h+1)
A, B = collect(x) .- 1, collect(y) .- h / d
C = (2.0 + 1.0im) .* (A' .+ B .* im) .- 0.5
Z, dZ, ddZ = zero(C), zero(C), zero(C)
D, S, T = zeros(size(C)), zeros(size(C)), zeros(size(C))
for k in 1:n
M = abs.(Z) .< r
S[M], T[M] = S[M] .+ sin.(density .* angle.(Z[M])), T[M] .+ 1
Z[M], dZ[M], ddZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1, 2 .* (dZ[M] .^ 2 .+ Z[M] .* ddZ[M])
end
N = abs.(Z) .>= r # basic normal map effect and stripe average coloring (potential function)
P, Q = S[N] ./ T[N], (S[N] .+ sin.(density .* angle.(Z[N]))) ./ (T[N] .+ 1)
U, V = Z[N] ./ dZ[N], 1 .+ (log2.(log.(abs.(Z[N])) ./ log(r)) .* (P .- Q) .+ Q) .* intensity
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit normal vectors and light vector
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ V .* height) ./ (1 + height), 0)
heatmap(D .^ 1.0, c=:bone_1)
savefig("Mandelbrot_normal_map_1.png")
N = abs.(Z) .> 2 # advanced normal map effect using higher derivatives (distance estimation)
U = Z[N] .* dZ[N] .* ((1 .+ log.(abs.(Z[N]))) .* conj.(dZ[N] .^ 2) .- log.(abs.(Z[N])) .* conj.(Z[N] .* ddZ[N]))
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit normal vectors and light vector
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ height) ./ (1 + height), 0)
heatmap(D .^ 1.0, c=:afmhot)
savefig("Mandelbrot_normal_map_2.png")
Mercator Mandelbrot Maps and Zoom Images
A small change in the code above creates Mercator maps and zoom images of the Mandelbrot set. See also the album Mercator Mandelbrot Maps by Anders Sandberg and Mandelbrot sequence new on Wikimedia for a zoom animation to the given coordinates.
using Plots
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
d, h = 200, 1200 # pixel density (= image width) and image height
n, r = 8000, 10000 # number of iterations and escape radius (r > 2)
a = -.743643887037158704752191506114774 # https://mathr.co.uk/web/m-location-analysis.html
b = 0.131825904205311970493132056385139 # try: a, b, n = -1.748764520194788535, 3e-13, 800
x = range(0, 2, length=d+1)
y = range(0, 2 * h / d, length=h+1)
A, B = collect(x) .* pi, collect(y) .* pi
C = 8.0 .* exp.((A' .+ B .* im) .* im) .+ (a + b * im)
Z, dZ = zero(C), zero(C)
D = zeros(size(C))
for k in 1:n
M = abs2.(Z) .< abs2(r)
Z[M], dZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1
end
N = abs.(Z) .> 2 # exterior distance estimation
D[N] = log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N])
heatmap(D' .^ 0.05, c=:nipy_spectral)
savefig("Mercator_Mandelbrot_map.png")
X, Y = real(C), imag(C) # zoom images (adjust circle size 50 and zoom level 20 as needed)
R, c, z = 50 * (2 / d) * pi .* exp.(.- B), min(d, h) + 1, max(0, h - d) ÷ 20
gr(c=:nipy_spectral, axis=true, ticks=true, legend=false, markerstrokewidth=0)
p1 = scatter(X[1z+1:1z+c,1:d], Y[1z+1:1z+c,1:d], markersize=R[1:c].^.5, marker_z=D[1z+1:1z+c,1:d].^.5)
p2 = scatter(X[2z+1:2z+c,1:d], Y[2z+1:2z+c,1:d], markersize=R[1:c].^.5, marker_z=D[2z+1:2z+c,1:d].^.4)
p3 = scatter(X[3z+1:3z+c,1:d], Y[3z+1:3z+c,1:d], markersize=R[1:c].^.5, marker_z=D[3z+1:3z+c,1:d].^.3)
p4 = scatter(X[4z+1:4z+c,1:d], Y[4z+1:4z+c,1:d], markersize=R[1:c].^.5, marker_z=D[4z+1:4z+c,1:d].^.2)
plot(p1, p2, p3, p4, layout=(2, 2))
savefig("Mercator_Mandelbrot_zoom.png")
Perturbation Theory and Deep Mercator Maps
For deep zoom images it is sufficient to calculate a single point with high accuracy. A good approximation can then be found for all other points by means of a perturbation calculation with standard accuracy. Rebasing is used to reduce glitches. See Another solution to perturbation glitches (Fractalforums) for details. See also the image Deeper Mercator Mandelbrot by Anders Sandberg.
using Plots
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
setprecision(BigFloat, 256) # set precision to 256 bits (default)
setrounding(BigFloat, RoundNearest) # set rounding mode (default)
d, h = 50, 1000 # pixel density (= image width) and image height
n, r = 80000, 100000 # number of iterations and escape radius (r > 2)
a = BigFloat("-1.256827152259138864846434197797294538253477389787308085590211144291")
b = BigFloat(".37933802890364143684096784819544060002129071484943239316486643285025")
S = zeros(Complex{Float64}, n+1)
let c = a + b * im, z = zero(c)
for k in 1:n+1
S[k] = z
if abs2(z) < abs2(r)
z = z ^ 2 + c
else
println("The reference sequence diverges within $(k-1) iterations.")
break
end
end
end
x = range(0, 2, length=d+1)
y = range(0, 2 * h / d, length=h+1)
A, B = collect(x) .* pi, collect(y) .* pi
C = 8.0 .* exp.((A' .+ B .* im) .* im)
E, Z, dZ = zero(C), zero(C), zero(C)
D, I, J = zeros(size(C)), ones(Int64, size(C)), ones(Int64, size(C))
for k in 1:n
M, R = abs2.(Z) .< abs2(r), abs2.(Z) .< abs2.(E)
E[R], I[R] = Z[R], J[R] # rebase when z is closer to zero
E[M], I[M] = (2 .* S[I[M]] .+ E[M]) .* E[M] .+ C[M], I[M] .+ 1
Z[M], dZ[M] = S[I[M]] .+ E[M], 2 .* Z[M] .* dZ[M] .+ 1
end
N = abs.(Z) .> 2 # exterior distance estimation
D[N] = log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N])
heatmap(D' .^ 0.015, c=:nipy_spectral)
savefig("Mercator_Mandelbrot_deep_map.png")
Kotlin
// version 1.1.2
import java.awt.Graphics
import java.awt.image.BufferedImage
import javax.swing.JFrame
class Mandelbrot: JFrame("Mandelbrot Set") {
companion object {
private const val MAX_ITER = 570
private const val ZOOM = 150.0
}
private val img: BufferedImage
init {
setBounds(100, 100, 800, 600)
isResizable = false
defaultCloseOperation = EXIT_ON_CLOSE
img = BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)
for (y in 0 until height) {
for (x in 0 until width) {
var zx = 0.0
var zy = 0.0
val cX = (x - 400) / ZOOM
val cY = (y - 300) / ZOOM
var iter = MAX_ITER
while (zx * zx + zy * zy < 4.0 && iter > 0) {
val tmp = zx * zx - zy * zy + cX
zy = 2.0 * zx * zy + cY
zx = tmp
iter--
}
img.setRGB(x, y, iter or (iter shl 7))
}
}
}
override fun paint(g: Graphics) {
g.drawImage(img, 0, 0, this)
}
}
fun main(args: Array<String>) {
Mandelbrot().isVisible = true
}
LabVIEW
Lang5
: d2c(*,*) 2 compress 'c dress ; # Make a complex number.
: iterate(c) [0 0](c) "dup * over +" steps reshape execute ;
: print_line(*) "#*+-. " "" split swap subscript "" join . "\n" . ;
75 iota 45 - 20 / # x coordinates
29 iota 14 - 10 / # y cordinates
'd2c outer # Make complex matrix.
10 'steps set # How many iterations?
iterate abs int 5 min 'print_line apply # Compute & print
Lambdatalk
Lambdatalk working in any web browser has access to javascript and could draw the mandelbrot set very quickly in a canvas, for instance here: - http: // lambdaway.free.fr/lambdawalks/?view=mandel_canvas
Here we show a pure lambdatalk code, a slow but minimalistic and easy to understand version without the burden of any canvas. We just compute if a point is inside or outside the mandelbrot set and just write "o" or "." directly in the wiki page.
{def mandel
{def mandel.r
{lambda {:iter :cx :cy :norm :x :y :count}
{if {> :count :iter} // then norm < 4
then o // inside the set
else {if {> :norm 4} // then iter > max
then . // outside the set
else {let { {:cx :cx} {:cy :cy} {:iter :iter}
{:X {+ {* :x :x} -{* :y :y} :cx}} // compute
{:Y {+ {* 2 :x :y} :cy}} // z = z^2+c
{:count {+ :count 1}}
} {mandel.r :iter :cx :cy
{+ {* :X :X} {* :Y :Y}} // the norm
:X :Y :count} }}}}}
{lambda {:iter :cx :cy}
{mandel.r :iter
{+ {* :cx 0.05} -1.50} // centering the set
{+ {* :cy 0.05} -0.75} // inside the frame
0 0 0 0} }}
-> mandel
We call mandel directly in the wiki page
{S.map {lambda {:i} {br} // loop on y
{S.map {{lambda {:i :j} // loop on x
{mandel 20 :i :j}} :i} // compute
{S.serie 0 30}}} // x resolution
{S.serie 0 40}} // y resolution
. . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o o o . . . . . . . . . . . . . . . . . . . . . . . . . . . . o o o . . . . . . . . . . . . . . . . . . . . . . . . . . . o o o o o . . . . . . . . . . . . . . . . . . . . . . . . . o o o o o o o . . . . . . . . . . . . . . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . . . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . . . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . . . . . . . . . . o o o o o o o o o o o o o . . . . . . . . . . . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . . . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . . . . . . . . . . . . o o o o o o o o o . . . . . . . . . . . . . . . . . . . . . . . o o o o o o o . . . . . . . . . . . . . . . . . . . . . . . . o o o o o o o . . . . . . . . . . . . . . . . . . o . o o o o o o o o o o o o o o o . o . . . . . . . . . . . . o . o o o o o o o o o o o o o o o . o . . . . . . . . . . . . o o o o o o o o o o o o o o o o o o o . . . . . . . . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . . . . o o o o o o o o o o o o o o o o o o o o o o o o o . . . . . . . o o o o o o o o o o o o o o o o o o o o o o o . . . . . . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . . . . o o o o o o o o o o o o o o o o o o o o o o o o o . . . . . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . o . o o o o o o o o o o o o o o o o o o o o o o o o o o o . o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o . o o o o o o o o o o o o o o o o o o o o o o o o o o o . o . . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . . . . o o o o o o o o o o o o o o o o o o o o o o o o o . . . . . o . o o o o o o o o o o o o o o o o o o o o o o o . o . . . . . . o o o o o o o o o o o o o o o o o o o o o o o . . . . . . . . o o o o o o o o o o o o o o o o o o o o o o o . . . . . . . . o o o o o o o o o o o . o o o o o o o o o o o . . . . . . . . o . . . o o o o o o . . . o o o o o o . . . o . . . . . . . . . . . . o . . o o . . . . . o o . . o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Lasso
define mandelbrotBailout => 16
define mandelbrotMaxIterations => 1000
define mandelbrotIterate(x, y) => {
local(cr = #y - 0.5,
ci = #x,
zi = 0.0,
zr = 0.0,
i = 0,
temp, zr2, zi2)
{
++#i;
#temp = #zr * #zi
#zr2 = #zr * #zr
#zi2 = #zi * #zi
#zi2 + #zr2 > mandelbrotBailout?
return #i
#i > mandelbrotMaxIterations?
return 0
#zr = #zr2 - #zi2 + #cr
#zi = #temp + #temp + #ci
currentCapture->restart
}()
}
define mandelbrotTest() => {
local(x, y = -39.0)
{
stdout('\n')
#x = -39.0
{
mandelbrotIterate(#x / 40.0, #y / 40.0) == 0?
stdout('*')
| stdout(' ');
++#x
#x <= 39.0?
currentCapture->restart
}();
++#y
#y <= 39.0?
currentCapture->restart
}()
stdout('\n')
}
mandelbrotTest
- Output:
* * * * * *** ***** ***** *** * ********* ************* *************** ********************* ********************* ******************* ******************* ******************* ******************* *********************** ******************* ******************* ********************* ******************* ******************* ***************** *************** ************* ********* * *************** *********************** * ************************* * ***************************** * ******************************* * ********************************* *********************************** *************************************** *** ***************************************** *** ************************************************* *********************************************** ********************************************* ********************************************* *********************************************** *********************************************** *************************************************** ************************************************* ************************************************* *************************************************** *************************************************** * *************************************************** * ***** *************************************************** ***** ****** *************************************************** ****** ******* *************************************************** ******* *********************************************************************** ********* *************************************************** ********* ****** *************************************************** ****** ***** *************************************************** ***** *************************************************** *************************************************** *************************************************** *************************************************** ************************************************* ************************************************* *************************************************** *********************************************** *********************************************** ******************************************* ***************************************** ********************************************* **** ****************** ****************** **** *** **************** **************** *** * ************** ************** * *********** *********** ** ***** ***** ** * * * *
LIL
From the source distribution. Produces a PBM, not shown here.
#
# A mandelbrot generator that outputs a PBM file. This can be used to measure
# performance differences between LIL versions and measure performance
# bottlenecks (although keep in mind that LIL is not supposed to be a fast
# language, but a small one which depends on C for the slow parts - in a real
# program where for some reason mandelbrots are required, the code below would
# be written in C). The code is based on the mandelbrot test for the Computer
# Language Benchmarks Game at http://shootout.alioth.debian.org/
#
# In my current computer (Intel Core2Quad Q9550 @ 2.83GHz) running x86 Linux
# the results are (using the default 256x256 size):
#
# 2m3.634s - commit 1c41cdf89f4c1e039c9b3520c5229817bc6274d0 (Jan 10 2011)
#
# To test call
#
# time ./lil mandelbrot.lil > mandelbrot.pbm
#
# with an optimized version of lil (compiled with CFLAGS=-O3 make).
#
set width [expr $argv]
if not $width { set width 256 }
set height $width
set bit_num 0
set byte_acc 0
set iter 50
set limit 2.0
write "P4\n${width} ${height}\n"
for {set y 0} {$y < $height} {inc y} {
for {set x 0} {$x < $width} {inc x} {
set Zr 0.0 Zi 0.0 Tr 0.0 Ti 0.0
set Cr [expr 2.0 * $x / $width - 1.5]
set Ci [expr 2.0 * $y / $height - 1.0]
for {set i 0} {$i < $iter && $Tr + $Ti <= $limit * $limit} {inc i} {
set Zi [expr 2.0 * $Zr * $Zi + $Ci]
set Zr [expr $Tr - $Ti + $Cr]
set Tr [expr $Zr * $Zr]
set Ti [expr $Zi * $Zi]
}
set byte_acc [expr $byte_acc << 1]
if [expr $Tr + $Ti <= $limit * $limit] {
set byte_acc [expr $byte_acc | 1]
}
inc bit_num
if [expr $bit_num == 8] {
writechar $byte_acc
set byte_acc 0
set bit_num 0
} {if [expr $x == $width - 1] {
set byte_acc [expr 8 - $width % 8]
writechar $byte_acc
set byte_acc 0
set bit_num 0
}}
}
}
Logo
to mandelbrot :left :bottom :side :size
cs setpensize [1 1]
make "inc :side/:size
make "zr :left
repeat :size [
make "zr :zr + :inc
make "zi :bottom
pu
setxy repcount - :size/2 minus :size/2
pd
repeat :size [
make "zi :zi + :inc
setpencolor count.color calc :zr :zi
fd 1 ] ]
end
to count.color :count
;op (list :count :count :count)
if :count > 256 [op 0] ; black
if :count > 128 [op 7] ; white
if :count > 64 [op 5] ; magenta
if :count > 32 [op 6] ; yellow
if :count > 16 [op 4] ; red
if :count > 8 [op 2] ; green
if :count > 4 [op 1] ; blue
op 3 ; cyan
end
to calc :zr :zi [:count 0] [:az 0] [:bz 0]
if :az*:az + :bz*:bz > 4 [op :count]
if :count > 256 [op :count]
op (calc :zr :zi (:count + 1) (:zr + :az*:az - :bz*:bz) (:zi + 2*:az*:bz))
end
mandelbrot -2 -1.25 2.5 400
Lua
Graphical
Needs LÖVE 2D Engine
Zoom in: drag the mouse; zoom out: right click
local maxIterations = 250
local minX, maxX, minY, maxY = -2.5, 2.5, -2.5, 2.5
local miX, mxX, miY, mxY
function remap( x, t1, t2, s1, s2 )
local f = ( x - t1 ) / ( t2 - t1 )
local g = f * ( s2 - s1 ) + s1
return g;
end
function drawMandelbrot()
local pts, a, as, za, b, bs, zb, cnt, clr = {}
for j = 0, hei - 1 do
for i = 0, wid - 1 do
a = remap( i, 0, wid, minX, maxX )
b = remap( j, 0, hei, minY, maxY )
cnt = 0; za = a; zb = b
while( cnt < maxIterations ) do
as = a * a - b * b; bs = 2 * a * b
a = za + as; b = zb + bs
if math.abs( a ) + math.abs( b ) > 16 then break end
cnt = cnt + 1
end
if cnt == maxIterations then clr = 0
else clr = remap( cnt, 0, maxIterations, 0, 255 )
end
pts[1] = { i, j, clr, clr, 0, 255 }
love.graphics.points( pts )
end
end
end
function startFractal()
love.graphics.setCanvas( canvas ); love.graphics.clear()
love.graphics.setColor( 255, 255, 255 )
drawMandelbrot(); love.graphics.setCanvas()
end
function love.load()
wid, hei = love.graphics.getWidth(), love.graphics.getHeight()
canvas = love.graphics.newCanvas( wid, hei )
startFractal()
end
function love.mousepressed( x, y, button, istouch )
if button == 1 then
startDrag = true; miX = x; miY = y
else
minX = -2.5; maxX = 2.5; minY = minX; maxY = maxX
startFractal()
startDrag = false
end
end
function love.mousereleased( x, y, button, istouch )
if startDrag then
local l
if x > miX then mxX = x
else l = x; mxX = miX; miX = l
end
if y > miY then mxY = y
else l = y; mxY = miY; miY = l
end
miX = remap( miX, 0, wid, minX, maxX )
mxX = remap( mxX, 0, wid, minX, maxX )
miY = remap( miY, 0, hei, minY, maxY )
mxY = remap( mxY, 0, hei, minY, maxY )
minX = miX; maxX = mxX; minY = miY; maxY = mxY
startFractal()
end
end
function love.draw()
love.graphics.draw( canvas )
end
ASCII
-- Mandelbrot set in Lua 6/15/2020 db
local charmap = { [0]=" ", ".", ":", "-", "=", "+", "*", "#", "%", "@" }
for y = -1.3, 1.3, 0.1 do
for x = -2.1, 1.1, 0.04 do
local zi, zr, i = 0, 0, 0
while i < 100 do
if (zi*zi+zr*zr >= 4) then break end
zr, zi, i = zr*zr-zi*zi+x, 2*zr*zi+y, i+1
end
io.write(charmap[i%10])
end
print()
end
- Output:
...............::::::::::::::::::---------------:::::::::::::::::::::::::::::::: .............:::::::::::---------------------------------::::::::::::::::::::::: ...........::::::::---------------------======+#@#++=====-----:::::::::::::::::: ..........::::::--------------------=======+++**@+@.@*+=====-----::::::::::::::: ........:::::--------------------========++++*#@@#=:%#*++=====------:::::::::::: .......:::--------------------========+++***#%: .:#*+++++===-------::::::::: ......:::------------------=======+++#%@%%%@@ :# %.@@%#***%*+==------:::::::: .....::-----------------====++++++**# = =% %-.*+=#%+==-------:::::: .....:--------------==+++++++++****%:.*+ *%*++==-------::::: ....:--------=====+*#=%##########%%.** .@ +===-------:::: ....---========++++*#@:=*:-@+ .@@ := @ #*===--------::: ...--=======+++++*##%.=: @+. @##+====--------:: ...=======****##% .-=% *#*+====--------:: ...@.:: :: % :@#*++====--------:: ...=======****##% .-=% *#*+====--------:: ...--=======+++++*##%.=: @+. @##+====--------:: ....---========++++*#@:=*:-@+ .@@ := @ #*===--------::: ....:--------=====+*#=%##########%%.** .@ +===-------:::: .....:--------------==+++++++++****%:.*+ *%*++==-------::::: .....::-----------------====++++++**# = =% %-.*+=#%+==-------:::::: ......:::------------------=======+++#%@%%%@@ :# %.@@%#***%*+==------:::::::: .......:::--------------------========+++***#%: .:#*+++++===-------::::::::: ........:::::--------------------========++++*#@@#=:%#*++=====------:::::::::::: ..........::::::--------------------=======+++**@+@.@*+=====-----::::::::::::::: ...........::::::::---------------------======+#@#++=====-----:::::::::::::::::: .............:::::::::::---------------------------------::::::::::::::::::::::: ...............::::::::::::::::::---------------::::::::::::::::::::::::::::::::
ASCII (obfuscated)
Produces an 80x25 ASCII Mandelbrot set, using only two lines of code. The result isn't very high quality because there's only so many iterations you can cram into two lines of 80 columns. And this code cheats, because it starts the iteration count at -15 instead of 0, to avoid the need for an excessively long character lookup table.
for y=-12,12 do l=""for x=-2,1,3/80 do a,b,n=0,0,-15 while n<9 and a*a+b*b<1e12
do a,b,n=a*a-b*b+x,2*a*b+y/8,n+1 end l=l..(".,:;=$%# "):sub(n,n)end print(l)end
- Output:
............................................,,,,,,,,............................ .................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,................... .........................,,,,,,,,,,,,,,,,,,,,,,::::,,,,,,,,,,,,,,,.............. ...................,,,,,,,,,,,,,,,,,,,,,::::::;=$=;;::::::,,,,,,,,,,,,.......... ..............,,,,,,,,,,,,,,,,,,,,:::::::::;;;==% :#=;;:::::,,,,,,,,,,,....... .........,,,,,,,,,,,,,,,,,,,,:::::::::;;;;;==$%;; ,##==;;;::::::,,,,,,,,,..... .....,,,,,,,,,,,,,,,,,:::::::::::;;;;====$$$%#: %$$===;;;;::::,,,,,,,,... ..,,,,,,,,,,,,,,::::::::::::;;;;;;==$ , .#% #=;:::,,,,,,,,,. ,,,,,,,,,,,,::::::;;;;;;;;;;=====$$#:. $=;;::::,,,,,,,, ,,,,,,,,:::::::;;;=%:%%%%%=%%%%%%# $ $;;:::,,,,,,,, ,,,,:::::::;;;;===$%#: ,.. :,=;;::::,,,,,,, ::::;;;;;;====$# ..# ;$=;;::::,,,,,,, ; %$=;;;::::,,,,,,, ::::;;;;;;====$# ..# ;$=;;::::,,,,,,, ,,,,:::::::;;;;===$%#: ,.. :,=;;::::,,,,,,, ,,,,,,,,:::::::;;;=%:%%%%%=%%%%%%# $ $;;:::,,,,,,,, ,,,,,,,,,,,,::::::;;;;;;;;;;=====$$#:. $=;;::::,,,,,,,, ..,,,,,,,,,,,,,,::::::::::::;;;;;;==$ , .#% #=;:::,,,,,,,,,. .....,,,,,,,,,,,,,,,,,:::::::::::;;;;====$$$%#: %$$===;;;;::::,,,,,,,,... .........,,,,,,,,,,,,,,,,,,,,:::::::::;;;;;==$%;; ,##==;;;::::::,,,,,,,,,..... ..............,,,,,,,,,,,,,,,,,,,,:::::::::;;;==% :#=;;:::::,,,,,,,,,,,....... ...................,,,,,,,,,,,,,,,,,,,,,::::::;=$=;;::::::,,,,,,,,,,,,.......... .........................,,,,,,,,,,,,,,,,,,,,,,::::,,,,,,,,,,,,,,,.............. .................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,................... ............................................,,,,,,,,............................
M2000 Interpreter
Console is a bitmap so we can plot on it. A subroutine plot different size of pixels so we get Mandelbrot image at final same size for 32X26 for a big pixel of 16x16 pixels to 512x416 for a 1:1 pixel. Iterations for each pixel set to 25. Module can get left top corner as twips, and the size factor from 1 to 16 (size of output is 512x416 pixels for any factor).
Module Mandelbrot(x=0&,y=0&,z=1&) {
If z<1 then z=1
If z>16 then z=16
Const iXmax=32*z
Const iYmax=26*z
Def single Cx, Cy, CxMin=-2.05, CxMax=0.85, CyMin=-1.2, CyMax=1.2
Const PixelWidth=(CxMax-CxMin)/iXmax, iXm=(iXmax-1)*PixelWidth
Const PixelHeight=(CyMax-CyMin)/iYmax,Ph2=PixelHeight/2
Const Iteration=25
Const EscRadious=2.5, ER2=EscRadious**2
Def single preview
preview=iXmax*twipsX*(z/16)
Def long yp, xp, dx, dy, dx1, dy1
Let dx=twipsx*(16/z), dx1=dx-1
Let dy=twipsy*(16/z), dy1=dy-1
yp=y
For iY=0 to (iYmax-1)*PixelHeight step PixelHeight {
Cy=CyMin+iY
xp=x
if abs(Cy)<Ph2 Then Cy=0
For iX=0 to iXm Step PixelWidth {
Let Cx=CxMin+iX,Zx=0,Zy=0,Zx2=0,Zy2=0
For It=Iteration to 1 {Let Zy=2*Zx*Zy+Cy,Zx=Zx2-Zy2+Cx,Zx2=Zx**2,Zy2=Zy**2 :if Zx2+Zy2>ER2 Then exit
}
if it>13 then {it-=13} else.if it=0 then SetPixel(xp,yp,0): xp+=dx : continue
it*=10:SetPixel(xp,yp,color(it, it,255)) :xp+=dx
} : yp+=dy
}
Sub SetPixel()
move number, number: fill dx1, dy1, number
End Sub
}
Cls 1,0
sz=(1,2,4,8,16)
i=each(sz)
While i {
Mandelbrot 250*twipsx,100*twipsy, array(i)
}
Version 2 without Subroutine. Also there is a screen refresh every 2 seconds.
Module Mandelbrot(x=0&,y=0&,z=1&) {
If z<1 then z=1
If z>16 then z=16
Const iXmax=32*z
Const iYmax=26*z
Def single Cx, Cy, CxMin=-2.05, CxMax=0.85, CyMin=-1.2, CyMax=1.2
Const PixelWidth=(CxMax-CxMin)/iXmax, iXm=(iXmax-1)*PixelWidth
Const PixelHeight=(CyMax-CyMin)/iYmax,Ph2=PixelHeight/2
Const Iteration=25
Const EscRadious=2.5, ER2=EscRadious**2
Def single preview
preview=iXmax*twipsX*(z/16)
Def long yp, xp, dx, dy, dx1, dy1
Let dx=twipsx*(16/z), dx1=dx-1
Let dy=twipsy*(16/z), dy1=dy-1
yp=y
Refresh 2000
For iY=0 to (iYmax-1)*PixelHeight step PixelHeight {
Cy=CyMin+iY
xp=x
if abs(Cy)<Ph2 Then Cy=0
move xp, yp
For iX=0 to iXm Step PixelWidth {
Let Cx=CxMin+iX,Zx=0,Zy=0,Zx2=0,Zy2=0
For It=Iteration to 1 {Let Zy=2*Zx*Zy+Cy,Zx=Zx2-Zy2+Cx,Zx2=Zx**2,Zy2=Zy**2 :if Zx2+Zy2>ER2 Then exit
}
if it>13 then {it-=13} else.if it=0 then fill dx1, dy1, 0: Step 0,-dy1: continue
it*=10:fill dx1, dy1, color(it, it,255): Step 0,-dy1
} : yp+=dy
}
}
Cls 1,0
sz=(1,2,4,8,16)
i=each(sz)
While i {
Mandelbrot 250*twipsx,100*twipsy, array(i)
}
M4
The following m4 code is not optimized very well, but it works. It is actually output from a program I call vmc, which translates output from the code generator task to different languages. The Mandelbrot set algorithm from the test set for that task. The vmc program itself is written in ATS, and the m4 it generates should run in any POSIX-compliant m4 (if not others as well). For very old m4 implementations, one might need to use an option such as -S 1000
to set the stack size larger than the default.
There are two data structures employed:
- A FORTH-like data stack, an example of which would be
789:456:123:stack-bottom
- A list of variables, such as
var0:123:var1:456:var2:789:
There are macros to do calculations with the stack. There are also macros to fetch
and store
the values of variables, which are referenced by name.
One might enjoy even manually writing m4 code using such structures. However, the big mutual recursion that is the core of the program probably is not how one would write code manually.
(None of the above involves m4's notorious trickery with commas.)
divert(-1)
changecom
define(`newline',`
')
define(`leftquote',`[')
define(`rightquote',`]')
changequote(`[',`]')
define([print_char],
[ifelse(
$1,0,[*],
$1,1,[*],
$1,2,[*],
$1,3,[*],
$1,4,[*],
$1,5,[*],
$1,6,[*],
$1,7,[*],
$1,8,[*],
$1,9,[*],
$1,10,[newline],
$1,11,[*],
$1,12,[*],
$1,13,[*],
$1,14,[*],
$1,15,[*],
$1,16,[*],
$1,17,[*],
$1,18,[*],
$1,19,[*],
$1,20,[*],
$1,21,[*],
$1,22,[*],
$1,23,[*],
$1,24,[*],
$1,25,[*],
$1,26,[*],
$1,27,[*],
$1,28,[*],
$1,29,[*],
$1,30,[*],
$1,31,[*],
$1,32,[ ],
$1,33,[!],
$1,34,["],
$1,35,[#],
$1,36,[$],
$1,37,[%],
$1,38,[&],
$1,39,['],
$1,40,[(],
$1,41,[)],
$1,42,[*],
$1,43,[+],
$1,44,[,],
$1,45,[-],
$1,46,[.],
$1,47,[/],
$1,48,[0],
$1,49,[1],
$1,50,[2],
$1,51,[3],
$1,52,[4],
$1,53,[5],
$1,54,[6],
$1,55,[7],
$1,56,[8],
$1,57,[9],
$1,58,[:],
$1,59,[;],
$1,60,[<],
$1,61,[=],
$1,62,[>],
$1,63,[?],
$1,64,[@],
$1,65,[A],
$1,66,[B],
$1,67,[C],
$1,68,[D],
$1,69,[E],
$1,70,[F],
$1,71,[G],
$1,72,[H],
$1,73,[I],
$1,74,[J],
$1,75,[K],
$1,76,[L],
$1,77,[M],
$1,78,[N],
$1,79,[O],
$1,80,[P],
$1,81,[Q],
$1,82,[R],
$1,83,[S],
$1,84,[T],
$1,85,[U],
$1,86,[V],
$1,87,[W],
$1,88,[X],
$1,89,[Y],
$1,90,[Z],
$1,91,[changequote([`],['])leftquote`'changequote(`[',`]')],
$1,92,[\],
$1,93,[rightquote],
$1,94,[^],
$1,95,[_],
$1,96,[`],
$1,97,[a],
$1,98,[b],
$1,99,[c],
$1,100,[d],
$1,101,[e],
$1,102,[f],
$1,103,[g],
$1,104,[h],
$1,105,[i],
$1,106,[j],
$1,107,[k],
$1,108,[l],
$1,109,[m],
$1,110,[n],
$1,111,[o],
$1,112,[p],
$1,113,[q],
$1,114,[r],
$1,115,[s],
$1,116,[t],
$1,117,[u],
$1,118,[v],
$1,119,[w],
$1,120,[x],
$1,121,[y],
$1,122,[z],
$1,123,[{],
$1,124,[|],
$1,125,[}],
$1,126,[~],
[*])])
define([stack_1st],[substr([$1],0,index([$1],[:]))])
define([stack_2nd],[stack_1st(stack_drop([$1]))])
define([stack_drop],[substr([$1],eval(index([$1],[:]) [+ 1]))])
define([stack_drop2],[stack_drop(stack_drop([$1]))])
define([stack_not],[eval(stack_1st([$1]) [== 0]):stack_drop([$1])])
define([stack_neg],[eval([-] stack_1st([$1])):stack_drop([$1])])
define([stack_and],[eval(stack_2nd([$1] [!= 0]) [&&] stack_1st([$1] [!= 0])):stack_drop2([$1])])
define([stack_or],[eval(stack_2nd([$1] [!= 0]) [||] stack_1st([$1] [!= 0])):stack_drop2([$1])])
define([stack_lt],[eval(stack_2nd([$1]) [<] stack_1st([$1])):stack_drop2([$1])])
define([stack_le],[eval(stack_2nd([$1]) [<=] stack_1st([$1])):stack_drop2([$1])])
define([stack_gt],[eval(stack_2nd([$1]) [>] stack_1st([$1])):stack_drop2([$1])])
define([stack_ge],[eval(stack_2nd([$1]) [>=] stack_1st([$1])):stack_drop2([$1])])
define([stack_eq],[eval(stack_2nd([$1]) [==] stack_1st([$1])):stack_drop2([$1])])
define([stack_ne],[eval(stack_2nd([$1]) [!=] stack_1st([$1])):stack_drop2([$1])])
define([stack_add],[eval(stack_2nd([$1]) [+] stack_1st([$1])):stack_drop2([$1])])
define([stack_sub],[eval(stack_2nd([$1]) [-] stack_1st([$1])):stack_drop2([$1])])
define([stack_mul],[eval(stack_2nd([$1]) [*] stack_1st([$1])):stack_drop2([$1])])
define([stack_div],[eval(stack_2nd([$1]) [/] stack_1st([$1])):stack_drop2([$1])])
define([stack_mod],[eval(stack_2nd([$1]) [%] stack_1st([$1])):stack_drop2([$1])])
define([prtc_1st],[print_char(stack_1st([$1]))])
define([prti_1st],[stack_1st([$1])])
define([prts_1st],[print_string(stack_1st([$1]))])
define([store],[define([_tmp1],index([$2],[$1:]))[]substr([$2],0,_tmp1)[$1:$3]define([_tmp2],substr([$2],eval(_tmp1 + len([$1]) [+ 1])))substr(_tmp2,index(_tmp2,[:]))])
define([fetch],[define([_tmp],substr([$2],eval(index([$2],[$1:]) [+] len([$1]) [+ 1])))[]substr(_tmp,0,index(_tmp,[:]))])
define([initial_vars],[var0:0:var1:0:var2:0:var3:0:var4:0:var5:0:var6:0:var7:0:var8:0:var9:0:var10:0:var11:0:var12:0:var13:0:var14:0:])
define([kont0],[kont5([420:$1],[$2])])
define([kont5],[kont6(stack_neg([$1]),[$2])])
define([kont6],[kont11(stack_drop([$1]),store([var0],[$2],stack_1st([$1])))])
define([kont11],[kont16([300:$1],[$2])])
define([kont16],[kont21(stack_drop([$1]),store([var1],[$2],stack_1st([$1])))])
define([kont21],[kont26([300:$1],[$2])])
define([kont26],[kont31(stack_drop([$1]),store([var2],[$2],stack_1st([$1])))])
define([kont31],[kont36([300:$1],[$2])])
define([kont36],[kont37(stack_neg([$1]),[$2])])
define([kont37],[kont42(stack_drop([$1]),store([var3],[$2],stack_1st([$1])))])
define([kont42],[kont47([7:$1],[$2])])
define([kont47],[kont52(stack_drop([$1]),store([var4],[$2],stack_1st([$1])))])
define([kont52],[kont57([15:$1],[$2])])
define([kont57],[kont62(stack_drop([$1]),store([var5],[$2],stack_1st([$1])))])
define([kont62],[kont67([200:$1],[$2])])
define([kont67],[kont72(stack_drop([$1]),store([var6],[$2],stack_1st([$1])))])
define([kont72],[kont77(fetch([var2],[$2])[:$1],[$2])])
define([kont77],[kont82(stack_drop([$1]),store([var7],[$2],stack_1st([$1])))])
define([kont82],[kont87(fetch([var7],[$2])[:$1],[$2])])
define([kont87],[kont92(fetch([var3],[$2])[:$1],[$2])])
define([kont92],[kont93(stack_gt([$1]),[$2])])
define([kont93],[ifelse(eval(stack_1st([$1]) [== 0]),1,[kont423(stack_drop([$1]),[$2])],[kont98(stack_drop([$1]),[$2])])])
define([kont98],[kont103(fetch([var0],[$2])[:$1],[$2])])
define([kont103],[kont108(stack_drop([$1]),store([var8],[$2],stack_1st([$1])))])
define([kont108],[kont113(fetch([var8],[$2])[:$1],[$2])])
define([kont113],[kont118(fetch([var1],[$2])[:$1],[$2])])
define([kont118],[kont119(stack_lt([$1]),[$2])])
define([kont119],[ifelse(eval(stack_1st([$1]) [== 0]),1,[kont396(stack_drop([$1]),[$2])],[kont124(stack_drop([$1]),[$2])])])
define([kont124],[kont129([0:$1],[$2])])
define([kont129],[kont134(stack_drop([$1]),store([var9],[$2],stack_1st([$1])))])
define([kont134],[kont139([0:$1],[$2])])
define([kont139],[kont144(stack_drop([$1]),store([var10],[$2],stack_1st([$1])))])
define([kont144],[kont149([32:$1],[$2])])
define([kont149],[kont154(stack_drop([$1]),store([var11],[$2],stack_1st([$1])))])
define([kont154],[kont159([0:$1],[$2])])
define([kont159],[kont164(stack_drop([$1]),store([var12],[$2],stack_1st([$1])))])
define([kont164],[kont169(fetch([var12],[$2])[:$1],[$2])])
define([kont169],[kont174(fetch([var6],[$2])[:$1],[$2])])
define([kont174],[kont175(stack_lt([$1]),[$2])])
define([kont175],[ifelse(eval(stack_1st([$1]) [== 0]),1,[kont369(stack_drop([$1]),[$2])],[kont180(stack_drop([$1]),[$2])])])
define([kont180],[kont185(fetch([var10],[$2])[:$1],[$2])])
define([kont185],[kont190(fetch([var10],[$2])[:$1],[$2])])
define([kont190],[kont191(stack_mul([$1]),[$2])])
define([kont191],[kont196([200:$1],[$2])])
define([kont196],[kont197(stack_div([$1]),[$2])])
define([kont197],[kont202(stack_drop([$1]),store([var13],[$2],stack_1st([$1])))])
define([kont202],[kont207(fetch([var9],[$2])[:$1],[$2])])
define([kont207],[kont212(fetch([var9],[$2])[:$1],[$2])])
define([kont212],[kont213(stack_mul([$1]),[$2])])
define([kont213],[kont218([200:$1],[$2])])
define([kont218],[kont219(stack_div([$1]),[$2])])
define([kont219],[kont224(stack_drop([$1]),store([var14],[$2],stack_1st([$1])))])
define([kont224],[kont229(fetch([var13],[$2])[:$1],[$2])])
define([kont229],[kont234(fetch([var14],[$2])[:$1],[$2])])
define([kont234],[kont235(stack_add([$1]),[$2])])
define([kont235],[kont240([800:$1],[$2])])
define([kont240],[kont241(stack_gt([$1]),[$2])])
define([kont241],[ifelse(eval(stack_1st([$1]) [== 0]),1,[kont298(stack_drop([$1]),[$2])],[kont246(stack_drop([$1]),[$2])])])
define([kont246],[kont251([48:$1],[$2])])
define([kont251],[kont256(fetch([var12],[$2])[:$1],[$2])])
define([kont256],[kont257(stack_add([$1]),[$2])])
define([kont257],[kont262(stack_drop([$1]),store([var11],[$2],stack_1st([$1])))])
define([kont262],[kont267(fetch([var12],[$2])[:$1],[$2])])
define([kont267],[kont272([9:$1],[$2])])
define([kont272],[kont273(stack_gt([$1]),[$2])])
define([kont273],[ifelse(eval(stack_1st([$1]) [== 0]),1,[kont288(stack_drop([$1]),[$2])],[kont278(stack_drop([$1]),[$2])])])
define([kont278],[kont283([64:$1],[$2])])
define([kont283],[kont288(stack_drop([$1]),store([var11],[$2],stack_1st([$1])))])
define([kont288],[kont293(fetch([var6],[$2])[:$1],[$2])])
define([kont293],[kont298(stack_drop([$1]),store([var12],[$2],stack_1st([$1])))])
define([kont298],[kont303(fetch([var10],[$2])[:$1],[$2])])
define([kont303],[kont308(fetch([var9],[$2])[:$1],[$2])])
define([kont308],[kont309(stack_mul([$1]),[$2])])
define([kont309],[kont314([100:$1],[$2])])
define([kont314],[kont315(stack_div([$1]),[$2])])
define([kont315],[kont320(fetch([var7],[$2])[:$1],[$2])])
define([kont320],[kont321(stack_add([$1]),[$2])])
define([kont321],[kont326(stack_drop([$1]),store([var9],[$2],stack_1st([$1])))])
define([kont326],[kont331(fetch([var13],[$2])[:$1],[$2])])
define([kont331],[kont336(fetch([var14],[$2])[:$1],[$2])])
define([kont336],[kont337(stack_sub([$1]),[$2])])
define([kont337],[kont342(fetch([var8],[$2])[:$1],[$2])])
define([kont342],[kont343(stack_add([$1]),[$2])])
define([kont343],[kont348(stack_drop([$1]),store([var10],[$2],stack_1st([$1])))])
define([kont348],[kont353(fetch([var12],[$2])[:$1],[$2])])
define([kont353],[kont358([1:$1],[$2])])
define([kont358],[kont359(stack_add([$1]),[$2])])
define([kont359],[kont364(stack_drop([$1]),store([var12],[$2],stack_1st([$1])))])
define([kont364],[kont164([$1],[$2])])
define([kont369],[kont374(fetch([var11],[$2])[:$1],[$2])])
define([kont374],[prtc_1st([$1])[]kont375(stack_drop([$1]),[$2])])
define([kont375],[kont380(fetch([var8],[$2])[:$1],[$2])])
define([kont380],[kont385(fetch([var4],[$2])[:$1],[$2])])
define([kont385],[kont386(stack_add([$1]),[$2])])
define([kont386],[kont391(stack_drop([$1]),store([var8],[$2],stack_1st([$1])))])
define([kont391],[kont108([$1],[$2])])
define([kont396],[kont401([10:$1],[$2])])
define([kont401],[prtc_1st([$1])[]kont402(stack_drop([$1]),[$2])])
define([kont402],[kont407(fetch([var7],[$2])[:$1],[$2])])
define([kont407],[kont412(fetch([var5],[$2])[:$1],[$2])])
define([kont412],[kont413(stack_sub([$1]),[$2])])
define([kont413],[kont418(stack_drop([$1]),store([var7],[$2],stack_1st([$1])))])
define([kont418],[kont82([$1],[$2])])
define([kont423],[])
divert[]dnl
kont0([stack-bottom],initial_vars)[]dnl
- Output:
$ m4 mandel.m4 1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 1111111111111112222222222222333333333333333333333333333333333333222222222222222222222222222222222222222 1111111111111222222222233333333333333333333333344444456655544443333332222222222222222222222222222222222 1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 11111111111222222333333333333333333333334444444445555679@@@@7654444443333333222222222222222222222222222 1111111112222223333333333333333333333444444444455556789@@@@98755544444433333332222222222222222222222222 1111111122223333333333333333333333344444444445556668@@@ @@@76555544444333333322222222222222222222222 1111111222233333333333333333333344444444455566667778@@ @987666555544433333333222222222222222222222 111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@877779@5443333333322222222222222222222 1111112233333333333333333334444455555556679@ @@@ @@@@@@ 8544333333333222222222222222222 1111122333333333333333334445555555556666789@@@ @86554433333333322222222222222222 1111123333333333333444456666555556666778@@ @ @@87655443333333332222222222222222 111123333333344444455568@887789@8777788@@@ @@@@65444333333332222222222222222 111133334444444455555668@@@@@@@@@@@@99@@@ @@765444333333333222222222222222 111133444444445555556778@@@ @@@@ @855444333333333222222222222222 11124444444455555668@99@@ @ @655444433333333322222222222222 11134555556666677789@@ @86655444433333333322222222222222 111 @@876555444433333333322222222222222 11134555556666677789@@ @86655444433333333322222222222222 11124444444455555668@99@@ @ @655444433333333322222222222222 111133444444445555556778@@@ @@@@ @855444333333333222222222222222 111133334444444455555668@@@@@@@@@@@@99@@@ @@765444333333333222222222222222 111123333333344444455568@887789@8777788@@@ @@@@65444333333332222222222222222 1111123333333333333444456666555556666778@@ @ @@87655443333333332222222222222222 1111122333333333333333334445555555556666789@@@ @86554433333333322222222222222222 1111112233333333333333333334444455555556679@ @@@ @@@@@@ 8544333333333222222222222222222 111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@877779@5443333333322222222222222222222 1111111222233333333333333333333344444444455566667778@@ @987666555544433333333222222222222222222222 1111111122223333333333333333333333344444444445556668@@@ @@@76555544444333333322222222222222222222222 1111111112222223333333333333333333333444444444455556789@@@@98755544444433333332222222222222222222222222 11111111111222222333333333333333333333334444444445555679@@@@7654444443333333222222222222222222222222222 1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 1111111111111222222222233333333333333333333333344444456655544443333332222222222222222222222222222222222 1111111111111112222222222222333333333333333333333333333333333333222222222222222222222222222222222222222 1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211
The entry for ALGOL W also is based on Rosetta Code's "compiler" task suite.
Maple
ImageTools:-Embed(Fractals[EscapeTime]:-Mandelbrot(500, -2.0-1.35*I, .7+1.35*I, output = layer1));
Mathematica / Wolfram Language
The implementation could be better. But this is a start...
eTime[c_, maxIter_Integer: 100] := Length@NestWhileList[#^2 + c &, 0, Abs@# <= 2 &, 1, maxIter] - 1
DistributeDefinitions[eTime];
mesh = ParallelTable[eTime[x + I*y, 1000], {y, 1.2, -1.2, -0.01}, {x, -1.72, 1, 0.01}];
ReliefPlot[mesh, Frame -> False]
Faster version:
cf = With[{
mandel = Block[{z = #, c = #},
Catch@Do[If[Abs[z] > 2, Throw@i]; z = z^2 + c, {i, 100}]] &
},
Compile[{},Table[mandel[y + x I], {x, -1, 1, 0.005}, {y, -2, 0.5, 0.005}]]
];
ArrayPlot[cf[]]
Built-in function:
MandelbrotSetPlot[]
Mathmap
filter mandelbrot (gradient coloration) c=ri:(xy/xy:[X,X]*1.5-xy:[0.5,0]); z=ri:[0,0]; # initial value z0 = 0 # iteration of z iter=0; while abs(z)<2 && iter<31 do z=z*z+c; # z(n+1) = fc(zn) iter=iter+1 end; coloration(iter/32) # color of pixel end
MATLAB
This solution uses the escape time algorithm to determine the coloring of the coordinates on the complex plane. The code can be reduced to a single line via vectorization after the Escape Time Algorithm function definition, but the code becomes unnecessarily obfuscated. Also, this code uses a lot of memory. You will need a computer with a lot of memory to compute the set with high resolution.
function [theSet,realAxis,imaginaryAxis] = mandelbrotSet(start,gridSpacing,last,maxIteration)
%Define the escape time algorithm
function escapeTime = escapeTimeAlgorithm(z0)
escapeTime = 0;
z = 0;
while( (abs(z)<=2) && (escapeTime < maxIteration) )
z = (z + z0)^2;
escapeTime = escapeTime + 1;
end
end
%Define the imaginary axis
imaginaryAxis = (imag(start):imag(gridSpacing):imag(last));
%Define the real axis
realAxis = (real(start):real(gridSpacing):real(last));
%Construct the complex plane from the real and imaginary axes
complexPlane = meshgrid(realAxis,imaginaryAxis) + meshgrid(imaginaryAxis(end:-1:1),realAxis)'.*i;
%Apply the escape time algorithm to each point in the complex plane
theSet = arrayfun(@escapeTimeAlgorithm, complexPlane);
%Draw the set
pcolor(realAxis,imaginaryAxis,theSet);
shading flat;
end
To use this function you must specify the:
- lower left hand corner of the complex plane from which to start the image,
- the grid spacing in both the imaginary and real directions,
- the upper right hand corner of the complex plane at which to end the image and
- the maximum iterations for the escape time algorithm.
For example:
- Lower Left Corner: -2.05-1.2i
- Grid Spacing: 0.004+0.0004i
- Upper Right Corner: 0.45+1.2i
- Maximum Iterations: 500
Sample usage:
mandelbrotSet(-2.05-1.2i,0.004+0.0004i,0.45+1.2i,500);
Maxima
Using autoloded package plotdf
mandelbrot ([iterations, 30], [x, -2.4, 0.75], [y, -1.2, 1.2],
[grid,320,320])$
Metapost
prologues:=3;
outputtemplate:="%j-%c.svg";
outputformat:="svg";
def mandelbrot(expr maxX, maxY) =
max_iteration := 500;
color col[];
for i := 0 upto max_iteration:
t := i / max_iteration;
col[i] = (t,t,t);
endfor;
for px := 0 upto maxX:
for py := 0 upto maxY:
xz := px * 3.5 / maxX - 2.5; % (-2.5,1)
yz := py * 2 / maxY - 1; % (-1,1)
x := 0;
y := 0;
iteration := 0;
forever: exitunless ((x*x + y*y < 4) and (iteration < max_iteration));
xtemp := x*x - y*y + xz;
y := 2*x*y + yz;
x := xtemp;
iteration := iteration + 1;
endfor;
draw (px,py) withpen pencircle withcolor col[iteration];
endfor;
endfor;
enddef;
beginfig(1);
mandelbrot(200, 150);
endfig;
end
Sample usage:
mpost -numbersystem="double" mandelbrot.mp
MiniScript
ZOOM = 100
MAX_ITER = 40
gfx.clear color.black
for y in range(0,200)
for x in range(0,300)
zx = 0
zy = 0
cx = (x - 200) / ZOOM
cy = (y - 100) / ZOOM
for iter in range(MAX_ITER)
if zx*zx + zy*zy > 4 then break
tmp = zx * zx - zy * zy + cx
zy = 2 * zx * zy + cy
zx = tmp
end for
if iter then
gfx.setPixel x, y, rgb(255-iter*6, 0, iter*6)
end if
end for
end for
- Output:
Modula-3
MODULE Mandelbrot EXPORTS Main;
IMPORT Wr, Stdio, Fmt, Word;
CONST m = 50;
limit2 = 4.0;
TYPE UByte = BITS 8 FOR [0..16_FF];
VAR width := 200;
height := 200;
bitnum: CARDINAL := 0;
byteacc: UByte := 0;
isOverLimit: BOOLEAN;
Zr, Zi, Cr, Ci, Tr, Ti: REAL;
BEGIN
Wr.PutText(Stdio.stdout, "P4\n" & Fmt.Int(width) & " " & Fmt.Int(height) & "\n");
FOR y := 0 TO height - 1 DO
FOR x := 0 TO width - 1 DO
Zr := 0.0; Zi := 0.0;
Cr := 2.0 * FLOAT(x) / FLOAT(width) - 1.5;
Ci := 2.0 * FLOAT(y) / FLOAT(height) - 1.0;
FOR i := 1 TO m + 1 DO
Tr := Zr*Zr - Zi*Zi + Cr;
Ti := 2.0*Zr*Zi + Ci;
Zr := Tr; Zi := Ti;
isOverLimit := Zr*Zr + Zi*Zi > limit2;
IF isOverLimit THEN EXIT; END;
END;
IF isOverLimit THEN
byteacc := Word.Xor(Word.LeftShift(byteacc, 1), 16_00);
ELSE
byteacc := Word.Xor(Word.LeftShift(byteacc, 1), 16_01);
END;
INC(bitnum);
IF bitnum = 8 THEN
Wr.PutChar(Stdio.stdout, VAL(byteacc, CHAR));
byteacc := 0;
bitnum := 0;
ELSIF x = width - 1 THEN
byteacc := Word.LeftShift(byteacc, 8 - (width MOD 8));
Wr.PutChar(Stdio.stdout, VAL(byteacc, CHAR));
byteacc := 0;
bitnum := 0
END;
Wr.Flush(Stdio.stdout);
END;
END;
END Mandelbrot.
MySQL
See http://arbitraryscrawl.blogspot.co.uk/2012/06/fractsql.html for an explanation.
-- Table to contain all the data points
CREATE TABLE points (
c_re DOUBLE,
c_im DOUBLE,
z_re DOUBLE DEFAULT 0,
z_im DOUBLE DEFAULT 0,
znew_re DOUBLE DEFAULT 0,
znew_im DOUBLE DEFAULT 0,
steps INT DEFAULT 0,
active CHAR DEFAULT 1
);
DELIMITER |
-- Iterate over all the points in the table 'points'
CREATE PROCEDURE itrt (IN n INT)
BEGIN
label: LOOP
UPDATE points
SET
znew_re=POWER(z_re,2)-POWER(z_im,2)+c_re,
znew_im=2*z_re*z_im+c_im,
steps=steps+1
WHERE active=1;
UPDATE points SET
z_re=znew_re,
z_im=znew_im,
active=IF(POWER(z_re,2)+POWER(z_im,2)>4,0,1)
WHERE active=1;
SET n = n - 1;
IF n > 0 THEN
ITERATE label;
END IF;
LEAVE label;
END LOOP label;
END|
-- Populate the table 'points'
CREATE PROCEDURE populate (
r_min DOUBLE,
r_max DOUBLE,
r_step DOUBLE,
i_min DOUBLE,
i_max DOUBLE,
i_step DOUBLE)
BEGIN
DELETE FROM points;
SET @rl = r_min;
SET @a = 0;
rloop: LOOP
SET @im = i_min;
SET @b = 0;
iloop: LOOP
INSERT INTO points (c_re, c_im)
VALUES (@rl, @im);
SET @b=@b+1;
SET @im=i_min + @b * i_step;
IF @im < i_max THEN
ITERATE iloop;
END IF;
LEAVE iloop;
END LOOP iloop;
SET @a=@a+1;
SET @rl=r_min + @a * r_step;
IF @rl < r_max THEN
ITERATE rloop;
END IF;
LEAVE rloop;
END LOOP rloop;
END|
DELIMITER ;
-- Choose size and resolution of graph
-- R_min, R_max, R_step, I_min, I_max, I_step
CALL populate( -2.5, 1.5, 0.005, -2, 2, 0.005 );
-- Calculate 50 iterations
CALL itrt( 50 );
-- Create the image (/tmp/image.ppm)
-- Note, MySQL will not over-write an existing file and you may need
-- administrator access to delete or move it
SELECT @xmax:=COUNT(c_re) INTO @xmax FROM points GROUP BY c_im LIMIT 1;
SELECT @ymax:=COUNT(c_im) INTO @ymax FROM points GROUP BY c_re LIMIT 1;
SET group_concat_max_len=11*@xmax*@ymax;
SELECT
'P3', @xmax, @ymax, 200,
GROUP_CONCAT(
CONCAT(
IF( active=1, 0, 55+MOD(steps, 200) ), ' ',
IF( active=1, 0, 55+MOD(POWER(steps,3), 200) ), ' ',
IF( active=1, 0, 55+MOD(POWER(steps,2), 200) ) )
ORDER BY c_im ASC, c_re ASC SEPARATOR ' ' )
INTO OUTFILE '/tmp/image.ppm'
FROM points;
Nim
Textual version
import complex
proc inMandelbrotSet(c: Complex, maxEscapeIterations = 50): bool =
result = true; var z: Complex
for i in 0..maxEscapeIterations:
z = z * z + c
if abs2(z) > 4: return false
iterator steps(start, step: float, numPixels: int): float =
for i in 0..numPixels:
yield start + i.float * step
proc mandelbrotImage(yStart, yStep, xStart, xStep: float, height, width: int): string =
for y in steps(yStart, yStep, height):
for x in steps(xStart, xStep, width):
result.add(if complex(x, y).inMandelbrotSet: '*'
else: ' ')
result.add('\n')
echo mandelbrotImage(1.0, -0.05, -2.0, 0.0315, 40, 80)
- Output:
** ****** ******** ****** ******** ** * *** ***************** ************************ *** **************************** ****************************** ****************************** ************************************ * ********************************** ** ***** * ********************************** *********** ************************************ ************** ************************************ *************************************************** ***************************************************** ************************************************************************ ***************************************************** *************************************************** ************** ************************************ *********** ************************************ ** ***** * ********************************** * ********************************** ************************************ ****************************** ****************************** **************************** ************************ *** *** ***************** ******** ** * ****** ******** ****** **
Graphical version
import math, complex, lenientops
import imageman
const
W = 800
H = 600
Zoom = 0.5
MoveX = -0.5
MoveY = 0.0
MaxIter = 30
func hsvToRgb(h, s, v: float): array[3, float] =
let c = v * s
let x = c * (1 - abs(((h / 60) mod 2) - 1))
let m = v - c
let (r, g, b) = if h < 60: (c, x, 0.0)
elif h < 120: (x, c, 0.0)
elif h < 180: (0.0, c, x)
elif h < 240: (0.0, x, c)
elif x < 300: (x, 0.0, c)
else: (c, 0.0, x)
result = [r + m, g + m, b + m]
var img = initImage[ColorRGBF64](W, H)
for x in 1..W:
for y in 1..H:
var i = MaxIter - 1
let c = complex((2 * x - W) / (W * Zoom) + MoveX, (2 * y - H) / (H * Zoom) + MoveY)
var z = c
while abs(z) < 2 and i > 0:
z = z * z + c
dec i
let color = hsvToRgb(i / MaxIter * 360, 1, i / MaxIter)
img[x - 1, y - 1] = ColorRGBF64(color)
img.savePNG("mandelbrot.png", compression = 9)
ObjectIcon
A simple interactive graphics program that can dump PNG images. An escape-time algorithm is used to set the opacity of black on white.
You can run it with oiscript the-file-name-you-gave-it.icn
. Or you can compile it to an executable intermediate code with oit the-file-name-you-gave-it.icn
and then run ./the-file-name-you-gave-it
# -*- ObjectIcon -*-
import graphics
import ipl.graphics
import io
import util(Math)
procedure main ()
local w
local width, height
local xcenter, ycenter, pixels_per_unit, max_iter
local zoom_ratio
write ("q or Q : quit")
write ("left press : recenter")
write ("+ : zoom in")
write ("- : zoom in")
write ("2 .. 9 : set zoom ratio")
write ("o or O : restore original")
write ("p or P : dump to a PNG")
width := 400
height := 400
pixels_per_unit := 150
max_iter := 200
zoom_ratio := 2
xcenter := -0.75
ycenter := 0.0
w := Window().
set_size(width, height).
set_resize(&yes).
set_bg("white").
set_canvas("normal") | stop(&why)
event_loop (w, xcenter, ycenter, pixels_per_unit, max_iter,
zoom_ratio)
end
procedure event_loop (w, xcenter, ycenter, pixels_per_unit,
max_iter, zoom_ratio)
local event
local xy
local png_number, png_name
local redraw
local width, height
local xleft, ytop
local i, j
local cx, cy, step
local iter, color
png_number := 1
redraw := &yes
repeat
{
if \redraw then
{
w.erase_area()
step := 1.0 / pixels_per_unit
width := w.get_width()
height := w.get_height()
xleft := xcenter - (width / (2.0 * pixels_per_unit))
ytop := ycenter + (height / (2.0 * pixels_per_unit))
cx := xleft
cy := ytop
j := 0
i := 0
redraw := &no
}
if j ~= height then
{
iter := count_mandelbrot_iterations (cx, cy, max_iter)
color := map_iterations_to_color (max_iter, iter)
w.set_fg (color)
w.draw_point (i, j)
i +:= 1; cx +:= step
if i = width then
{
i := 0; cx := xleft
j +:= 1; cy -:= step
}
}
if *w.pending() ~= 0 then
{
event := w.event()
case event[1] of
{
QuitEvents():
exit()
Mouse.LEFT_PRESS:
{
xy := window_coords_to_point (w, event[2], event[3],
xcenter, ycenter,
pixels_per_unit)
xcenter := xy[1]
ycenter := xy[2]
redraw := &yes
}
"+":
{
pixels_per_unit := zoom_ratio * pixels_per_unit
redraw := &yes
}
"-":
{
pixels_per_unit :=
max (1, (1.0 / zoom_ratio) * pixels_per_unit)
redraw := &yes
}
!"23456789":
zoom_ratio := integer(event[1])
!"oO":
{
pixels_per_unit := 150
max_iter := 200
zoom_ratio := 2
xcenter := -0.75
ycenter := 0.0
redraw := &yes
}
!"pP":
{
png_name := "mandelbrot-image-" || png_number || ".png"
png_number +:= 1
w.get_pixels().to_file(png_name)
write ("Wrote ", png_name)
}
Window.RESIZE:
redraw := &yes
}
WDelay(w, 100)
}
}
end
procedure count_mandelbrot_iterations (cx, cy, max_iter)
local x, y, xsquared, ysquared, iter, tmp
x := 0
y := 0
iter := 0
until (iter = max_iter |
4 < (xsquared := x * x) + (ysquared := y * y)) do
{
tmp := xsquared - ysquared + cx
y := (2 * x * y) + cy
x := tmp
iter +:= 1
}
return iter
end
procedure map_iterations_to_color (max_iter, iter)
return "black " ||
integer((Math.log (iter) * 100.0) / Math.log (max_iter)) ||
"%"
end
procedure window_coords_to_point (w, xcoord, ycoord,
xcenter, ycenter,
pixels_per_unit)
local x, y
x := xcenter +
(((2.0 * xcoord) - w.get_width()) / (2.0 * pixels_per_unit))
y := ycenter +
((w.get_height() - (2.0 * ycoord)) / (2.0 * pixels_per_unit))
return [x, y]
end
- Output:
An example of a dumped PNG:
![A sample of seahorse valley from the Object Icon program.](http://static.miraheze.org/rosettacodewiki/thumb/0/04/Mandelbrot_task_OI_sampleimage.png/300px-Mandelbrot_task_OI_sampleimage.png)
OCaml
#load "graphics.cma";;
let mandelbrot xMin xMax yMin yMax xPixels yPixels maxIter =
let rec mandelbrotIterator z c n =
if (Complex.norm z) > 2.0 then false else
match n with
| 0 -> true
| n -> let z' = Complex.add (Complex.mul z z) c in
mandelbrotIterator z' c (n-1) in
Graphics.open_graph
(" "^(string_of_int xPixels)^"x"^(string_of_int yPixels));
let dx = (xMax -. xMin) /. (float_of_int xPixels)
and dy = (yMax -. yMin) /. (float_of_int yPixels) in
for xi = 0 to xPixels - 1 do
for yi = 0 to yPixels - 1 do
let c = {Complex.re = xMin +. (dx *. float_of_int xi);
Complex.im = yMin +. (dy *. float_of_int yi)} in
if (mandelbrotIterator Complex.zero c maxIter) then
(Graphics.set_color Graphics.white;
Graphics.plot xi yi )
else
(Graphics.set_color Graphics.black;
Graphics.plot xi yi )
done
done;;
mandelbrot (-1.5) 0.5 (-1.0) 1.0 500 500 200;;
Octave
This code runs rather slowly and produces coloured Mandelbrot set by accident (output image).
#! /usr/bin/octave -qf
global width = 200;
global height = 200;
maxiter = 100;
z0 = 0;
global cmax = 1 + i;
global cmin = -2 - i;
function cs = pscale(c)
global cmax;
global cmin;
global width;
global height;
persistent px = (real(cmax-cmin))/width;
persistent py = (imag(cmax-cmin))/height;
cs = real(cmin) + px*real(c) + i*(imag(cmin) + py*imag(c));
endfunction
ms = zeros(width, height);
for x = 0:width-1
for y = 0:height-1
z0 = 0;
c = pscale(x+y*i);
for ic = 1:maxiter
z1 = z0^2 + c;
if ( abs(z1) > 2 ) break; endif
z0 = z1;
endfor
ms(x+1, y+1) = ic/maxiter;
endfor
endfor
saveimage("mandel.ppm", round(ms .* 255).', "ppm");
A bit faster than the above implementation
function z = mandelbrot()
% to view the image call "image(mandelbrot())"
width = 500; height = 500;
z = zeros(width, height);
c = zeros(width, height);
xi = 1;
for x = linspace(-2, 2, width)
yi = 1;
for y = linspace(-2, 2, height)
c(yi, xi) = x+y*i; yi += 1;
end
xi += 1;
end
for iter = 1:50
z = z.*z + c;
end
z = abs(z);
end
Ol
(define x-size 59)
(define y-size 21)
(define min-im -1)
(define max-im 1)
(define min-re -2)
(define max-re 1)
(define step-x (/ (- max-re min-re) x-size))
(define step-y (/ (- max-im min-im) y-size))
(for-each (lambda (y)
(let ((im (+ min-im (* step-y y))))
(for-each (lambda (x)
(let*((re (+ min-re (* step-x x)))
(zr (inexact re))
(zi (inexact im)))
(let loop ((n 0) (zi zi) (zr zr))
(let ((a (* zr zr))
(b (* zi zi)))
(cond
((> (+ a b) 4)
(display (string (- 62 n))))
((= n 30)
(display (string (- 62 n))))
(else
(loop (+ n 1) (+ (* 2 zr zi) im) (- (+ a re) b))))))))
(iota x-size))
(print)))
(iota y-size))
Output:
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<========== >>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======= >>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== >>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== >>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== >>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== >=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= ><<<<;;;;;:::972456-567763 +9;;<<<<<<< ><;;;;;;::::9875& .3 *9;;;<<<<<< >;;;;;;::997564' ' 8:;;;<<<<<< >::988897735/ &89:;;;<<<<<< >::988897735/ &89:;;;<<<<<< >;;;;;;::997564' ' 8:;;;<<<<<< ><;;;;;;::::9875& .3 *9;;;<<<<<< ><<<<;;;;;:::972456-567763 +9;;<<<<<<< >=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= >>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== >>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== >>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== >>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== >>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<=======
OpenEdge/Progress
DEFINE VARIABLE print_str AS CHAR NO-UNDO INIT ''.
DEFINE VARIABLE X1 AS DECIMAL NO-UNDO INIT 50.
DEFINE VARIABLE Y1 AS DECIMAL NO-UNDO INIT 21.
DEFINE VARIABLE X AS DECIMAL NO-UNDO.
DEFINE VARIABLE Y AS DECIMAL NO-UNDO.
DEFINE VARIABLE N AS DECIMAL NO-UNDO.
DEFINE VARIABLE I3 AS DECIMAL NO-UNDO.
DEFINE VARIABLE R3 AS DECIMAL NO-UNDO.
DEFINE VARIABLE Z1 AS DECIMAL NO-UNDO.
DEFINE VARIABLE Z2 AS DECIMAL NO-UNDO.
DEFINE VARIABLE A AS DECIMAL NO-UNDO.
DEFINE VARIABLE B AS DECIMAL NO-UNDO.
DEFINE VARIABLE I1 AS DECIMAL NO-UNDO INIT -1.0.
DEFINE VARIABLE I2 AS DECIMAL NO-UNDO INIT 1.0.
DEFINE VARIABLE R1 AS DECIMAL NO-UNDO INIT -2.0.
DEFINE VARIABLE R2 AS DECIMAL NO-UNDO INIT 1.0.
DEFINE VARIABLE S1 AS DECIMAL NO-UNDO.
DEFINE VARIABLE S2 AS DECIMAL NO-UNDO.
S1 = (R2 - R1) / X1.
S2 = (I2 - I1) / Y1.
DO Y = 0 TO Y1 - 1:
I3 = I1 + S2 * Y.
DO X = 0 TO X1 - 1:
R3 = R1 + S1 * X.
Z1 = R3.
Z2 = I3.
DO N = 0 TO 29:
A = Z1 * Z1.
B = Z2 * Z2.
IF A + B > 4.0 THEN
LEAVE.
Z2 = 2 * Z1 * Z2 + I3.
Z1 = A - B + R3.
END.
print_str = print_str + CHR(62 - N).
END.
print_str = print_str + '~n'.
END.
OUTPUT TO "C:\Temp\out.txt".
MESSAGE print_str.
OUTPUT CLOSE.
Example :
PARI/GP
Define function mandelbrot():
mandelbrot() =
{
forstep(y=-1, 1, 0.05,
forstep(x=-2, 0.5, 0.0315,
print1(((c)->my(z=c);for(i=1,20,z=z*z+c;if(abs(z)>2,return(" ")));"#")(x+y*I)));
print());
}
Output:
gp > mandelbrot() # # ### # ######## ######### ###### ## ## ############ # ### ################### # ############################# ############################ ################################ ################################ #################################### # # # ################################### ########### ################################### ########### ##################################### ############## #################################### #################################################### ###################################################### ######################################################################### ###################################################### #################################################### ############## #################################### ########### ##################################### ########### ################################### # # ################################### #################################### # ################################ ################################ ############################ ############################# ### ################### # ## ## ############ # ###### ######### ######## # ### # #
Pascal
program mandelbrot;
{$IFDEF FPC}
{$MODE DELPHI}
{$ENDIF}
const
ixmax = 800;
iymax = 800;
cxmin = -2.5;
cxmax = 1.5;
cymin = -2.0;
cymax = 2.0;
maxcolorcomponentvalue = 255;
maxiteration = 200;
escaperadius = 2;
type
colortype = record
red : byte;
green : byte;
blue : byte;
end;
var
ix, iy : integer;
cx, cy : real;
pixelwidth : real = (cxmax - cxmin) / ixmax;
pixelheight : real = (cymax - cymin) / iymax;
filename : string = 'new1.ppm';
comment : string = '# ';
outfile : textfile;
color : colortype;
zx, zy : real;
zx2, zy2 : real;
iteration : integer;
er2 : real = (escaperadius * escaperadius);
begin
{$I-}
assign(outfile, filename);
rewrite(outfile);
if ioresult <> 0 then
begin
{$IFDEF FPC}
writeln(stderr, 'Unable to open output file: ', filename);
{$ELSE}
writeln('ERROR: Unable to open output file: ', filename);
{$ENDIF}
exit;
end;
writeln(outfile, 'P6');
writeln(outfile, ' ', comment);
writeln(outfile, ' ', ixmax);
writeln(outfile, ' ', iymax);
writeln(outfile, ' ', maxcolorcomponentvalue);
for iy := 1 to iymax do
begin
cy := cymin + (iy - 1)*pixelheight;
if abs(cy) < pixelheight / 2 then cy := 0.0;
for ix := 1 to ixmax do
begin
cx := cxmin + (ix - 1)*pixelwidth;
zx := 0.0;
zy := 0.0;
zx2 := zx*zx;
zy2 := zy*zy;
iteration := 0;
while (iteration < maxiteration) and (zx2 + zy2 < er2) do
begin
zy := 2*zx*zy + cy;
zx := zx2 - zy2 + cx;
zx2 := zx*zx;
zy2 := zy*zy;
iteration := iteration + 1;
end;
if iteration = maxiteration then
begin
color.red := 0;
color.green := 0;
color.blue := 0;
end
else
begin
color.red := 255;
color.green := 255;
color.blue := 255;
end;
write(outfile, chr(color.red), chr(color.green), chr(color.blue));
end;
end;
close(outfile);
end.
Peri
###sysinclude standard.uh
###sysinclude str.uh
###sysinclude system.uh
###sysinclude X.uh
$ff0000 sto szin
300 sto maxiter
maxypixel sto YRES
maxxpixel sto XRES
myscreen "Mandelbrot" @YRES @XRES graphic
#g
@YRES 2 / (#d) sto y2
@YRES 2 / (#d) sto x2
@XRES i: {{
@YRES {{
{{}}§i #g !(#d) 480. - @x2 - @x2 /
sto xx
{{}} #g !(#d) @y2 - @y2 /
sto yy
zero#d xa zero#d ya zero iter
#d
ciklus:
@xa dup* @ya dup* - @xx +
@xa 2. * @ya * @yy + sto ya
sto xa ++()#g iter
@xa dup* @ya dup* + 4. > @iter @maxiter >=#g |#g then §ciklusvége
goto §ciklus
ciklusvége:
@iter @maxiter ==#g {
myscreen {{}} {{}}§i @szin setpixel
}{
myscreen {{}} {{}}§i @iter 64 *#g setpixel
}
}}
}}
myscreen 10000 key?
vége: myscreen inv graphic
//."A lenyomott billentyű: " kprintnl
end
{ „xx” }
{ „x2” }
{ „yy” }
{ „y2” }
{ „xa” }
{ „ya” }
{ „iter” }
{ „maxiter” }
{ „szin” }
{ „YRES” }
{ „XRES” }
{ „myscreen” }
- Output:
Perl
translation / optimization of the ruby solution
use Math::Complex;
sub mandelbrot {
my ($z, $c) = @_[0,0];
for (1 .. 20) {
$z = $z * $z + $c;
return $_ if abs $z > 2;
}
}
for (my $y = 1; $y >= -1; $y -= 0.05) {
for (my $x = -2; $x <= 0.5; $x += 0.0315)
{print mandelbrot($x + $y * i) ? ' ' : '#'}
print "\n"
}
Phix
- Ascii
This is included in the distribution (with some extra validation) as demo\mandle.exw
--
-- Mandlebrot set in ascii art demo.
--
constant b=" .:,;!/>)|&IH%*#"
atom r, i, c, C, z, Z, t, k
for y=30 to 0 by -1 do
C = y*0.1-1.5
puts(1,'\n')
for x=0 to 74 do
c = x*0.04-2
z = 0
Z = 0
r = c
i = C
k = 0
while k<112 do
t = z*z-Z*Z+r
Z = 2*z*Z+i
z = t
if z*z+Z*Z>10 then exit end if
k += 1
end while
puts(1,b[remainder(k,16)+1])
end for
end for
- Graphical
This is included in the distribution as demo\arwendemo\mandel.exw
include arwen.ew
include ..\arwen\dib256.ew
constant HelpText = "Left-click drag with the mouse to move the image.\n"&
" (the image is currently only redrawn on mouseup).\n"&
"Right-click-drag with the mouse to select a region to zoom in to.\n"&
"Use the mousewheel to zoom in and out (nb: can be slow).\n"&
"Press F2 to select iterations, higher==more detail but slower.\n"&
"Resize the window as you please, but note that going fullscreen, \n"&
"especially at high iteration, may mean a quite long draw time.\n"&
"Press Escape to close the window."
procedure Help()
void = messageBox("Mandelbrot Set",HelpText,MB_OK)
end procedure
integer cWidth = 520 -- client area width
integer cHeight = 480 -- client area height
constant Main = create(Window, "Mandelbrot Set", 0, 0, 50, 50, cWidth+16, cHeight+38, 0),
mainHwnd = getHwnd(Main),
mainDC = getPrivateDC(Main),
mIter = create(Menu, "", 0, 0, 0,0,0,0,0),
iterHwnd = getHwnd(mIter),
mIter50 = create(MenuItem,"50 (fast, low detail)", 0, mIter, 0,0,0,0,0),
mIter100 = create(MenuItem,"100 (default)", 0, mIter, 0,0,0,0,0),
mIter500 = create(MenuItem,"500", 0, mIter, 0,0,0,0,0),
mIter1000 = create(MenuItem,"1000 (slow, high detail)",0, mIter, 0,0,0,0,0),
m50to1000 = {mIter50,mIter100,mIter500,mIter1000},
i50to1000 = { 50, 100, 500, 1000}
integer mainDib = 0
constant whitePen = c_func(xCreatePen, {0,1,BrightWhite})
constant NULL_BRUSH = 5,
NullBrushID = c_func(xGetStockObject,{NULL_BRUSH})
atom t0
integer iter
atom x0, y0 -- top-left coords to draw
atom scale -- controls width/zoom
procedure init()
x0 = -2
y0 = -1.25
scale = 2.5/cHeight
iter = 100
void = c_func(xSelectObject,{mainDC,whitePen})
void = c_func(xSelectObject,{mainDC,NullBrushID})
end procedure
init()
function in_set(atom x, atom y)
atom u,t
if x>-0.75 then
u = x-0.25
t = u*u+y*y
return ((2*t+u)*(2*t+u)>t)
else
return ((x+1)*(x+1)+y*y)>0.0625
end if
end function
function pixel_colour(atom x0, atom y0, integer iter)
integer count = 1
atom x = 0, y = 0
while (count<=iter) and (x*x+y*y<4) do
count += 1
{x,y} = {x*x-y*y+x0,2*x*y+y0}
end while
if count<=iter then return count end if
return 0
end function
procedure mandel(atom x0, atom y0, atom scale)
atom x,y
integer c
t0 = time()
y = y0
for yi=1 to cHeight do
x = x0
for xi=1 to cWidth do
c = 0 -- default to black
if in_set(x,y) then
c = pixel_colour(x,y,iter)
end if
setDibPixel(mainDib, xi, yi, c)
x += scale
end for
y += scale
end for
end procedure
integer firsttime = 1
integer drawBox = 0
integer drawTime = 0
procedure newDib()
sequence pal
if mainDib!=0 then
{} = deleteDib(mainDib)
end if
mainDib = createDib(cWidth, cHeight)
pal = repeat({0,0,0},256)
for i=2 to 256 do
pal[i][1] = i*5
pal[i][2] = 0
pal[i][3] = i*10
end for
setDibPalette(mainDib, 1, pal)
mandel(x0,y0,scale)
drawTime = 2
end procedure
procedure reDraw()
setText(Main,"Please Wait...")
mandel(x0,y0,scale)
drawTime = 2
repaintWindow(Main,False)
end procedure
procedure zoom(integer z)
while z do
if z>0 then
scale /= 1.1
z -= 1
else
scale *= 1.1
z += 1
end if
end while
reDraw()
end procedure
integer dx=0,dy=0 -- mouse down coords
integer mx=0,my=0 -- mouse move/up coords
function mainHandler(integer id, integer msg, atom wParam, object lParam)
integer x, y -- scratch vars
atom scale10
if msg=WM_SIZE then -- (also activate/firsttime)
{{},{},x,y} = getClientRect(Main)
if firsttime or cWidth!=x or cHeight!=y then
scale *= cWidth/x
{cWidth, cHeight} = {x,y}
newDib()
firsttime = 0
end if
elsif msg=WM_PAINT then
copyDib(mainDC, 0, 0, mainDib)
if drawBox then
void = c_func(xRectangle, {mainDC, dx, dy, mx, my})
end if
if drawTime then
if drawTime=2 then
setText(Main,sprintf("Mandelbrot Set [generated in %gs]",time()-t0))
else
setText(Main,"Mandelbrot Set")
end if
drawTime -= 1
end if
elsif msg=WM_CHAR then
if wParam=VK_ESCAPE then
closeWindow(Main)
elsif wParam='+' then zoom(+1)
elsif wParam='-' then zoom(-1)
end if
elsif msg=WM_LBUTTONDOWN
or msg=WM_RBUTTONDOWN then
{dx,dy} = lParam
elsif msg=WM_MOUSEMOVE then
if and_bits(wParam,MK_LBUTTON) then
{mx,my} = lParam
-- minus dx,dy (see WM_LBUTTONUP)
-- DEV maybe a timer to redraw, but probably too slow...
-- (this is where we need a background worker thread,
-- ideally one we can direct to abandon what it is
-- currently doing and start work on new x,y instead)
elsif and_bits(wParam,MK_RBUTTON) then
{mx,my} = lParam
drawBox = 1
repaintWindow(Main,False)
end if
elsif msg=WM_MOUSEWHEEL then
wParam = floor(wParam/#10000)
if wParam>=#8000 then -- sign bit set
wParam-=#10000
end if
wParam = floor(wParam/120) -- (gives +/-1, usually)
zoom(wParam)
elsif msg=WM_LBUTTONUP then
{mx,my} = lParam
drawBox = 0
x0 += (dx-mx)*scale
y0 += (dy-my)*scale
reDraw()
elsif msg=WM_RBUTTONUP then
{mx,my} = lParam
drawBox = 0
if mx!=dx and my!=dy then
x0 += min(mx,dx)*scale
y0 += min(my,dy)*scale
scale *= (abs(mx-dx))/cHeight
reDraw()
end if
elsif msg=WM_KEYDOWN then
if wParam=VK_F1 then
Help()
elsif wParam=VK_F2 then
{x,y} = getWindowRect(Main)
void = c_func(xTrackPopupMenu, {iterHwnd,TPM_LEFTALIGN,x+20,y+40,0,mainHwnd,NULL})
elsif find(wParam,{VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT}) then
drawBox = 0
scale10 = scale*10
if wParam=VK_UP then
y0 += scale10
elsif wParam=VK_DOWN then
y0 -= scale10
elsif wParam=VK_LEFT then
x0 += scale10
elsif wParam=VK_RIGHT then
x0 -= scale10
end if
reDraw()
end if
elsif msg=WM_COMMAND then
id = find(id,m50to1000)
if id!=0 then
iter = i50to1000[id]
reDraw()
end if
end if
return 0
end function
setHandler({Main,mIter50,mIter100,mIter500,mIter1000}, routine_id("mainHandler"))
WinMain(Main,SW_NORMAL)
void = deleteDib(0)
PHP
![](http://static.miraheze.org/rosettacodewiki/thumb/d/de/Mandel-php.png/300px-Mandel-php.png)
$min_x=-2;
$max_x=1;
$min_y=-1;
$max_y=1;
$dim_x=400;
$dim_y=300;
$im = @imagecreate($dim_x, $dim_y)
or die("Cannot Initialize new GD image stream");
header("Content-Type: image/png");
$black_color = imagecolorallocate($im, 0, 0, 0);
$white_color = imagecolorallocate($im, 255, 255, 255);
for($y=0;$y<=$dim_y;$y++) {
for($x=0;$x<=$dim_x;$x++) {
$c1=$min_x+($max_x-$min_x)/$dim_x*$x;
$c2=$min_y+($max_y-$min_y)/$dim_y*$y;
$z1=0;
$z2=0;
for($i=0;$i<100;$i++) {
$new1=$z1*$z1-$z2*$z2+$c1;
$new2=2*$z1*$z2+$c2;
$z1=$new1;
$z2=$new2;
if($z1*$z1+$z2*$z2>=4) {
break;
}
}
if($i<100) {
imagesetpixel ($im, $x, $y, $white_color);
}
}
}
imagepng($im);
imagedestroy($im);
Picat
Picat has not support for fancy graphics so it's plain 0/1 ASCII. Also, there's no built-in support for complex numbers.
go =>
Width = 90,
Height = 50,
Limit = 50,
foreach(Y in 1..Height)
P="",
foreach (X in 1..Width)
Z=complex(0,0),
C=complex(2.5*X/Width-2.0,2.0*Y/Height-1.0),
J = 0,
while (J < Limit, c_abs(Z)<2.0)
Z := c_add(c_mul(Z,Z),C),
J := J + 1
end,
if J == Limit then
P := P ++ "#"
else
P := P ++ "."
end
end,
printf("%s\n", P)
end,
nl.
% Operations on complex numbers
complex(R,I) = [R,I].
c_add(X,Y) = complex(X[1]+Y[1],X[2]+Y[2]).
c_mul(X,Y) = complex(X[1]*Y[1]-X[2]*Y[2],X[1]*Y[2]+X[2]*Y[1]).
c_abs(X) = sqrt(X[1]*X[1]+X[2]*X[2]).
- Output:
.......................................................................................... .......................................................................................... ...................................................................##..................... ..................................................................##...................... ...............................................................########................... ..............................................................#########................... ...............................................................#######.................... ................................................................######.................... ..........................................................#.#.############................ ...................................................###..#####################............. ...................................................###########################..####...... .....................................................##############################....... ..................................................###############################......... ..............................................#.###################################....... ................................................####################################...... ................................................####################################.#.... ...............................................#######################################.... ...............................#...##.........#######################################..... .............................##########......#########################################.... ..............................############...#########################################.... ...........................################..#########################################.... ...........................#################.########################################..... ...........................#################.#######################################...... .......................############################################################....... #################################################################################......... .......................############################################################....... ...........................#################.#######################################...... ...........................#################.########################################..... ...........................################..#########################################.... ..............................############...#########################################.... .............................##########......#########################################.... ...............................#...##.........#######################################..... ...............................................#######################################.... ................................................####################################.#.... ................................................####################################...... ..............................................#.###################################....... ..................................................###############################......... .....................................................##############################....... ...................................................###########################..####...... ...................................................###..#####################............. ..........................................................#.#.############................ ................................................................######.................... ...............................................................#######.................... ..............................................................#########................... ...............................................................########................... ..................................................................##...................... ...................................................................##..................... .......................................................................................... .......................................................................................... .......................................................................#..................
PicoLisp
(scl 6)
(let Ppm (make (do 300 (link (need 400))))
(for (Y . Row) Ppm
(for (X . @) Row
(let (ZX 0 ZY 0 CX (*/ (- X 250) 1.0 150) CY (*/ (- Y 150) 1.0 150) C 570)
(while (and (> 4.0 (+ (*/ ZX ZX 1.0) (*/ ZY ZY 1.0))) (gt0 C))
(let Tmp (- (*/ ZX ZX 1.0) (*/ ZY ZY 1.0) (- CX))
(setq
ZY (+ (*/ 2 ZX ZY 1.0) CY)
ZX Tmp ) )
(dec 'C) )
(set (nth Ppm Y X) (list 0 C C)) ) ) )
(out "img.ppm"
(prinl "P6")
(prinl 400 " " 300)
(prinl 255)
(for Y Ppm (for X Y (apply wr X))) ) )
PostScript
%!PS-Adobe-2.0
%%BoundingBox: 0 0 300 200
%%EndComments
/origstate save def
/ld {load def} bind def
/m /moveto ld /g /setgray ld
/dot { currentpoint 1 0 360 arc fill } bind def
%%EndProlog
% param
/maxiter 200 def
% complex manipulation
/complex { 2 array astore } def
/real { 0 get } def
/imag { 1 get } def
/cmul { /a exch def /b exch def
a real b real mul
a imag b imag mul sub
a real b imag mul
a imag b real mul add
2 array astore
} def
/cadd { aload pop 3 -1 roll aload pop
3 -1 roll add
3 1 roll add exch 2 array astore
} def
/cconj { aload pop neg 2 array astore } def
/cabs2 { dup cconj cmul 0 get} def
% mandel
200 100 translate
-200 1 100 { /x exch def
-100 1 100 { /y exch def
/z0 0.0 0.0 complex def
0 1 maxiter { /iter exch def
x 100 div y 100 div complex
z0 z0 cmul
cadd dup /z0 exch def
cabs2 4 gt {exit} if
} for
iter maxiter div g
x y m dot
} for
} for
%
showpage
origstate restore
%%EOF
PowerShell
$x = $y = $i = $j = $r = -16
$colors = [Enum]::GetValues([System.ConsoleColor])
while(($y++) -lt 15)
{
for($x=0; ($x++) -lt 84; Write-Host " " -BackgroundColor ($colors[$k -band 15]) -NoNewline)
{
$i = $k = $r = 0
do
{
$j = $r * $r - $i * $i -2 + $x / 25
$i = 2 * $r * $i + $y / 10
$r = $j
}
while (($j * $j + $i * $i) -lt 11 -band ($k++) -lt 111)
}
Write-Host
}
Processing
Click on an area to zoom in. Choose areas with multiple colors for interesting zooming.
double x, y, zr, zi, zr2, zi2, cr, ci, n;
double zmx1, zmx2, zmy1, zmy2, f, di, dj;
double fn1, fn2, fn3, re, gr, bl, xt, yt, i, j;
void setup() {
size(500, 500);
di = 0;
dj = 0;
f = 10;
fn1 = random(20);
fn2 = random(20);
fn3 = random(20);
zmx1 = int(width / 4);
zmx2 = 2;
zmy1 = int(height / 4);
zmy2 = 2;
}
void draw() {
if (i <= width) i++;
x = (i + di)/ zmx1 - zmx2;
for ( j = 0; j <= height; j++) {
y = zmy2 - (j + dj) / zmy1;
zr = 0;
zi = 0;
zr2 = 0;
zi2 = 0;
cr = x;
ci = y;
n = 1;
while (n < 200 && (zr2 + zi2) < 4) {
zi2 = zi * zi;
zr2 = zr * zr;
zi = 2 * zi * zr + ci;
zr = zr2 - zi2 + cr;
n++;
}
re = (n * fn1) % 255;
gr = (n * fn2) % 255;
bl = (n * fn3) % 255;
stroke((float)re, (float)gr, (float)bl);
point((float)i, (float)j);
}
}
void mousePressed() {
background(200);
xt = mouseX;
yt = mouseY;
di = di + xt - float(width / 2);
dj = dj + yt - float(height / 2);
zmx1 = zmx1 * f;
zmx2 = zmx2 * (1 / f);
zmy1 = zmy1 * f;
zmy2 = zmy2 * (1 / f);
di = di * f;
dj = dj * f;
i = 0;
j = 0;
}
The sketch can be run online :
here.
Processing Python mode
Click on an area to zoom in. Choose areas with multiple colors for interesting zooming.
i = di = dj = 0
fn1, fn2, fn3 = random(20), random(20), random(20)
f = 10
def setup():
global zmx1, zmx2, zmy1, zmy2
size(500, 500)
zmx1 = int(width / 4)
zmx2 = 2
zmy1 = int(height / 4)
zmy2 = 2
def draw():
global i
if i <= width:
i += 1
x = float(i + di) / zmx1 - zmx2
for j in range(height + 1):
y = zmy2 - float(j + dj) / zmy1
zr = zi = zr2 = zi2 = 0
cr, ci = x, y
n = 1
while n < 200 and (zr2 + zi2) < 4:
zi2 = zi * zi
zr2 = zr * zr
zi = 2 * zi * zr + ci
zr = zr2 - zi2 + cr
n += 1
re = (n * fn1) % 255
gr = (n * fn2) % 255
bl = (n * fn3) % 255
stroke(re, gr, bl)
point(i, j)
def mousePressed():
global zmx1, zmx2, zmy1, zmy2, di, dj
global i, j
background(200)
xt, yt = mouseX, mouseY
di = di + xt - width / 2.
dj = dj + yt - height / 2.
zmx1 = zmx1 * f
zmx2 = zmx2 * (1. / f)
zmy1 = zmy1 * f
zmy2 = zmy2 * (1. / f)
di, dj = di * f, dj * f
i = j = 0
Prolog
SWI-Prolog has a graphic interface XPCE :
:- use_module(library(pce)).
mandelbrot :-
new(D, window('Mandelbrot Set')),
send(D, size, size(700, 650)),
new(Img, image(@nil, width := 700, height := 650, kind := pixmap)),
forall(between(0,699, I),
( forall(between(0,649, J),
( get_RGB(I, J, R, G, B),
R1 is (R * 256) mod 65536,
G1 is (G * 256) mod 65536,
B1 is (B * 256) mod 65536,
send(Img, pixel(I, J, colour(@default, R1, G1, B1))))))),
new(Bmp, bitmap(Img)),
send(D, display, Bmp, point(0,0)),
send(D, open).
get_RGB(X, Y, R, G, B) :-
CX is (X - 350) / 150,
CY is (Y - 325) / 150,
Iter = 570,
compute_RGB(CX, CY, 0, 0, Iter, It),
IterF is It \/ It << 15,
R is IterF >> 16,
Iter1 is IterF - R << 16,
G is Iter1 >> 8,
B is Iter1 - G << 8.
compute_RGB(CX, CY, ZX, ZY, Iter, IterF) :-
ZX * ZX + ZY * ZY < 4,
Iter > 0,
!,
Tmp is ZX * ZX - ZY * ZY + CX,
ZY1 is 2 * ZX * ZY + CY,
Iter1 is Iter - 1,
compute_RGB(CX, CY, Tmp, ZY1, Iter1, IterF).
compute_RGB(_CX, _CY, _ZX, _ZY, Iter, Iter).
Example :
Python
Translation of the ruby solution
# Python 3.0+ and 2.5+
try:
from functools import reduce
except:
pass
def mandelbrot(a):
return reduce(lambda z, _: z * z + a, range(50), 0)
def step(start, step, iterations):
return (start + (i * step) for i in range(iterations))
rows = (("*" if abs(mandelbrot(complex(x, y))) < 2 else " "
for x in step(-2.0, .0315, 80))
for y in step(1, -.05, 41))
print("\n".join("".join(row) for row in rows))
A more "Pythonic" version of the code:
import math
def mandelbrot(z , c , n=40):
if abs(z) > 1000:
return float("nan")
elif n > 0:
return mandelbrot(z ** 2 + c, c, n - 1)
else:
return z ** 2 + c
print("\n".join(["".join(["#" if not math.isnan(mandelbrot(0, x + 1j * y).real) else " "
for x in [a * 0.02 for a in range(-80, 30)]])
for y in [a * 0.05 for a in range(-20, 20)]])
)
Finally, we can also use Matplotlib to visualize the Mandelbrot set with Python:
from pylab import *
from numpy import NaN
def m(a):
z = 0
for n in range(1, 100):
z = z**2 + a
if abs(z) > 2:
return n
return NaN
X = arange(-2, .5, .002)
Y = arange(-1, 1, .002)
Z = zeros((len(Y), len(X)))
for iy, y in enumerate(Y):
print (iy, "of", len(Y))
for ix, x in enumerate(X):
Z[iy,ix] = m(x + 1j * y)
imshow(Z, cmap = plt.cm.prism, interpolation = 'none', extent = (X.min(), X.max(), Y.min(), Y.max()))
xlabel("Re(c)")
ylabel("Im(c)")
savefig("mandelbrot_python.svg")
show()
Another Numpy version using masks to avoid (explicit) nested loops. Runs about 16x faster for the same resolution.
import matplotlib.pyplot as plt
import numpy as np
npts = 300
max_iter = 100
X = np.linspace(-2, 1, 2 * npts)
Y = np.linspace(-1, 1, npts)
#broadcast X to a square array
C = X[:, None] + 1J * Y
#initial value is always zero
Z = np.zeros_like(C)
exit_times = max_iter * np.ones(C.shape, np.int32)
mask = exit_times > 0
for k in range(max_iter):
Z[mask] = Z[mask] * Z[mask] + C[mask]
mask, old_mask = abs(Z) < 2, mask
#use XOR to detect the area which has changed
exit_times[mask ^ old_mask] = k
plt.imshow(exit_times.T,
cmap=plt.cm.prism,
extent=(X.min(), X.max(), Y.min(), Y.max()))
plt.show()
Normal Map Effect, Mercator Projection and Deep Zoom Images
Normalization, Distance Estimation and Boundary Detection
The Mandelbrot set is printed with smooth colors. The e^(-|z|)-smoothing, normalized iteration count and exterior distance estimation algorithms are used with NumPy and complex matrices (see Javier Barrallo & Damien M. Jones: Coloring Algorithms for Dynamical Systems in the Complex Plane and Arnaud Chéritat: Boundary detection methods via distance estimators). Partial antialiasing is used for boundary detection.
import numpy as np
import matplotlib.pyplot as plt
d, h = 800, 500 # pixel density (= image width) and image height
n, r = 200, 500 # number of iterations and escape radius (r > 2)
x = np.linspace(0, 2, num=d+1)
y = np.linspace(0, 2 * h / d, num=h+1)
A, B = np.meshgrid(x - 1, y - h / d)
C = 2.0 * (A + B * 1j) - 0.5
Z, dZ = np.zeros_like(C), np.zeros_like(C)
D, S, T = np.zeros(C.shape), np.zeros(C.shape), np.zeros(C.shape)
for k in range(n):
M = abs(Z) < r
S[M], T[M] = S[M] + np.exp(- abs(Z[M])), T[M] + 1
Z[M], dZ[M] = Z[M] ** 2 + C[M], 2 * Z[M] * dZ[M] + 1
plt.imshow(S ** 0.1, cmap=plt.cm.twilight_shifted, origin="lower")
plt.savefig("Mandelbrot_set_1.png", dpi=200)
N = abs(Z) >= r # normalized iteration count
T[N] = T[N] - np.log2(np.log(np.abs(Z[N])) / np.log(r))
plt.imshow(T ** 0.1, cmap=plt.cm.twilight_shifted, origin="lower")
plt.savefig("Mandelbrot_set_2.png", dpi=200)
N = abs(Z) > 2 # exterior distance estimation
D[N] = np.log(abs(Z[N])) * abs(Z[N]) / abs(dZ[N])
plt.imshow(D ** 0.1, cmap=plt.cm.twilight_shifted, origin="lower")
plt.savefig("Mandelbrot_set_3.png", dpi=200)
N, thickness = D > 0, 0.01 # boundary detection
D[N] = np.maximum(1 - D[N] / thickness, 0)
plt.imshow(D ** 2.0, cmap=plt.cm.binary, origin="lower")
plt.savefig("Mandelbrot_set_4.png", dpi=200)
Normal Map Effect and Stripe Average Coloring
The Mandelbrot set is represented using Normal Maps and Stripe Average Coloring by Jussi Härkönen (cf. Arnaud Chéritat: Normal map effect). Note that the second derivative (ddZ) grows very fast, so the second method can only be used for small iteration numbers (n <= 400). See also the picture in section Mixing it all and Julia Stripes on Shadertoy. To get a stripe pattern similar to that of Arnaud Chéritat, one can increase the density of the stripes, use cos instead of sin, and set the colormap to binary.
import numpy as np
import matplotlib.pyplot as plt
d, h = 800, 500 # pixel density (= image width) and image height
n, r = 200, 500 # number of iterations and escape radius (r > 2)
direction, height = 45.0, 1.5 # direction and height of the light
density, intensity = 4.0, 0.5 # density and intensity of the stripes
x = np.linspace(0, 2, num=d+1)
y = np.linspace(0, 2 * h / d, num=h+1)
A, B = np.meshgrid(x - 1, y - h / d)
C = (2.0 + 1.0j) * (A + B * 1j) - 0.5
Z, dZ, ddZ = np.zeros_like(C), np.zeros_like(C), np.zeros_like(C)
D, S, T = np.zeros(C.shape), np.zeros(C.shape), np.zeros(C.shape)
for k in range(n):
M = abs(Z) < r
S[M], T[M] = S[M] + np.sin(density * np.angle(Z[M])), T[M] + 1
Z[M], dZ[M], ddZ[M] = Z[M] ** 2 + C[M], 2 * Z[M] * dZ[M] + 1, 2 * (dZ[M] ** 2 + Z[M] * ddZ[M])
N = abs(Z) >= r # basic normal map effect and stripe average coloring (potential function)
P, Q = S[N] / T[N], (S[N] + np.sin(density * np.angle(Z[N]))) / (T[N] + 1)
U, V = Z[N] / dZ[N], 1 + (np.log2(np.log(np.abs(Z[N])) / np.log(r)) * (P - Q) + Q) * intensity
U, v = U / abs(U), np.exp(direction / 180 * np.pi * 1j) # unit normal vectors and light vector
D[N] = np.maximum((U.real * v.real + U.imag * v.imag + V * height) / (1 + height), 0)
plt.imshow(D ** 1.0, cmap=plt.cm.bone, origin="lower")
plt.savefig("Mandelbrot_normal_map_1.png", dpi=200)
N = abs(Z) > 2 # advanced normal map effect using higher derivatives (distance estimation)
U = Z[N] * dZ[N] * ((1 + np.log(abs(Z[N]))) * np.conj(dZ[N] ** 2) - np.log(abs(Z[N])) * np.conj(Z[N] * ddZ[N]))
U, v = U / abs(U), np.exp(direction / 180 * np.pi * 1j) # unit normal vectors and light vector
D[N] = np.maximum((U.real * v.real + U.imag * v.imag + height) / (1 + height), 0)
plt.imshow(D ** 1.0, cmap=plt.cm.afmhot, origin="lower")
plt.savefig("Mandelbrot_normal_map_2.png", dpi=200)
Mercator Mandelbrot Maps and Zoom Images
A small change in the code above creates Mercator maps of the Mandelbrot set (see David Madore: Mandelbrot set images and videos and Anders Sandberg: Mercator Mandelbrot Maps). The maximum magnification is about , which is also the maximum for 64-bit arithmetic. Note that Anders Sandberg uses a different scaling. He uses instead of , so his images appear somewhat compressed in comparison (but not much, because ). With the same pixel density and the same maximum magnification, the difference in height between the maps is only about 10 percent. By misusing a scatter plot, it is possible to create zoom images of the Mandelbrot set. See also Mandelbrot sequence new on Wikimedia for a zoom animation to the given coordinates.
import numpy as np
import matplotlib.pyplot as plt
d, h = 200, 1200 # pixel density (= image width) and image height
n, r = 8000, 10000 # number of iterations and escape radius (r > 2)
a = -.743643887037158704752191506114774 # https://mathr.co.uk/web/m-location-analysis.html
b = 0.131825904205311970493132056385139 # try: a, b, n = -1.748764520194788535, 3e-13, 800
x = np.linspace(0, 2, num=d+1)
y = np.linspace(0, 2 * h / d, num=h+1)
A, B = np.meshgrid(x * np.pi, y * np.pi)
C = 8.0 * np.exp((A + B * 1j) * 1j) + (a + b * 1j)
Z, dZ = np.zeros_like(C), np.zeros_like(C)
D = np.zeros(C.shape)
for k in range(n):
M = Z.real ** 2 + Z.imag ** 2 < r ** 2
Z[M], dZ[M] = Z[M] ** 2 + C[M], 2 * Z[M] * dZ[M] + 1
N = abs(Z) > 2 # exterior distance estimation
D[N] = np.log(abs(Z[N])) * abs(Z[N]) / abs(dZ[N])
plt.imshow(D.T ** 0.05, cmap=plt.cm.nipy_spectral, origin="lower")
plt.savefig("Mercator_Mandelbrot_map.png", dpi=200)
X, Y = C.real, C.imag # zoom images (adjust circle size 100 and zoom level 20 as needed)
R, c, z = 100 * (2 / d) * np.pi * np.exp(- B), min(d, h) + 1, max(0, h - d) // 20
fig, ax = plt.subplots(2, 2, figsize=(12, 12))
ax[0,0].scatter(X[1*z:1*z+c,0:d], Y[1*z:1*z+c,0:d], s=R[0:c,0:d]**2, c=D[1*z:1*z+c,0:d]**.5, cmap=plt.cm.nipy_spectral)
ax[0,1].scatter(X[2*z:2*z+c,0:d], Y[2*z:2*z+c,0:d], s=R[0:c,0:d]**2, c=D[2*z:2*z+c,0:d]**.4, cmap=plt.cm.nipy_spectral)
ax[1,0].scatter(X[3*z:3*z+c,0:d], Y[3*z:3*z+c,0:d], s=R[0:c,0:d]**2, c=D[3*z:3*z+c,0:d]**.3, cmap=plt.cm.nipy_spectral)
ax[1,1].scatter(X[4*z:4*z+c,0:d], Y[4*z:4*z+c,0:d], s=R[0:c,0:d]**2, c=D[4*z:4*z+c,0:d]**.2, cmap=plt.cm.nipy_spectral)
plt.savefig("Mercator_Mandelbrot_zoom.png", dpi=100)
Perturbation Theory and Deep Mercator Maps
For deep zoom images it is sufficient to calculate a single point with high accuracy. A good approximation can then be found for all other points by means of a perturbation calculation with standard accuracy. Rebasing is used to reduce glitches. See Perturbation theory (Wikipedia) and Avoiding loss of precision (Fractalshades) for details. See also the image Deeper Mercator Mandelbrot by Anders Sandberg.
import numpy as np
import matplotlib.pyplot as plt
import decimal as dc # decimal floating point arithmetic with arbitrary precision
dc.getcontext().prec = 80 # set precision to 80 digits (about 256 bits)
d, h = 50, 1000 # pixel density (= image width) and image height
n, r = 80000, 100000 # number of iterations and escape radius (r > 2)
a = dc.Decimal("-1.256827152259138864846434197797294538253477389787308085590211144291")
b = dc.Decimal(".37933802890364143684096784819544060002129071484943239316486643285025")
S = np.zeros(n+1, dtype=np.complex128)
u, v = dc.Decimal(0), dc.Decimal(0)
for k in range(n+1):
S[k] = float(u) + float(v) * 1j
if u ** 2 + v ** 2 < r ** 2:
u, v = u ** 2 - v ** 2 + a, 2 * u * v + b
else:
print("The reference sequence diverges within %s iterations." % k)
break
x = np.linspace(0, 2, num=d+1, dtype=np.float64)
y = np.linspace(0, 2 * h / d, num=h+1, dtype=np.float64)
A, B = np.meshgrid(x * np.pi, y * np.pi)
C = 8.0 * np.exp((A + B * 1j) * 1j)
E, Z, dZ = np.zeros_like(C), np.zeros_like(C), np.zeros_like(C)
D, I, J = np.zeros(C.shape), np.zeros(C.shape, dtype=np.int64), np.zeros(C.shape, dtype=np.int64)
for k in range(n):
Z2 = Z.real ** 2 + Z.imag ** 2
M, R = Z2 < r ** 2, Z2 < E.real ** 2 + E.imag ** 2
E[R], I[R] = Z[R], J[R] # rebase when z is closer to zero
E[M], I[M] = (2 * S[I[M]] + E[M]) * E[M] + C[M], I[M] + 1
Z[M], dZ[M] = S[I[M]] + E[M], 2 * Z[M] * dZ[M] + 1
N = abs(Z) > 2 # exterior distance estimation
D[N] = np.log(abs(Z[N])) * abs(Z[N]) / abs(dZ[N])
plt.imshow(D.T ** 0.015, cmap=plt.cm.nipy_spectral, origin="lower")
plt.savefig("Mercator_Mandelbrot_deep_map.png", dpi=200)
You can only rebase to the beginning of the reference sequence. If you want to change from current reference point to reference point , the difference must be calculated. With this subtraction, however, the entire precision is lost due to catastrophic cancellation. Only at the first reference point there is no cancellation because . Therefore, the rebasing condition can also be written as or as . This keeps the differences to the reference sequence as small as possible: rebasing occurs when the distance to reference point is smaller than the distance to the current reference point .
Python - "One liner"
print(
'\n'.join(
''.join(
' *'[(z:=0, c:=x/50+y/50j, [z:=z*z+c for _ in range(99)], abs(z))[-1]<2]
for x in range(-100,25)
)
for y in range(-50,50)
))
Python - "Functional"
Based on the "One liner" approach.
from functools import reduce
def mandelbrot(x, y, c): return ' *'[abs(reduce(lambda z, _: z*z + c, range(99), 0)) < 2]
print('\n'.join(''.join(mandelbrot(x, y, x/50 + y/50j) for x in range(-100, 25)) for y in range(-50, 50)))
q
/adapted from https://www.linkedin.com/pulse/want-work-k-1010data-michal-wallace
q)s:{(.[-]x*x),2*prd x} / complex square (x is R,Im pair)
q)m:{floor sqrt sum x*x} / magnitude (distance from origin)
q)d: 120 60 / dimensions of the picture
q)t: -88 -30 / camera translation
q)f: reciprocal 40 20 / scale factor
q)c: (,/:\:) . f * t + til each d / complex plane near mandelbrot set
q)z: d # enlist 0 0 / 3d array of zeroes in same shape
q)mb: c+ (s'')@ / mandelbrot: s(z) + c
q)r: 1 _ 8 mb\z / collect 8 times
q)o: " 12345678"@ sum 2<m'''[r] / "color" by how soon point "escapes"
q)-1 "\n"sv flip o; / transpose and print the output
555555555555555555555556666666666666665555555555555555555555555555555555555555555555555555555555555666666666666666666666 555555555555555555556666666666666555555555555555555555555555555555555555555555555555555555555555555555556666666666666666 555555555555555556666666666666555555555555555555555555555555555555555555555555555555555555555555555555555556666666666666 555555555555555666666666665555555555555555555555555555555555555555555556666666666666666666555555555555555555555666666666 555555555555666666666666555555555555555555555555555555555555555556666666666666666666666666666665555555555555555556666666 555555555566666666666555555555555555555555555555555555555555566666666555555555555555555555566666665555555555555555556666 555555556666666666655555555555555555555555555555555555556666666655555555555555555555555555555555666665555555555555555566 555555666666666655555555555555555555555555555555555566666666555555555555555554444444444555555555555666665555555555555555 55556666666666555555555555555555555555555555555566666666555555555555555555444432 13344444555555555555666655555555555555 556666666666655555555555555555555555555555555666666665555555555555555554444443321 1222234445555555555556666655555555555 666666666665555555555555555555555555555556666666665555555555555555555444444433321 3344455555555555566666555555555 666666666555555555555555555555555555556666666665555555555555555555544444443332211 22334444455555555555666655555555 666666665555555555555555555555555566666666665555555555555555555544444444333321 12233444444555555555566666555555 6666665555555555555555555555555666666666665555555555555555555444444443333322 123334444444555555555666655555 6666655555555555555555555555666666666665555555555555555554444444433333332221 22333344444445555555566666555 666655555555555555555555566666666666555555555555555554444444443333322222211 11223333333444455555556666655 666555555555555555555556666666666555555555555555544444444444332111 111 11222222 23444555555666665 665555555555555555556666666666555555555555555444444444444333321 11 2334455555566666 655555555555555555666666665555555555555544444444444444433333221 134445555556666 555555555555555566666665555555555555544444444444444433333332211 234444555555666 555555555555556666655555555555555444444444444333333333332221 1233444555555566 55555555555566665555555555555544444332233333333333322222211 1223344455555566 5555555555666555555555555554444443331 1122222111122222111 2344455555556 5555555566655555555555555444444433321 1 344455555556 5555555666555555555555544444444333221 12334455555555 5555566655555555555554444444433332221 2344445555555 555566655555555555444444443333322111 12344445555555 5556665555555554444443333333221 23344445555555 556666555544444443333333322221 233344445555555 55666555444333322 122111111 12233444445555555 55666555 12233444445555555 55666555444333322 122111111 12233444445555555 556666555544444443333333322221 233344445555555 5556665555555554444443333333221 23344445555555 555566655555555555444444443333322111 12344445555555 5555566655555555555554444444433332221 2344445555555 5555555666555555555555544444444333221 12334455555555 5555555566655555555555555444444433321 1 344455555556 5555555555666555555555555554444443331 1122222111122222111 2344455555556 55555555555566665555555555555544444332233333333333322222211 1223344455555566 555555555555556666655555555555555444444444444333333333332221 1233444555555566 555555555555555566666665555555555555544444444444444433333332211 234444555555666 655555555555555555666666665555555555555544444444444444433333221 134445555556666 665555555555555555556666666666555555555555555444444444444333321 11 2334455555566666 666555555555555555555556666666666555555555555555544444444444332111 111 11222222 23444555555666665 666655555555555555555555566666666666555555555555555554444444443333322222211 11223333333444455555556666655 6666655555555555555555555555666666666665555555555555555554444444433333332221 22333344444445555555566666555 6666665555555555555555555555555666666666665555555555555555555444444443333322 123334444444555555555666655555 666666665555555555555555555555555566666666665555555555555555555544444444333321 12233444444555555555566666555555 666666666555555555555555555555555555556666666665555555555555555555544444443332211 22334444455555555555666655555555 666666666665555555555555555555555555555556666666665555555555555555555444444433321 3344455555555555566666555555555 556666666666655555555555555555555555555555555666666665555555555555555554444443321 1222234445555555555556666655555555555 55556666666666555555555555555555555555555555555566666666555555555555555555444432 13344444555555555555666655555555555555 555555666666666655555555555555555555555555555555555566666666555555555555555554444444444555555555555666665555555555555555 555555556666666666655555555555555555555555555555555555556666666655555555555555555555555555555555666665555555555555555566 555555555566666666666555555555555555555555555555555555555555566666666555555555555555555555566666665555555555555555556666 555555555555666666666666555555555555555555555555555555555555555556666666666666666666666666666665555555555555555556666666 555555555555555666666666665555555555555555555555555555555555555555555556666666666666666666555555555555555555555666666666 555555555555555556666666666666555555555555555555555555555555555555555555555555555555555555555555555555555556666666666666 555555555555555555556666666666666555555555555555555555555555555555555555555555555555555555555555555555556666666666666666
R
iterate.until.escape <- function(z, c, trans, cond, max=50, response=dwell) {
#we iterate all active points in the same array operation,
#and keeping track of which points are still iterating.
active <- seq_along(z)
dwell <- z
dwell[] <- 0
for (i in 1:max) {
z[active] <- trans(z[active], c[active]);
survived <- cond(z[active])
dwell[active[!survived]] <- i
active <- active[survived]
if (length(active) == 0) break
}
eval(substitute(response))
}
re = seq(-2, 1, len=500)
im = seq(-1.5, 1.5, len=500)
c <- outer(re, im, function(x,y) complex(real=x, imaginary=y))
x <- iterate.until.escape(array(0, dim(c)), c,
function(z,c)z^2+c, function(z)abs(z) <= 2,
max=100)
image(x)
Mandelbrot Set with R Animation
Modified Mandelbrot set animation by Jarek Tuszynski, PhD. (see: Wikipedia: R (programming_language) and R Tricks: Mandelbrot Set with R Animation)
#install.packages("caTools") # install external package (if missing)
library(caTools) # external package providing write.gif function
jet.colors <- colorRampPalette(c("red", "blue", "#007FFF", "cyan", "#7FFF7F",
"yellow", "#FF7F00", "red", "#7F0000"))
dx <- 800 # define width
dy <- 600 # define height
C <- complex(real = rep(seq(-2.5, 1.5, length.out = dx), each = dy),
imag = rep(seq(-1.5, 1.5, length.out = dy), dx))
C <- matrix(C, dy, dx) # reshape as square matrix of complex numbers
Z <- 0 # initialize Z to zero
X <- array(0, c(dy, dx, 20)) # initialize output 3D array
for (k in 1:20) { # loop with 20 iterations
Z <- Z^2 + C # the central difference equation
X[, , k] <- exp(-abs(Z)) # capture results
}
write.gif(X, "Mandelbrot.gif", col = jet.colors, delay = 100)
Racket
#lang racket
(require racket/draw)
(define (iterations a z i)
(define z′ (+ (* z z) a))
(if (or (= i 255) (> (magnitude z′) 2))
i
(iterations a z′ (add1 i))))
(define (iter->color i)
(if (= i 255)
(make-object color% "black")
(make-object color% (* 5 (modulo i 15)) (* 32 (modulo i 7)) (* 8 (modulo i 31)))))
(define (mandelbrot width height)
(define target (make-bitmap width height))
(define dc (new bitmap-dc% [bitmap target]))
(for* ([x width] [y height])
(define real-x (- (* 3.0 (/ x width)) 2.25))
(define real-y (- (* 2.5 (/ y height)) 1.25))
(send dc set-pen (iter->color (iterations (make-rectangular real-x real-y) 0 0)) 1 'solid)
(send dc draw-point x y))
(send target save-file "mandelbrot.png" 'png))
(mandelbrot 300 200)
Raku
(formerly Perl 6)
Using the hyper statement prefix for concurrency, the code below produces a graymap to standard output.
constant MAX-ITERATIONS = 64;
my $width = +(@*ARGS[0] // 800);
my $height = $width + $width %% 2;
say "P2";
say "$width $height";
say MAX-ITERATIONS;
sub cut(Range $r, UInt $n where $n > 1 --> Seq) {
$r.min, * + ($r.max - $r.min) / ($n - 1) ... $r.max
}
my @re = cut(-2 .. 1/2, $width);
my @im = cut( 0 .. 5/4, 1 + ($height div 2)) X* 1i;
sub mandelbrot(Complex $z is copy, Complex $c --> Int) {
for 1 .. MAX-ITERATIONS {
$z = $z*$z + $c;
return $_ if $z.abs > 2;
}
return 0;
}
my @lines = hyper for @im X+ @re {
mandelbrot(0i, $_);
}.rotor($width);
.put for @lines[1..*].reverse;
.put for @lines;
REXX
version 1
This REXX version doesn't depend on the ASCII sequence of glyphs; an internal character string was used that mimics a part of the ASCII glyph sequence.
/*REXX program generates and displays a Mandelbrot set as an ASCII art character image.*/
@ = '>=<;:9876543210/.-,+*)(''&%$#"!' /*the characters used in the display. */
Xsize = 59; minRE = -2; maxRE = +1; stepX = (maxRE-minRE) / Xsize
Ysize = 21; minIM = -1; maxIM = +1; stepY = (maxIM-minIM) / Ysize
do y=0 for ysize; im=minIM + stepY*y
$=
do x=0 for Xsize; re=minRE + stepX*x; zr=re; zi=im
do n=0 for 30; a=zr**2; b=zi**2; if a+b>4 then leave
zi=zr*zi*2 + im; zr=a-b+re
end /*n*/
$=$ || substr(@, n+1, 1) /*append number (as a char) to $ string*/
end /*x*/
say $ /*display a line of character output.*/
end /*y*/ /*stick a fork in it, we're all done. */
output using the internal defaults:
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<========== >>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<======= >>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== >>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== >>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== >>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== >=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= ><<<<;;;;;:::972456-567763 +9;;<<<<<<< ><;;;;;;::::9875& .3 *9;;;<<<<<< >;;;;;;::997564' ' 8:;;;<<<<<< >::988897735/ &89:;;;<<<<<< >::988897735/ &89:;;;<<<<<< >;;;;;;::997564' ' 8:;;;<<<<<< ><;;;;;;::::9875& .3 *9;;;<<<<<< ><<<<;;;;;:::972456-567763 +9;;<<<<<<< >=<<<<<<<<;;;:599999999886 %78:;;<<<<<<= >>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<== >>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<=== >>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<==== >>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<====== >>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<=======
version 2
This REXX version uses glyphs that are "darker" (with a white background) around the output's peripheral.
/*REXX program generates and displays a Mandelbrot set as an ASCII art character image.*/
@ = '█▓▒░@9876543210=.-,+*)(·&%$#"!' /*the characters used in the display. */
Xsize = 59; minRE = -2; maxRE = +1; stepX = (maxRE-minRE) / Xsize
Ysize = 21; minIM = -1; maxIM = +1; stepY = (maxIM-minIM) / Ysize
do y=0 for ysize; im=minIM + stepY*y
$=
do x=0 for Xsize; re=minRE + stepX*x; zr=re; zi=im
do n=0 for 30; a=zr**2; b=zi**2; if a+b>4 then leave
zi=zr*zi*2 + im; zr=a-b+re
end /*n*/
$=$ || substr(@, n+1, 1) /*append number (as a char) to $ string*/
end /*x*/
say $ /*display a line of character output.*/
end /*y*/ /*stick a fork in it, we're all done. */
output using the internal defaults:
██████▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░@@@96032@░░░░▒▒▒▒▓▓▓▓▓▓▓▓▓▓ █████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@@873*079@@░░░░▒▒▒▒▒▓▓▓▓▓▓▓ ████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@9974 (.9@@@@░░▒▒▒▒▒▓▓▓▓▓▓ ███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░@98888764 5789999@░░▒▒▒▒▒▓▓▓▓ ██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░@@@@996. &2 45335@░▒▒▒▒▒▒▓▓▓ ██▓▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@999752 *79@░▒▒▒▒▒▒▓▓ █▓▒▒▒▒▒▒▒▒░░░@599999999886 %78@░░▒▒▒▒▒▒▓ █▒▒▒▒░░░░░@@@972456-567763 +9░░▒▒▒▒▒▒▒ █▒░░░░░░@@@@9875& .3 *9░░░▒▒▒▒▒▒ █░░░░░░@@997564· · 8@░░░▒▒▒▒▒▒ █@@988897735= &89@░░░▒▒▒▒▒▒ █@@988897735= &89@░░░▒▒▒▒▒▒ █░░░░░░@@997564· · 8@░░░▒▒▒▒▒▒ █▒░░░░░░@@@@9875& .3 *9░░░▒▒▒▒▒▒ █▒▒▒▒░░░░░@@@972456-567763 +9░░▒▒▒▒▒▒▒ █▓▒▒▒▒▒▒▒▒░░░@599999999886 %78@░░▒▒▒▒▒▒▓ ██▓▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@999752 *79@░▒▒▒▒▒▒▓▓ ██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░@@@@996. &2 45335@░▒▒▒▒▒▒▓▓▓ ███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░@98888764 5789999@░░▒▒▒▒▒▓▓▓▓ ████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@9974 (.9@@@@░░▒▒▒▒▒▓▓▓▓▓▓ █████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@@873*079@@░░░░▒▒▒▒▒▓▓▓▓▓▓▓
version 3
This REXX version produces a larger output (it uses the full width of the terminal screen (less one), and the height is one-half of the width.
/*REXX program generates and displays a Mandelbrot set as an ASCII art character image.*/
@ = '█▓▒░@9876543210=.-,+*)(·&%$#"!' /*the characters used in the display. */
parse arg Xsize Ysize . /*obtain optional arguments from the CL*/
if Xsize=='' then Xsize=linesize() - 1 /*X: the (usable) linesize (minus 1).*/
if Ysize=='' then Ysize=Xsize%2 + (Xsize//2==1) /*Y: half the linesize (make it even).*/
minRE = -2; maxRE = +1; stepX = (maxRE-minRE) / Xsize
minIM = -1; maxIM = +1; stepY = (maxIM-minIM) / Ysize
do y=0 for ysize; im=minIM + stepY*y
$=
do x=0 for Xsize; re=minRE + stepX*x; zr=re; zi=im
do n=0 for 30; a=zr**2; b=zi**2; if a+b>4 then leave
zi=zr*zi*2 + im; zr=a-b+re
end /*n*/
$=$ || substr(@, n+1, 1) /*append number (as a char) to $ string*/
end /*x*/
say $ /*display a line of character output.*/
end /*y*/ /*stick a fork in it, we're all done. */
output using the internal defaults:
████████▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░@@@@985164(9@░░░░░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ███████▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@@@98763=5799@░░░░░░▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓ ███████▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@@98763.-2789@@@░░░░░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓ ██████▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@@985 2. 1448@@@@░░░░░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓ █████▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@999874 *=79@@@@@░░░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓ █████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@999998873 17899@@@@@░░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓ ████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@98888888764 #4678899999@@░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓ ████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@@@9343,665 322= =215357888709@░░▒▒▒▒▒▒▒▒▓▓▓▓▓ ███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░@@@@@9986 + 32 ,56554)79@░▒▒▒▒▒▒▒▒▒▓▓▓▓ ███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░@@@@@@@999863 + 2· ",59@░░▒▒▒▒▒▒▒▒▓▓▓▓ ███▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@@@@@9998763 $ 379@@░▒▒▒▒▒▒▒▒▒▓▓▓ ██▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@@@@@999986.2 $ +689@@░░▒▒▒▒▒▒▒▒▒▓▓ ██▓▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@689999@@@99999887 05789@░░▒▒▒▒▒▒▒▒▒▓▓ ██▒▒▒▒▒▒▒▒▒▒░░░░░@@9717888877888888763. 2558@░░░▒▒▒▒▒▒▒▒▒▓ █▓▒▒▒▒▒▒░░░░░░░@@@996)566761467777762 4@░░░▒▒▒▒▒▒▒▒▒▓ █▓▒▒▒▒░░░░░░░░@@@@99763 & 42&..366651· .68@░░░░▒▒▒▒▒▒▒▒▓ █▒▒▒░░░░░░░░@@@@@@98864* ) $ 343 259@░░░░▒▒▒▒▒▒▒▒▒ █▒▒░░░░░░░░@@@@@@988753. 11 #9@░░░░▒▒▒▒▒▒▒▒▒ █▒░░░░░░░░@@@@@9877650 - 289@░░░░▒▒▒▒▒▒▒▒▒ █░░░░░░░░@9999887%413+ % &69@@░░░░▒▒▒▒▒▒▒▒▒ █░@@@@@89999888763 % ( 389@@░░░░▒▒▒▒▒▒▒▒▒ █@@99872676676422 5789@@░░░░▒▒▒▒▒▒▒▒▒ █@@99872676676422 5789@@░░░░▒▒▒▒▒▒▒▒▒ █░@@@@@89999888763 % ( 389@@░░░░▒▒▒▒▒▒▒▒▒ █░░░░░░░░@9999887%413+ % &69@@░░░░▒▒▒▒▒▒▒▒▒ █▒░░░░░░░░@@@@@9877650 - 289@░░░░▒▒▒▒▒▒▒▒▒ █▒▒░░░░░░░░@@@@@@988753. 11 #9@░░░░▒▒▒▒▒▒▒▒▒ █▒▒▒░░░░░░░░@@@@@@98864* ) $ 343 259@░░░░▒▒▒▒▒▒▒▒▒ █▓▒▒▒▒░░░░░░░░@@@@99763 & 42&..366651· .68@░░░░▒▒▒▒▒▒▒▒▓ █▓▒▒▒▒▒▒░░░░░░░@@@996)566761467777762 4@░░░▒▒▒▒▒▒▒▒▒▓ ██▒▒▒▒▒▒▒▒▒▒░░░░░@@9717888877888888763. 2558@░░░▒▒▒▒▒▒▒▒▒▓ ██▓▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@689999@@@99999887 05789@░░▒▒▒▒▒▒▒▒▒▓▓ ██▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@@@@@999986.2 $ +689@@░░▒▒▒▒▒▒▒▒▒▓▓ ███▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░@@@@@@@@@@9998763 $ 379@@░▒▒▒▒▒▒▒▒▒▓▓▓ ███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░@@@@@@@999863 + 2· ",59@░░▒▒▒▒▒▒▒▒▓▓▓▓ ███▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░@@@@@9986 + 32 ,56554)79@░▒▒▒▒▒▒▒▒▒▓▓▓▓ ████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░@@@@9343,665 322= =215357888709@░░▒▒▒▒▒▒▒▒▓▓▓▓▓ ████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@98888888764 #4678899999@@░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓ █████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@999998873 17899@@@@@░░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓ █████▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@999874 *=79@@@@@░░░░▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓ ██████▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@@985 2. 1448@@@@░░░░░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓ ███████▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░@@@@98763.-2789@@@░░░░░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓ ███████▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░@@@@98763=5799@░░░░░░▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓
This REXX program makes use of linesize REXX program (or BIF) which is used to determine the screen width (or linesize) of the terminal (console).
The LINESIZE.REX REXX program is included here ──► LINESIZE.REX.
Ring
load "guilib.ring"
new qapp
{
win1 = new qwidget() {
setwindowtitle("Mandelbrot set")
setgeometry(100,100,500,500)
label1 = new qlabel(win1) {
setgeometry(10,10,400,400)
settext("")
}
new qpushbutton(win1) {
setgeometry(200,400,100,30)
settext("draw")
setclickevent("draw()")
}
show()
}
exec()
}
func draw
p1 = new qpicture()
color = new qcolor() {
setrgb(0,0,255,255)
}
pen = new qpen() {
setcolor(color)
setwidth(1)
}
new qpainter() {
begin(p1)
setpen(pen)
x1=300 y1=250
i1=-1 i2=1 r1=-2 r2=1
s1=(r2-r1)/x1 s2=(i2-i1)/y1
for y=0 to y1
i3=i1+s2*y
for x=0 to x1
r3=r1+s1*x z1=r3 z2=i3
for n=0 to 30
a=z1*z1 b=z2*z2
if a+b>4 exit ok
z2=2*z1*z2+i3 z1=a-b+r3
next
if n != 31 drawpoint(x,y) ok
next
next
endpaint()
}
label1 { setpicture(p1) show() }
Output:
Ruby
Text only, prints an 80-char by 41-line depiction. Found here.
require 'complex'
def mandelbrot(a)
Array.new(50).inject(0) { |z,c| z*z + a }
end
(1.0).step(-1,-0.05) do |y|
(-2.0).step(0.5,0.0315) do |x|
print mandelbrot(Complex(x,y)).abs < 2 ? '*' : ' '
end
puts
end
Uses Raster graphics operations/Ruby
# frozen_string_literal: true
require_relative 'raster_graphics'
class RGBColour
def self.mandel_colour(i)
self.new( 16*(i % 15), 32*(i % 7), 8*(i % 31) )
end
end
class Pixmap
def self.mandelbrot(width, height)
mandel = Pixmap.new(width,height)
pb = ProgressBar.new(width) if $DEBUG
width.times do |x|
height.times do |y|
x_ish = Float(x - width*11/15) / (width/3)
y_ish = Float(y - height/2) / (height*3/10)
mandel[x,y] = RGBColour.mandel_colour(mandel_iters(x_ish, y_ish))
end
pb.update(x) if $DEBUG
end
pb.close if $DEBUG
mandel
end
def self.mandel_iters(cx,cy)
x = y = 0.0
count = 0
while Math.hypot(x,y) < 2 and count < 255
x, y = (x**2 - y**2 + cx), (2*x*y + cy)
count += 1
end
count
end
end
Pixmap.mandelbrot(300,300).save('mandel.ppm')
JRubyArt is a port of processing to ruby
# frozen_string_literal: true
def setup
sketch_title 'Mandelbrot'
load_pixels
no_loop
end
def draw
grid(900, 600) do |x, y|
const = Complex(
map1d(x, (0...900), (-3..1.5)), map1d(y, (0...600), (-1.5..1.5))
)
pixels[x + y * 900] = color(
constrained_map(mandel(const, 20), (5..20), (255..0))
)
end
update_pixels
end
def mandel(z, max)
score = 0
const = z
while score < max
# z = z^2 + c
z *= z
z += const
break if z.abs > 2
score += 1
end
score
end
def settings
size(900, 600)
end
Rust
Dependencies: image, num-complex
extern crate image;
extern crate num_complex;
use num_complex::Complex;
fn main() {
let max_iterations = 256u16;
let img_side = 800u32;
let cxmin = -2f32;
let cxmax = 1f32;
let cymin = -1.5f32;
let cymax = 1.5f32;
let scalex = (cxmax - cxmin) / img_side as f32;
let scaley = (cymax - cymin) / img_side as f32;
// Create a new ImgBuf
let mut imgbuf = image::ImageBuffer::new(img_side, img_side);
// Calculate for each pixel
for (x, y, pixel) in imgbuf.enumerate_pixels_mut() {
let cx = cxmin + x as f32 * scalex;
let cy = cymin + y as f32 * scaley;
let c = Complex::new(cx, cy);
let mut z = Complex::new(0f32, 0f32);
let mut i = 0;
for t in 0..max_iterations {
if z.norm() > 2.0 {
break;
}
z = z * z + c;
i = t;
}
*pixel = image::Luma([i as u8]);
}
// Save image
imgbuf.save("fractal.png").unwrap();
}
Sass/SCSS
$canvasWidth: 200;
$canvasHeight: 200;
$iterations: 20;
$xCorner: -2;
$yCorner: -1.5;
$zoom: 3;
$data: ()!global;
@mixin plot ($x,$y,$count){
$index: ($y * $canvasWidth + $x) * 4;
$r: $count * -12 + 255;
$g: $count * -12 + 255;
$b: $count * -12 + 255;
$data: append($data, $x + px $y + px 0 rgb($r,$g,$b), comma)!global;
}
@for $x from 1 to $canvasWidth {
@for $y from 1 to $canvasHeight {
$count: 0;
$size: 0;
$cx: $xCorner + (($x * $zoom) / $canvasWidth);
$cy: $yCorner + (($y * $zoom) / $canvasHeight);
$zx: 0;
$zy: 0;
@while $count < $iterations and $size <= 4 {
$count: $count + 1;
$temp: ($zx * $zx) - ($zy * $zy);
$zy: (2 * $zx * $zy) + $cy;
$zx: $temp + $cx;
$size: ($zx * $zx) + ($zy * $zy);
}
@include plot($x, $y, $count);
}
}
.set {
height: 1px;
width: 1px;
position: absolute;
top: 50%;
left: 50%;
transform: translate($canvasWidth*0.5px, $canvasWidth*0.5px);
box-shadow: $data;
}
Scala
Uses RgbBitmap from Basic Bitmap Storage task and Complex number class from this programming task.
import org.rosettacode.ArithmeticComplex._
import java.awt.Color
object Mandelbrot
{
def generate(width:Int =600, height:Int =400)={
val bm=new RgbBitmap(width, height)
val maxIter=1000
val xMin = -2.0
val xMax = 1.0
val yMin = -1.0
val yMax = 1.0
val cx=(xMax-xMin)/width
val cy=(yMax-yMin)/height
for(y <- 0 until bm.height; x <- 0 until bm.width){
val c=Complex(xMin+x*cx, yMin+y*cy)
val iter=itMandel(c, maxIter, 4)
bm.setPixel(x, y, getColor(iter, maxIter))
}
bm
}
def itMandel(c:Complex, imax:Int, bailout:Int):Int={
var z=Complex()
for(i <- 0 until imax){
z=z*z+c;
if(z.abs > bailout) return i
}
imax;
}
def getColor(iter:Int, max:Int):Color={
if (iter==max) return Color.BLACK
var c=3*math.log(iter)/math.log(max-1.0)
if(c<1) new Color((255*c).toInt, 0, 0)
else if(c<2) new Color(255, (255*(c-1)).toInt, 0)
else new Color(255, 255, (255*(c-2)).toInt)
}
}
Read–eval–print loop
import scala.swing._
import javax.swing.ImageIcon
val imgMandel=Mandelbrot.generate()
val mainframe=new MainFrame(){title="Test"; visible=true
contents=new Label(){icon=new ImageIcon(imgMandel.image)}
}
Scheme
A simple implementation for many Scheme implementations
This implementation writes an image of the Mandelbrot set to a plain pgm file. The set itself is drawn in white, while the exterior is drawn in black.
(define x-centre -0.5)
(define y-centre 0.0)
(define width 4.0)
(define i-max 800)
(define j-max 600)
(define n 100)
(define r-max 2.0)
(define file "out.pgm")
(define colour-max 255)
(define pixel-size (/ width i-max))
(define x-offset (- x-centre (* 0.5 pixel-size (+ i-max 1))))
(define y-offset (+ y-centre (* 0.5 pixel-size (+ j-max 1))))
(define (inside? z)
(define (*inside? z-0 z n)
(and (< (magnitude z) r-max)
(or (= n 0)
(*inside? z-0 (+ (* z z) z-0) (- n 1)))))
(*inside? z 0 n))
(define (boolean->integer b)
(if b colour-max 0))
(define (pixel i j)
(boolean->integer
(inside?
(make-rectangular (+ x-offset (* pixel-size i))
(- y-offset (* pixel-size j))))))
(define (plot)
(with-output-to-file file
(lambda ()
(begin (display "P2") (newline)
(display i-max) (newline)
(display j-max) (newline)
(display colour-max) (newline)
(do ((j 1 (+ j 1))) ((> j j-max))
(do ((i 1 (+ i 1))) ((> i i-max))
(begin (display (pixel i j)) (newline))))))))
(plot)
An interactive program for CHICKEN Scheme
You will need several CHICKEN "eggs", which can be deduced from the imports.
Compile with (for example) csc -O3 mandelbrot_task_CHICKEN.scm
.
;; A program written for CHICKEN Scheme version 5.3.0 and various
;; eggs.
(import (r7rs))
(import (scheme base))
(import (scheme case-lambda))
(import (scheme inexact))
(import (prefix sdl2 "sdl2:"))
(import (prefix imlib2 "imlib2:"))
(import (format))
(import (matchable))
(import (simple-exceptions))
(define sdl2-subsystems-used '(events video))
;; ------------------------------
;; Basics for using the sdl2 egg:
(sdl2:set-main-ready!)
(sdl2:init! sdl2-subsystems-used)
(on-exit sdl2:quit!)
(current-exception-handler
(let ((original-handler (current-exception-handler)))
(lambda (exception)
(sdl2:quit!)
(original-handler exception))))
;; ------------------------------
(define-record-type <mandel-params>
(%%make-mandel-params)
mandel-params?
(window ref-window set-window!)
(xcenter ref-xcenter set-xcenter!)
(ycenter ref-ycenter set-ycenter!)
(pixels-per-unit ref-pixels-per-unit set-pixels-per-unit!)
(pixels-per-event-check ref-pixels-per-event-check
set-pixels-per-event-check!)
(max-escape-time ref-max-escape-time set-max-escape-time!))
(define initial-width 400)
(define initial-height 400)
(define initial-xcenter -3/4)
(define initial-ycenter 0)
(define initial-pixels-per-unit 150)
(define initial-pixels-per-event-check 1000)
(define initial-max-escape-time 1000)
(define (make-mandel-params window)
(let ((params (%%make-mandel-params)))
(set-window! params window)
(set-xcenter! params initial-xcenter)
(set-ycenter! params initial-ycenter)
(set-pixels-per-unit! params initial-pixels-per-unit)
(set-pixels-per-event-check! params
initial-pixels-per-event-check)
(set-max-escape-time! params initial-max-escape-time)
params))
(define window (sdl2:create-window! "mandelbrot set task"
'centered 'centered
initial-width initial-height
'()))
(define params (make-mandel-params window))
(define empty-color (sdl2:make-color 200 200 200))
(define (clear-mandel!)
(sdl2:fill-rect! (sdl2:window-surface (ref-window params))
#f empty-color)
(sdl2:update-window-surface! window))
(define drawing? #t)
(define redraw? #f)
(define (draw-mandel! event-checker)
(clear-mandel!)
(let repeat ()
(let*-values
(((window) (ref-window params))
((width height) (sdl2:window-size window)))
(let* ((xcenter (ref-xcenter params))
(ycenter (ref-ycenter params))
(pixels-per-unit (ref-pixels-per-unit params))
(pixels-per-event-check
(ref-pixels-per-event-check params))
(max-escape-time (ref-max-escape-time params))
(step (/ 1.0 pixels-per-unit))
(xleft (- xcenter (/ width (* 2.0 pixels-per-unit))))
(ytop (+ ycenter (/ height (* 2.0 pixels-per-unit))))
(pixel-count 0))
(do ((j 0 (+ j 1))
(cy ytop (- cy step)))
((= j height))
(do ((i 0 (+ i 1))
(cx xleft (+ cx step)))
((= i width))
(let* ((color (compute-color-by-escape-time-algorithm
cx cy max-escape-time)))
(sdl2:surface-set! (sdl2:window-surface window)
i j color)
(if (= pixel-count pixels-per-event-check)
(let ((event-checker (call/cc event-checker)))
(cond (redraw?
(set! redraw? #f)
(clear-mandel!)
(repeat)))
(set! pixel-count 0))
(set! pixel-count (+ pixel-count 1)))))
;; Display a row.
(sdl2:update-window-surface! window))))
(set! drawing? #f)
(repeat)))
(define (compute-color-by-escape-time-algorithm
cx cy max-escape-time)
(escape-time->color (compute-escape-time cx cy max-escape-time)
max-escape-time))
(define (compute-escape-time cx cy max-escape-time)
(let loop ((x 0.0)
(y 0.0)
(iter 0))
(if (= iter max-escape-time)
iter
(let ((xsquared (* x x))
(ysquared (* y y)))
(if (< 4 (+ xsquared ysquared))
iter
(let ((x (+ cx (- xsquared ysquared)))
(y (+ cy (* (+ x x) y))))
(loop x y (+ iter 1))))))))
(define (escape-time->color escape-time max-escape-time)
;; This is a very naive and ad hoc algorithm for choosing colors,
;; but hopefully will suffice for the task. With this algorithm, at
;; least one can zoom in and see some of the fractal-like structures
;; out on the filaments.
(let* ((initial-ppu initial-pixels-per-unit)
(ppu (ref-pixels-per-unit params))
(fraction (* (/ (log escape-time) (log max-escape-time))))
(fraction (if (= fraction 1.0)
fraction
(* fraction
(/ (log initial-ppu)
(log (max initial-ppu (* 0.05 ppu)))))))
(value (- 255 (min 255 (exact-rounded (* fraction 255))))))
(sdl2:make-color value value value)))
(define (exact-rounded x)
(exact (round x)))
(define (event-loop)
(define event (sdl2:make-event))
(define painter draw-mandel!)
(define zoom-ratio 2)
(define (recenter! xcoord ycoord)
(let*-values
(((window) (ref-window params))
((width height) (sdl2:window-size window))
((ppu) (ref-pixels-per-unit params)))
(set-xcenter! params
(+ (ref-xcenter params)
(/ (- (* 2.0 xcoord) width) (* 2.0 ppu))))
(set-ycenter! params
(+ (ref-ycenter params)
(/ (- height (* 2.0 ycoord)) (* 2.0 ppu))))))
(define (zoom-in!)
(let* ((ppu (ref-pixels-per-unit params))
(ppu (* ppu zoom-ratio)))
(set-pixels-per-unit! params ppu)))
(define (zoom-out!)
(let* ((ppu (ref-pixels-per-unit params))
(ppu (* (/ 1.0 zoom-ratio) ppu)))
(set-pixels-per-unit! params (max 1 ppu))))
(define (restore-original-settings!)
(set-xcenter! params initial-xcenter)
(set-ycenter! params initial-ycenter)
(set-pixels-per-unit! params initial-pixels-per-unit)
(set-pixels-per-event-check!
params initial-pixels-per-event-check)
(set-max-escape-time! params initial-max-escape-time)
(set! zoom-ratio 2))
(define dump-image! ; Really this should put up a dialog.
(let ((dump-number 1))
(lambda ()
(let*-values
(((window) (ref-window params))
((width height) (sdl2:window-size window))
((surface) (sdl2:window-surface window)))
(let ((filename (string-append "mandelbrot-image-"
(number->string dump-number)
".png"))
(img (imlib2:image-create width height)))
(do ((j 0 (+ j 1)))
((= j height))
(do ((i 0 (+ i 1)))
((= i width))
(let-values
(((r g b a) (sdl2:color->values
(sdl2:surface-ref surface i j))))
(imlib2:image-draw-pixel
img (imlib2:color/rgba r g b a) i j))))
(imlib2:image-alpha-set! img #f)
(imlib2:image-save img filename)
(format #t "~a written~%" filename)
(set! dump-number (+ dump-number 1)))))))
(let loop ()
(when redraw?
(set! drawing? #t))
(when drawing?
(set! painter (call/cc painter)))
(set! redraw? #f)
(if (not (sdl2:poll-event! event))
(loop)
(begin
(match (sdl2:event-type event)
('quit) ; Quit by leaving the loop.
('window
(match (sdl2:window-event-event event)
;; It should be possible to resize the window, but I
;; have not yet figured out how to do this with SDL2
;; and not crash sometimes.
((or 'exposed 'restored)
(sdl2:update-window-surface! (ref-window params))
(loop))
(_ (loop))))
('mouse-button-down
(recenter! (sdl2:mouse-button-event-x event)
(sdl2:mouse-button-event-y event))
(set! redraw? #t)
(loop))
('key-down
(match (sdl2:keyboard-event-sym event)
('q 'quit-by-leaving-the-loop)
((or 'plus 'kp-plus)
(zoom-in!)
(set! redraw? #t)
(loop))
((or 'minus 'kp-minus)
(zoom-out!)
(set! redraw? #t)
(loop))
((or 'n-2 'kp-2)
(set! zoom-ratio 2)
(loop))
((or 'n-3 'kp-3)
(set! zoom-ratio 3)
(loop))
((or 'n-4 'kp-4)
(set! zoom-ratio 4)
(loop))
((or 'n-5 'kp-5)
(set! zoom-ratio 5)
(loop))
((or 'n-6 'kp-6)
(set! zoom-ratio 6)
(loop))
((or 'n-7 'kp-7)
(set! zoom-ratio 7)
(loop))
((or 'n-8 'kp-8)
(set! zoom-ratio 8)
(loop))
((or 'n-9 'kp-9)
(set! zoom-ratio 9)
(loop))
('o
(restore-original-settings!)
(set! redraw? #t)
(loop))
('p
(dump-image!)
(loop))
(some-key-in-which-we-are-not-interested
(loop))))
(some-event-in-which-we-are-not-interested
(loop)))))))
;; At the least this legend should go in a window, but printing it to
;; the terminal will, hopefully, suffice for the task.
(format #t "~%~8tACTIONS~%")
(format #t "~8t-------~%")
(define fmt "~2t~a~15t: ~a~%")
(format #t fmt "Q key" "quit")
(format #t fmt "mouse button" "recenter")
(format #t fmt "+ key" "zoom in")
(format #t fmt "- key" "zoom in")
(format #t fmt "2 .. 9 key" "set zoom ratio")
(format #t fmt "O key" "restore original")
(format #t fmt "P key" "dump to a PNG")
(format #t "~%")
(event-loop)
- Output:
An example of a PNG dumped by the program while it was zoomed in:
![A zoomed-in picture of a part of the Mandelbrot set.](http://static.miraheze.org/rosettacodewiki/thumb/9/93/Mandelbrot_task_CHICKEN_sampleimage.png/300px-Mandelbrot_task_CHICKEN_sampleimage.png)
Scratch
Seed7
$ include "seed7_05.s7i"; include "float.s7i"; include "complex.s7i"; include "draw.s7i"; include "keybd.s7i"; # Display the Mandelbrot set, that are points z[0] in the complex plane # for which the sequence z[n+1] := z[n] ** 2 + z[0] (n >= 0) is bounded. # Since this program is computing intensive it should be compiled with # s7c -O2 mandelbr const integer: pix is 200; const integer: max_iter is 256; var array color: colorTable is max_iter times black; const func integer: iterate (in complex: z0) is func result var integer: iter is 1; local var complex: z is complex.value; begin z := z0; while sqrAbs(z) < 4.0 and # not diverged iter < max_iter do # not converged z *:= z; z +:= z0; incr(iter); end while; end func; const proc: displayMandelbrotSet (in complex: center, in float: zoom) is func local var integer: x is 0; var integer: y is 0; var complex: z0 is complex.value; begin for x range -pix to pix do for y range -pix to pix do z0 := center + complex(flt(x) * zoom, flt(y) * zoom); point(x + pix, y + pix, colorTable[iterate(z0)]); end for; end for; end func; const proc: main is func local const integer: num_pix is 2 * pix + 1; var integer: col is 0; begin screen(num_pix, num_pix); clear(curr_win, black); KEYBOARD := GRAPH_KEYBOARD; for col range 1 to pred(max_iter) do colorTable[col] := color(65535 - (col * 5003) mod 65535, (col * 257) mod 65535, (col * 2609) mod 65535); end for; displayMandelbrotSet(complex(-0.75, 0.0), 1.3 / flt(pix)); flushGraphic; readln(KEYBOARD); end func;
Original source: [1]
SenseTalk
put 0 into oReal # Real origin
put 0 into oImag # Imaginary origin
put 0.5 into mag # Magnification
put oReal - .8 / mag into leftReal
put oImag + .5 / mag into topImag
put 1 / 200 / mag into inc
put [
(0,255,255), # aqua
(0,0,255), # blue
(255,0,255), # fuchsia
(128,128,128), # gray
(0,128,0), # green
(0,255,0), # lime
(128,0,0), # maroon
(0,0,128), # navy
(128,128,0), # olive
(128,0,128), # purple
(255,0,0), # red
(192,192,192), # silver
(0,128,128), # teal
(255,255,255), # white
(255,255,0) # yellow
] into colors
put "mandelbrot.ppm" into myFile
open file myFile for writing
write "P3" & return to file myFile # PPM file magic number
write "320 200" & return to file myFile # Width and height
write "255" & return to file myFile # Max value in color channels
put topImag into cImag
repeat with each item in 1 .. 200
put leftReal into cReal
repeat with each item in 1 .. 320
put 0 into zReal
put 0 into zImag
put 0 into count
put 0 into size
repeat at least once until size > 2 or count = 100
put zReal squared + zImag squared * -1 into newZreal
put zReal * zImag + zReal * zImag into newZimag
put newZreal + cReal into zReal
put newZimag + cImag into zImag
put sqrt(zReal squared + zImag squared) into size
add 1 to count
end repeat
if size > 2 then # Outside the set - colorize
put item count mod 15 + 1 of colors into color
write color joined by " " to file myFile
write return to file myFile
else # Inside the set - black
write "0 0 0" & return to file myFile
end if
add inc to cReal
end repeat
subtract inc from cImag
end repeat
close file myFile
SequenceL
SequenceL Code for Computing and Coloring:
import <Utilities/Complex.sl>;
import <Utilities/Sequence.sl>;
import <Utilities/Math.sl>;
COLOR_STRUCT ::= (R: int(0), G: int(0), B: int(0));
rgb(r(0), g(0), b(0)) := (R: r, G: g, B: b);
RESULT_STRUCT ::= (FinalValue: Complex(0), Iterations: int(0));
makeResult(val(0), iters(0)) := (FinalValue: val, Iterations: iters);
zSquaredOperation(startingNum(0), currentNum(0)) :=
complexAdd(startingNum, complexMultiply(currentNum, currentNum));
zSquared(minX(0), maxX(0), resolutionX(0), minY(0), maxY(0), resolutionY(0), maxMagnitude(0), maxIters(0))[Y,X] :=
let
stepX := (maxX - minX) / resolutionX;
stepY := (maxY - minY) / resolutionY;
currentX := X * stepX + minX;
currentY := Y * stepY + minY;
in
operateUntil(zSquaredOperation, makeComplex(currentX, currentY), makeComplex(currentX, currentY), maxMagnitude, 0, maxIters)
foreach Y within 0 ... (resolutionY - 1),
X within 0 ... (resolutionX - 1);
operateUntil(operation(0), startingNum(0), currentNum(0), maxMagnitude(0), currentIters(0), maxIters(0)) :=
let
operated := operation(startingNum, currentNum);
in
makeResult(currentNum, maxIters) when currentIters >= maxIters
else
makeResult(currentNum, currentIters) when complexMagnitude(currentNum) >= maxMagnitude
else
operateUntil(operation, startingNum, operated, maxMagnitude, currentIters + 1, maxIters);
//region Smooth Coloring
COLOR_COUNT := size(colorSelections);
colorRange := range(0, 255, 1);
colors :=
let
first[i] := rgb(0, 0, i) foreach i within colorRange;
second[i] := rgb(i, i, 255) foreach i within colorRange;
third[i] := rgb(255, 255, i) foreach i within reverse(colorRange);
fourth[i] := rgb(255, i, 0) foreach i within reverse(colorRange);
fifth[i] := rgb(i, 0, 0) foreach i within reverse(colorRange);
red[i] := rgb(i, 0, 0) foreach i within colorRange;
redR[i] := rgb(i, 0, 0) foreach i within reverse(colorRange);
green[i] := rgb(0, i, 0) foreach i within colorRange;
greenR[i] :=rgb(0, i, 0) foreach i within reverse(colorRange);
blue[i] := rgb(0, 0, i) foreach i within colorRange;
blueR[i] := rgb(0, 0, i) foreach i within reverse(colorRange);
in
//red ++ redR ++ green ++ greenR ++ blue ++ blueR;
first ++ second ++ third ++ fourth ++ fifth;
//first ++ fourth;
colorSelections := range(1, size(colors), 30);
getSmoothColorings(zSquaredResult(2), maxIters(0))[Y,X] :=
let
current := zSquaredResult[Y,X];
zn := complexMagnitude(current.FinalValue);
nu := ln(ln(zn) / ln(2)) / ln(2);
result := abs(current.Iterations + 1 - nu);
index := floor(result);
rem := result - index;
color1 := colorSelections[(index mod COLOR_COUNT) + 1];
color2 := colorSelections[((index + 1) mod COLOR_COUNT) + 1];
in
rgb(0, 0, 0) when current.Iterations = maxIters
else
colors[color1] when color2 < color1
else
colors[floor(linearInterpolate(color1, color2, rem))];
linearInterpolate(v0(0), v1(0), t(0)) := (1 - t) * v0 + t * v1;
//endregion
C++ Driver Code:
#include "SL_Generated.h"
#include "../../../ThirdParty/CImg/CImg.h"
using namespace std;
using namespace cimg_library;
int main(int argc, char ** argv)
{
int cores = 0;
Sequence<Sequence<_sl_RESULT_STRUCT> > computeResult;
Sequence<Sequence<_sl_COLOR_STRUCT> > colorResult;
sl_init(cores);
int maxIters = 1000;
int imageWidth = 1920;
int imageHeight = 1200;
double maxMag = 256;
double xmin = -2.5;
double xmax = 1.0;
double ymin = -1.0;
double ymax = 1.0;
CImg<unsigned char> visu(imageWidth, imageHeight, 1, 3);
CImgDisplay draw_disp(visu, "Mandelbrot Fractal in SequenceL");
bool redraw = true;
SLTimer t;
double computeTime;
double colorTime;
double renderTime;
while(!draw_disp.is_closed())
{
if(redraw)
{
redraw = false;
t.start();
sl_zSquared(xmin, xmax, imageWidth, ymin, ymax, imageHeight, maxMag, maxIters, cores, computeResult);
t.stop();
computeTime = t.getTime();
t.start();
sl_getSmoothColorings(computeResult, maxIters, cores, colorResult);
t.stop();
colorTime = t.getTime();
t.start();
visu.fill(0);
for(int i = 1; i <= colorResult.size(); i++)
{
for(int j = 1; j <= colorResult[i].size(); j++)
{
visu(j-1,i-1,0,0) = colorResult[i][j].R;
visu(j-1,i-1,0,1) = colorResult[i][j].G;
visu(j-1,i-1,0,2) = colorResult[i][j].B;
}
}
visu.display(draw_disp);
t.stop();
renderTime = t.getTime();
draw_disp.set_title("X:[%f, %f] Y:[%f, %f] | Mandelbrot Fractal in SequenceL | Compute Time: %f | Color Time: %f | Render Time: %f | Total FPS: %f", xmin, xmax, ymin, ymax, cores, computeTime, colorTime, renderTime, 1 / (computeTime + colorTime + renderTime));
}
draw_disp.wait();
double xdiff = (xmax - xmin);
double ydiff = (ymax - ymin);
double xcenter = ((1.0 * draw_disp.mouse_x()) / imageWidth) * xdiff + xmin;
double ycenter = ((1.0 * draw_disp.mouse_y()) / imageHeight) * ydiff + ymin;
if(draw_disp.button()&1)
{
redraw = true;
xmin = xcenter - (xdiff / 4);
xmax = xcenter + (xdiff / 4);
ymin = ycenter - (ydiff / 4);
ymax = ycenter + (ydiff / 4);
}
else if(draw_disp.button()&2)
{
redraw = true;
xmin = xcenter - xdiff;
xmax = xcenter + xdiff;
ymin = ycenter - ydiff;
ymax = ycenter + ydiff;
}
}
sl_done();
return 0;
}
- Output:
Sidef
func mandelbrot(z) {
var c = z
{ z = (z*z + c)
z.abs > 2 && return true
} * 20
return false
}
for y range(1, -1, -0.05) {
for x in range(-2, 0.5, 0.0315) {
print(mandelbrot(x + y.i) ? ' ' : '#')
}
print "\n"
}
Simula
BEGIN
REAL XCENTRE, YCENTRE, WIDTH, RMAX, XOFFSET, YOFFSET, PIXELSIZE;
INTEGER N, IMAX, JMAX, COLOURMAX;
TEXT FILENAME;
CLASS COMPLEX(RE,IM); REAL RE,IM;;
REF(COMPLEX) PROCEDURE ADD(A,B); REF(COMPLEX) A,B;
ADD :- NEW COMPLEX(A.RE + B.RE, A.IM + B.IM);
REF(COMPLEX) PROCEDURE SUB(A,B); REF(COMPLEX) A,B;
SUB :- NEW COMPLEX(A.RE - B.RE, A.IM - B.IM);
REF(COMPLEX) PROCEDURE MUL(A,B); REF(COMPLEX) A,B;
MUL :- NEW COMPLEX(A.RE * B.RE - A.IM * B.IM,
A.RE * B.IM + A.IM * B.RE);
REF(COMPLEX) PROCEDURE DIV(A,B); REF(COMPLEX) A,B;
BEGIN
REAL TMP;
TMP := B.RE * B.RE + B.IM * B.IM;
DIV :- NEW COMPLEX((A.RE * B.RE + A.IM * B.IM) / TMP,
(A.IM * B.RE - A.RE * B.IM) / TMP);
END DIV;
REF(COMPLEX) PROCEDURE RECTANGULAR(RE,IM); REAL RE,IM;
RECTANGULAR :- NEW COMPLEX(RE,IM);
REAL PROCEDURE MAGNITUDE(CX); REF(COMPLEX) CX;
MAGNITUDE := SQRT(CX.RE**2 + CX.IM**2);
BOOLEAN PROCEDURE INSIDEP(Z); REF(COMPLEX) Z;
BEGIN
BOOLEAN PROCEDURE INSIDE(Z0,Z,N); REAL N; REF(COMPLEX) Z,Z0;
INSIDE := MAGNITUDE(Z) < RMAX
AND THEN N = 0 OR ELSE INSIDE(Z0, ADD(Z0,MUL(Z,Z)), N-1);
INSIDEP := INSIDE(Z, NEW COMPLEX(0,0), N);
END INSIDEP;
INTEGER PROCEDURE BOOL2INT(B); BOOLEAN B;
BOOL2INT := IF B THEN COLOURMAX ELSE 0;
INTEGER PROCEDURE PIXEL(I,J); INTEGER I,J;
PIXEL := BOOL2INT(INSIDEP(RECTANGULAR(XOFFSET + PIXELSIZE * I,
YOFFSET - PIXELSIZE * J)));
PROCEDURE PLOT;
BEGIN
REF (OUTFILE) OUTF;
INTEGER J,I;
OUTF :- NEW OUTFILE(FILENAME);
OUTF.OPEN(BLANKS(132));
OUTF.OUTTEXT("P2"); OUTF.OUTIMAGE;
OUTF.OUTINT(IMAX,0); OUTF.OUTIMAGE;
OUTF.OUTINT(JMAX,0); OUTF.OUTIMAGE;
OUTF.OUTINT(COLOURMAX,0); OUTF.OUTIMAGE;
FOR J := 1 STEP 1 UNTIL JMAX DO
BEGIN
FOR I := 1 STEP 1 UNTIL IMAX DO
BEGIN
OUTF.OUTINT(PIXEL(I,J),0);
OUTF.OUTIMAGE;
END;
END;
OUTF.CLOSE;
END PLOT;
XCENTRE := -0.5;
YCENTRE := 0.0;
WIDTH := 4.0;
IMAX := 800;
JMAX := 600;
N := 100;
RMAX := 2.0;
FILENAME :- "out.pgm";
COLOURMAX := 255;
PIXELSIZE := WIDTH / IMAX;
XOFFSET := XCENTRE - (0.5 * PIXELSIZE * (IMAX + 1));
YOFFSET := YCENTRE + (0.5 * PIXELSIZE * (JMAX + 1));
OUTTEXT("OUTPUT WILL BE WRITTEN TO ");
OUTTEXT(FILENAME);
OUTIMAGE;
PLOT;
END;
Spin
con
_clkmode = xtal1+pll16x
_clkfreq = 80_000_000
xmin=-8601 ' int(-2.1*4096)
xmax=2867 ' int( 0.7*4096)
ymin=-4915 ' int(-1.2*4096)
ymax=4915 ' int( 1.2*4096)
maxiter=25
obj
ser : "FullDuplexSerial"
pub main | c,cx,cy,dx,dy,x,y,x2,y2,iter
ser.start(31, 30, 0, 115200)
dx:=(xmax-xmin)/79
dy:=(ymax-ymin)/24
cy:=ymin
repeat while cy=<ymax
cx:=xmin
repeat while cx=<xmax
x:=0
y:=0
x2:=0
y2:=0
iter:=0
repeat while iter=<maxiter and x2+y2=<16384
y:=((x*y)~>11)+cy
x:=x2-y2+cx
iter+=1
x2:=(x*x)~>12
y2:=(y*y)~>12
cx+=dx
ser.tx(iter+32)
cy+=dy
ser.str(string(13,10))
waitcnt(_clkfreq+cnt)
ser.stop
- Output:
!!!!!!!!!!!!!!!"""""""""""""####################################"""""""""""""""" !!!!!!!!!!!!!"""""""""#######################$$$$$$$%'+)%%%$$$$$#####""""""""""" !!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(+,)++&%$$$$$$######"""""" !!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*5:/+('&%%$$$$$$#######""" !!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),:::::::,'&%%%%%$$$$######## !!!!!!!"""####################$$$$$$$$%%%&'())((())*,::::::/+))('&&&&)'%$$###### !!!!!!""###################$$$$$%%%%%%&&&'+.:::/::::::::::::::::/++:..93%%$##### !!!!!"################$$$%%%%%%%%%%&&&&'),+2:::::::::::::::::::::::::1(&&%$$#### !!!!"##########$$$$$%%&(-(''''''''''''(*,5::::::::::::::::::::::::::::+)-&%$$### !!!!####$$$$$$$$%%%%%&'(*-:1.+.:-4+))**:::::::::::::::::::::::::::::::4-(&%$$$## !!!!#$$$$$$$$$%%%%%%'''++.6:::::::::8/0::::::::::::::::::::::::::::::::3(%%$$$$# !!!#$$$$$$$%&&&&''()/-5.5::::::::::::::::::::::::::::::::::::::::::::::'&%%$$$$# !!!(**+/+:523/80/46::::::::::::::::::::::::::::::::::::::::::::::::4+)'&&%%$$$$# !!!#$$$$$$$%&&&&''().-2.:::::::::::::::::::::::::::::::::::::::::::::::'&%%$$$$# !!!!#$$$$$$$$$%%%%%&'''/,.7::::::::::/0::::::::::::::::::::::::::::::::0'%%$$$$# !!!!####$$$$$$$$%%%%%&'(*-:2.,/:-5+))**:::::::::::::::::::::::::::::::4+(&%$$$## !!!!"##########$$$$$%%&(-(''''(''''''((*,4:::::::::::::::::::::::::::4+).&%$$### !!!!!"################$$$%%%%%%%%%%&&&&'):,4:::::::::::::::::::::::::/('&%%$#### !!!!!!""##################$$$$$$%%%%%%&&&'*.:::0::::::::::::::::1,,://9)%%$##### !!!!!!!"""####################$$$$$$$$%%%&(())((()**-::::::/+)))'&&&')'%$$###### !!!!!!!!""""#####################$$$$$$$$$$%%%&&&''(,:::::::+'&&%%%%%$$$######## !!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*7:0+('&%%%$$$$$#######""" !!!!!!!!!!!"""""""######################$$$$$$$$$%%%&&(+-).*&%$$$$$$######"""""" !!!!!!!!!!!!!"""""""""#######################$$$$$$%%'3(%%%$$$$$######"""""""""" !!!!!!!!!!!!!!!""""""""""""#####################################""""""""""""""""
SparForte
As a structured script.
#!/usr/local/bin/spar
pragma annotate( summary, "mandel" )
@( description, "Create a color image of the Mandelbrot set" )
@( author, "Ken O. Burtch" );
pragma license( unrestricted );
pragma restriction( no_external_commands );
procedure mandel is
mandel_limit : constant long_float := 4.0; -- reach this? it's the set
max_iterations : constant integer := 128; -- quit if looped this amt
center_r : constant long_float := -0.75; -- center of set (x=real)
center_i : constant long_float := 0.0; -- center of set (i=imag.)
c_r : long_float; -- current point (x=real)
c_i : long_float; -- current point (i=imag.)
loop_count : integer; -- number of iterations
z_r : long_float; -- mandelbot set formula
z_i : long_float; -- variables
z_r2 : long_float;
z_i2 : long_float;
c : pen.canvas_id; -- bush drawing canvas
plot : limited pen.rect; -- rectangle to draw with
s : string;
bits : integer; -- for determining color
red : pen.rgbcomponent;
green: pen.rgbcomponent;
blue : pen.rgbcomponent;
begin
-- create the drawing canvas
pen.new_window_canvas( 200, 200, 32, c );
pen.set_title( c, "Mandelbrot" );
-- loop for the size of the canvas (-50% to +50%)
for i in -50..50 loop
c_i := center_i - long_float(i)*0.025;
pen.wait_to_reveal( c );
for r in -50..50 loop
c_r := center_r - long_float(r)*0.025;
-- Evaluatuate how close point (c_z, c_i ) in complex number space
-- is to the Mandelbrot set. Return a number between 0 and
-- max_iterations. A value of max_iterations implies that the point
-- is probably a member of the Mandelbrot set.
z_r := c_r;
z_i := c_i;
loop_count := 1;
loop
z_i2 := z_i*z_i;
z_r2 := z_r*z_r;
z_i := 2.0 * z_r * z_i + c_i;
z_r := z_r2 - z_i2 + c_r;
loop_count := @+1;
exit when not ( (z_r2 + z_i2 < mandel_limit) and (loop_count /= max_iterations) );
end loop;
-- pick a color based on loop_count (mandelbrot set is black)
if loop_count = max_iterations then
red := 0.0;
green := 0.0;
blue := 0.0;
else
bits := (loop_count and 3 );
red := 100.0-pen.rgbcomponent((100*bits/3));
bits := (loop_count / 3 ) and 3;
green := 100.0-pen.rgbcomponent((100*bits/3));
bits := (loop_count / 27 ) and 2;
blue := 100.0-pen.rgbcomponent((100*bits)/2);
end if;
pen.set_pen_ink( c, red, green, blue );
-- Draw the point, reversing the X axis
pen.set_rect( plot, 100-(r+50),i+50, 100-(r+49), i+51 );
pen.paint_rect( c, plot );
end loop;
pen.reveal( c );
end loop;
? "Press return";
s := get_line;
end mandel;
SPL
w,h = #.scrsize()
sfx = -2.5; sfy = -2*h/w; fs = 4/w
#.aaoff()
> y, 1...h
> x, 1...w
fx = sfx + x*fs; fy = sfy + y*fs
#.drawpoint(x,y,color(fx,fy):3)
<
<
color(x,y)=
zr = x; zi = y; n = 0; maxn = 150
> zr*zr+zi*zi<4 & n<maxn
zrn = zr*zr-zi*zi+x; zin = 2*zr*zi+y
zr = zrn; zi = zin; n += 1
<
? n=maxn, <= 0,0,0
<= #.hsv2rgb(n/maxn*360,1,1):3
.
Swift
Using the Swift Numerics package, as well as the C library Quick 'N Dirty BMP imported in Swift.
import Foundation
import Numerics
import QDBMP
public typealias Color = (red: UInt8, green: UInt8, blue: UInt8)
public class BitmapDrawer {
public let imageHeight: Int
public let imageWidth: Int
var grid: [[Color?]]
private let bmp: OpaquePointer
public init(height: Int, width: Int) {
self.imageHeight = height
self.imageWidth = width
self.grid = [[Color?]](repeating: [Color?](repeating: nil, count: height), count: width)
self.bmp = BMP_Create(UInt(width), UInt(height), 24)
checkError()
}
deinit {
BMP_Free(bmp)
}
private func checkError() {
let err = BMP_GetError()
guard err == BMP_STATUS(0) else {
fatalError("\(err)")
}
}
public func save(to path: String = "~/Desktop/out.bmp") {
for x in 0..<imageWidth {
for y in 0..<imageHeight {
guard let color = grid[x][y] else { continue }
BMP_SetPixelRGB(bmp, UInt(x), UInt(y), color.red, color.green, color.blue)
checkError()
}
}
(path as NSString).expandingTildeInPath.withCString {s in
BMP_WriteFile(bmp, s)
}
}
public func setPixel(x: Int, y: Int, to color: Color?) {
grid[x][y] = color
}
}
let imageSize = 10_000
let canvas = BitmapDrawer(height: imageSize, width: imageSize)
let maxIterations = 256
let cxMin = -2.0
let cxMax = 1.0
let cyMin = -1.5
let cyMax = 1.5
let scaleX = (cxMax - cxMin) / Double(imageSize)
let scaleY = (cyMax - cyMin) / Double(imageSize)
for x in 0..<imageSize {
for y in 0..<imageSize {
let cx = cxMin + Double(x) * scaleX
let cy = cyMin + Double(y) * scaleY
let c = Complex(cx, cy)
var z = Complex(0.0, 0.0)
var i = 0
for t in 0..<maxIterations {
if z.magnitude > 2 {
break
}
z = z * z + c
i = t
}
canvas.setPixel(x: x, y: y, to: Color(red: UInt8(i), green: UInt8(i), blue: UInt8(i)))
}
}
canvas.save()
Tcl
This code makes extensive use of Tk's built-in photo image system, which provides a 32-bit RGBA plotting surface that can be then quickly drawn in any number of places in the application. It uses a computational color scheme that was easy to code...
package require Tk
proc mandelIters {cx cy} {
set x [set y 0.0]
for {set count 0} {hypot($x,$y) < 2 && $count < 255} {incr count} {
set x1 [expr {$x*$x - $y*$y + $cx}]
set y1 [expr {2*$x*$y + $cy}]
set x $x1; set y $y1
}
return $count
}
proc mandelColor {iter} {
set r [expr {16*($iter % 15)}]
set g [expr {32*($iter % 7)}]
set b [expr {8*($iter % 31)}]
format "#%02x%02x%02x" $r $g $b
}
image create photo mandel -width 300 -height 300
# Build picture in strips, updating as we go so we have "progress" monitoring
# Also set the cursor to tell the user to wait while we work.
pack [label .mandel -image mandel -cursor watch]
update
for {set x 0} {$x < 300} {incr x} {
for {set y 0} {$y < 300} {incr y} {
set i [mandelIters [expr {($x-220)/100.}] [expr {($y-150)/90.}]]
mandel put [mandelColor $i] -to $x $y
}
update
}
.mandel configure -cursor {}
Plain TeX
The pst-fractal
package includes a Mandelbrot set drawn by emitting PostScript code (using PSTricks), so the actual work done in the printer or PostScript interpreter.
\input pst-fractal
\psfractal[type=Mandel,xWidth=14cm,yWidth=12cm,maxIter=30,dIter=20] (-2.5,-1.5)(1,1.5)
\end
The coordinates are a rectangle in the complex plane to draw, scaled up to xWidth,yWidth
.
More iterations with maxIter
is higher resolution but slower.
dIter
is a scale factor for the colours.
LaTeX
The pstricks-examples
package which is samples from the PSTricks book includes similar for LaTeX (25-02-6.ltx
and 33-02-6.ltx
).
The PGF shadings
library includes a Mandelbrot set.
In PGF 3.0 the calculations are done in PostScript code emitted, so the output size is small but it only does 10 iterations so is very low resolution.
\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{shadings}
\begin{document}
\begin{tikzpicture}
\shade[shading=Mandelbrot set] (0,0) rectangle (4,4);
\end{tikzpicture}
\end{document}
LuaTeX
LuaLaTeX plus pgfplots code can be found at http://texwelt.de/wissen/fragen/3960/fraktale-mit-pgfplots.
The calculations are done by inline Lua code and the resulting bitmap shown with a PGF plot.
TI-83 BASIC
Based on the BASIC Version. Due to the TI-83's lack of power, it takes around 2 hours to complete at 16 iterations.
PROGRAM:MANDELBR
:Input "ITER. ",D
:For(A,Xmin,Xmax,ΔX)
:For(B,Ymin,Ymax,ΔY)
:0→X
:0→Y
:0→I
:D→M
:While X^2+Y^2≤4 and I<M
:X^2-Y^2+A→R
:2XY+B→Y
:R→X
:I+1→I
:End
:If I≠M
:Then
:I→C
:Else
:0→C
:End
:If C<1
:Pt-On(A,B)
:End
:End
:End
Transact-SQL
This is a Transact-SQL version of SQL Server to generate Mandelbrot set. Export the final result to a .ppm file to view the image. More details are available here.
-- Mandelbrot Set
-- SQL Server 2017 and above
SET NOCOUNT ON
GO
-- Plot area 800 X 800
DECLARE @width INT = 800
DECLARE @height INT = 800
DECLARE @r_min DECIMAL (10, 8) = -2.5;
DECLARE @r_max DECIMAL (10, 8) = 1.5;
DECLARE @r_step DECIMAL (10, 8) = 0.005;
DECLARE @i_min DECIMAL (10, 8) = -2;
DECLARE @i_max DECIMAL (10, 8) = 2;
DECLARE @i_step DECIMAL (10, 8) = 0.005;
DECLARE @iter INT = 255; -- Iteration
DROP TABLE IF EXISTS dbo.Numbers
DROP TABLE IF EXISTS dbo.mandelbrot_set;
CREATE TABLE dbo.Numbers (n INT);
-- Generate a number table of 1000 rows
;WITH N1(n) AS
(
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), -- 10
N2(n) AS (SELECT 1 FROM N1 CROSS JOIN N1 AS b), -- 10*10
N3(n) AS (SELECT 1 FROM N1 CROSS JOIN N2) -- 10*100
INSERT INTO dbo.Numbers (n)
SELECT n = ROW_NUMBER() OVER (ORDER BY n)
FROM N3 ORDER BY n;
/*
-- If the version is SQL Server 2022 and above
INSERT INTO dbo.Numbers (n)
SELECT value FROM GENERATE_SERIES(0, 1000);
*/
CREATE TABLE dbo.mandelbrot_set
(
a INT,
b INT,
c_re DECIMAL (10, 8),
c_im DECIMAL (10, 8),
z_re DECIMAL (10, 8) DEFAULT 0,
z_im DECIMAL (10, 8) DEFAULT 0,
znew_re DECIMAL (10, 8) DEFAULT 0,
znew_im DECIMAL (10, 8) DEFAULT 0,
steps INT DEFAULT 0,
active BIT DEFAULT 1,
)
-- Store all the c_re, c_im corresponding to each point in the plot area
-- Generate 640,000 rows (800 X 800)
INSERT INTO dbo.mandelbrot_set (a, b, c_re, c_im, steps)
SELECT a.n as a, b.n as b
,(@r_min + (a.n * @r_step)) AS c_re
,(@i_min + (b.n * @i_step)) AS c_im
,@iter AS steps
FROM
(
SELECT n - 1 as n FROM dbo.Numbers WHERE n <= @width
) as a
CROSS JOIN
(
SELECT n - 1 as n FROM dbo.Numbers WHERE n <= @height
) as b;
-- Iteration
WHILE (@iter > 1)
BEGIN
UPDATE dbo.mandelbrot_set
SET
znew_re = POWER(z_re,2)-POWER(z_im,2)+c_re,
znew_im = 2*z_re*z_im+c_im,
steps = steps-1
WHERE active=1;
UPDATE dbo.mandelbrot_set
SET
z_re=znew_re,
z_im=znew_im,
active= CASE
WHEN POWER(znew_re,2)+POWER(znew_im,2)>4 THEN 0
ELSE 1
END
WHERE active=1;
SET @iter = @iter - 1;
END
-- Generating PPM File
-- Save the below query results to a file with extension .ppm
-- NOTE : All the unwanted info like 'rows affected', 'completed time' etc. needs to be
-- removed from the file. Most of the image editing softwares and online viewers can display the .ppm file
SELECT 'P3' UNION ALL
SELECT CAST(@width AS VARCHAR(5)) + ' ' + CAST(@height AS VARCHAR(5)) UNION ALL
SELECT '255' UNION ALL
SELECT
STRING_AGG(CAST(CASE WHEN active = 1 THEN 0 ELSE 55 + steps % 200 END AS VARCHAR(10)) + ' ' -- R
+ CAST(CASE WHEN active = 1 THEN 0 ELSE 55+POWER(steps,3) % 200 END AS VARCHAR(10)) + ' ' -- G
+ CAST(CASE WHEN active = 1 THEN 0 ELSE 55+ POWER(steps,2) % 200 END AS VARCHAR(10)) -- B
, ' ') WITHIN GROUP (ORDER BY c_re, c_im)
FROM dbo.mandelbrot_set
GROUP BY c_re, c_im;
OUTPUT
![](http://static.miraheze.org/rosettacodewiki/thumb/1/18/Mandelbrot_set_transact-sql.png/300px-Mandelbrot_set_transact-sql.png)
TXR
Creates same mandelbrot.pgm
file.
(defvar x-centre -0.5)
(defvar y-centre 0.0)
(defvar width 4.0)
(defvar i-max 800)
(defvar j-max 600)
(defvar n 100)
(defvar r-max 2.0)
(defvar file "mandelbrot.pgm")
(defvar colour-max 255)
(defvar pixel-size (/ width i-max))
(defvar x-offset (- x-centre (* 0.5 pixel-size (+ i-max 1))))
(defvar y-offset (+ y-centre (* 0.5 pixel-size (+ j-max 1))))
;; with-output-to-file macro
(defmacro with-output-to-file (name . body)
^(let ((*stdout* (open-file ,name "w")))
(unwind-protect (progn ,*body) (close-stream *stdout*))))
;; complex number library
(defmacro cplx (x y) ^(cons ,x ,y))
(defmacro re (c) ^(car ,c))
(defmacro im (c) ^(cdr ,c))
(defsymacro c0 '(0 . 0))
(macro-time
(defun with-cplx-expand (specs body)
(tree-case specs
(((re im expr) . rest)
^(tree-bind (,re . ,im) ,expr ,(with-cplx-expand rest body)))
(() (tree-case body
((a b . rest) ^(progn ,a ,b ,*rest))
((a) a)
(x (error "with-cplx: invalid body ~s" body))))
(x (error "with-cplx: bad args ~s" x)))))
(defmacro with-cplx (specs . body)
(with-cplx-expand specs body))
(defun c+ (x y)
(with-cplx ((a b x) (c d y))
(cplx (+ a c) (+ b d))))
(defun c* (x y)
(with-cplx ((a b x) (c d y))
(cplx (- (* a c) (* b d)) (+ (* b c) (* a d)))))
(defun modulus (z)
(with-cplx ((a b z))
(sqrt (+ (* a a) (* b b)))))
;; Mandelbrot routines
(defun inside-p (z0 : (z c0) (n n))
(and (< (modulus z) r-max)
(or (zerop n)
(inside-p z0 (c+ (c* z z) z0) (- n 1)))))
(defmacro int-bool (b)
^(if ,b colour-max 0))
(defun pixel (i j)
(int-bool
(inside-p
(cplx (+ x-offset (* pixel-size i))
(- y-offset (* pixel-size j))))))
;; Mandelbrot loop and output
(defun plot ()
(with-output-to-file file
(format t "P2\n~s\n~s\n~s\n" i-max j-max colour-max)
(each ((j (range 1 j-max)))
(each ((i (range 1 i-max)))
(format *stdout* "~s " (pixel i j)))
(put-line "" *stdout*))))
(plot)
uBasic/4tH
uBasic does not support floating point calculations, so fixed point arithmetic is used, with Value 10000 representing 1.0. The Mandelbrot image is drawn using ASCII characters 1-9 to show number of iterations. Iteration count 10 or more is represented with '@'. To compensate the aspect ratio of the font, step sizes in x and y directions are different.
A =-21000 ' Left Edge = -2.1
B = 15000 ' Right Edge = 1.5
C = 15000 ' Top Edge = 1.5
D =-15000 ' Bottom Edge = -1.5
E = 200 ' Max Iteration Depth
F = 350 ' X Step Size
G = 750 ' Y Step Size
For L = C To D Step -G ' Y0
For K = A To B-1 Step F ' X0
V = 0 ' Y
U = 0 ' X
I = 32 ' Char To Be Displayed
For O = 0 To E-1 ' Iteration
X = (U/10 * U) / 1000 ' X*X
Y = (V/10 * V) / 1000 ' Y*Y
If (X + Y > 40000)
I = 48 + O ' Print Digit 0...9
If (O > 9) ' If Iteration Count > 9,
I = 64 ' Print '@'
Endif
Break
Endif
Z = X - Y + K ' Temp = X*X - Y*Y + X0
V = (U/10 * V) / 500 + L ' Y = 2*X*Y + Y0
U = Z ' X = Temp
Next
Gosub I ' Ins_char(I)
Next
Print
Next
End
' Translate number to ASCII
32 Print " "; : Return
48 Print "0"; : Return
49 Print "1"; : Return
50 Print "2"; : Return
51 Print "3"; : Return
52 Print "4"; : Return
53 Print "5"; : Return
54 Print "6"; : Return
55 Print "7"; : Return
56 Print "8"; : Return
57 Print "9"; : Return
64 Print "@"; : Return
Output:
1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 1111111111111112222222222222333333333333333333333333333333333333322222222222222222222222222222222222222 1111111111111222222222233333333333333333333333344444457655544443333332222222222222222222222222222222222 1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 11111111111222222333333333333333333333334444444445555678@@@@7654444443333332222222222222222222222222222 1111111112222223333333333333333333333444444444455556789@@@@98655544444433333332222222222222222222222222 1111111122222333333333333333333333344444444445556668@@@ @@@@76555544444333333322222222222222222222222 1111111122233333333333333333333344444444445566667778@@ @987666555544433333333222222222222222222222 111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@87777@95443333333322222222222222222222 1111112233333333333333333334444455555556678@@ @@ @@@@@@@8544333333333222222222222222222 1111122333333333333333334445555555555666789@@@ @86554433333333322222222222222222 1111123333333333333444466666555556666778@@@@ @@87655443333333332222222222222222 111123333333344444455568@887789@8777788@@@ @@@@65443333333332222222222222222 1111333344444444455556679@@@@@@@@@@@99@@@ @@765444333333333222222222222222 1111334444444455555567789@@ @@@@ @855444333333333222222222222222 11114444444455555668@99@@@ @ @@655444433333333322222222222222 11134555556666677789@@@ @ @86655444433333333322222222222222 111 @@876555444433333333322222222222222 11134555556666677789@@@ @ @86655444433333333322222222222222 11114444444455555668@99@@@ @ @@655444433333333322222222222222 1111334444444455555567789@@ @@@@ @855444333333333222222222222222 1111333344444444455556679@@@@@@@@@@@99@@@ @@765444333333333222222222222222 111123333333344444455568@887789@8777788@@@ @@@@65443333333332222222222222222 1111123333333333333444466666555556666778@@@@ @@87655443333333332222222222222222 1111122333333333333333334445555555555666789@@@ @86554433333333322222222222222222 1111112233333333333333333334444455555556678@@ @@ @@@@@@@8544333333333222222222222222222 111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@87777@95443333333322222222222222222222 1111111122233333333333333333333344444444445566667778@@ @987666555544433333333222222222222222222222 1111111122222333333333333333333333344444444445556668@@@ @@@@76555544444333333322222222222222222222222 1111111112222223333333333333333333333444444444455556789@@@@98655544444433333332222222222222222222222222 11111111111222222333333333333333333333334444444445555678@@@@7654444443333332222222222222222222222222222 1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 1111111111111222222222233333333333333333333333344444457655544443333332222222222222222222222222222222222 1111111111111112222222222222333333333333333333333333333333333333322222222222222222222222222222222222222 1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 0 OK, 0:1726
Uiua
Size ← 800
Cs ← ÷ 5[5_5_5 4_5_5 4_5_5 3_5_5 5_3_5 3_3_5 2_5_0 5_2_2 2_2_5 0_0_0]
# Initialise complex co-ordinates.
×2.5 ⊞ℂ:-1/4. ÷:-÷2,⇡.⟜(↯:0⊟.)Size
# Iterate 50 times (a, b, got_there) -> (a*a+b, b, got_there)
# got_there counts when corresponding value in b hits 2.
⍥⊃(+×.|⋅∘|+<2⌵⊙◌)50 0
# Scale the results down and display
⊏:Cs⌈×9÷:⟜(/↥/↥)ₙ2◌◌
- Output:
![](http://static.miraheze.org/rosettacodewiki/thumb/5/5d/Uiua_Mandelbrot_Set.png/300px-Uiua_Mandelbrot_Set.png)
UNIX Shell
function mandelbrot() {
local -ir maxiter=100
local -i i j {x,y}m{in,ax} d{x,y}
local -ra C=( {0..9} )
local -i lC=${#C[*]}
local -i columns=${COLUMNS:-72} lines=${LINES:-24}
((
xmin=-21*4096/10,
xmax= 7*4096/10,
ymin=-12*4096/10,
ymax= 12*4096/10,
dx=(xmax-xmin)/columns,
dy=(ymax-ymin)/lines
))
for ((cy=ymax, i=0; i<lines; cy-=dy, i++))
do for ((cx=xmin, j=0; j<columns; cx+=dx, j++))
do (( x=0, y=0, x2=0, y2=0 ))
for (( iter=0; iter<maxiter && x2+y2<=16384; iter++ ))
do
((
y=((x*y)>>11)+cy,
x=x2-y2+cx,
x2=(x*x)>>12,
y2=(y*y)>>12
))
done
((c=iter%lC))
echo -n "${C[c]}"
done
echo
done
}
- Output:
1111111111111222222222222333333333333333333333333333333333222222222222222 1111111111112222222233333333333333333333344444456015554444333332222222222 1111111111222222333333333333333333333444444445556704912544444433333222222 1111111112222333333333333333333333444444444555678970508655544444333333222 1111111222233333333333333333333444444444556667807000002076555544443333333 1111112223333333333333333333444444455577898889016000003099766662644333333 1111122333333333333333334444455555566793000800000000000000931045875443333 1111123333333333333344455555555566668014000000000000000000000009865544333 1111233333333344445568277777777777880600000000000000000000000009099544433 1111333344444445555678041513450199023000000000000000000000000000807544433 1112344444445555556771179000000000410000000000000000000000000000036544443 1114444444566667782404400000000000000000000000000000000000000000775544443 1119912160975272040000000000000000000000000000000000000000000219765544443 1114444444566667792405800000000000000000000000000000000000000000075544443 1113344444445555556773270000000000500000000000000000000000000000676544443 1111333344444445555678045623255199020000000000000000000000000000707544433 1111233333333444445568177777877777881500000000000000000000000009190544433 1111123333333333333344455555555566668126000000000000000000000009865544333 1111122333333333333333334444455555566793000100000000000000941355975443333 1111112223333333333333333334444444455588908889016000003099876670654433333 1111111222233333333333333333334444444445556667800000002976555554443333333 1111111112222333333333333333333333444444444555679060608655544444333333222 1111111111222222333333333333333333333444444445556702049544444433333222222 1111111111112222222233333333333333333333344444456205554444333333222222222 1111111111111222222222222333333333333333333333333333333333222222222222222
Vala
public class Example: Gtk.Application {
private Gtk.ApplicationWindow window;
private Gtk.DrawingArea drawing_area;
public Example() {
Object(application_id: "my.application", flags: ApplicationFlags.FLAGS_NONE);
this.activate.connect(() => {
window = new Gtk.ApplicationWindow(this);
drawing_area = new Gtk.DrawingArea();
drawing_area.set_draw_func(draw_mandelbrot);
window.set_child(drawing_area);
window.present();
});
}
private void draw_mandelbrot(Gtk.DrawingArea area, Cairo.Context cr, int width, int height) {
cr.set_source_rgb(0, 0, 0);
cr.paint();
int x0 = -1;
double x_increment = 2.47 / (float) width;
double y_increment = 2.24 / (float) height;
for (double x = -2.0; x < 0.47; x += x_increment, x0++) {
int y0 = -1;
for (double y = -1.12; y < 1.12; y += y_increment, y0++) {
double c_re = x;
double c_im = y;
double x_ = 0,
y_ = 0;
int iterations = 0;
int max_iterations = 50;
while (iterations < max_iterations && x_ * x_ + y_ * y_ <= 4.0) {
double x_new = x_ * x_ - y_ * y_ + c_re;
y_ = 2.0 * x_ * y_ + c_im;
x_ = x_new;
iterations++;
}
if (iterations < max_iterations) {
cr.set_source_rgb((float) iterations / (float) max_iterations, 0, 0);
cr.rectangle(x0, y0, 1, 1);
cr.fill();
}
}
}
}
public static int main(string[] argv) {
var app = new Example();
return app.run(argv);
}
}
VBScript
option explicit
' Raster graphics class in VBSCRIPT by Antoni Gual
'--------------------------------------------
' An array keeps the image allowing to set pixels, draw lines and boxes in it.
' at class destroy a bmp file is saved to disk and the default viewer is called
' The class can work with 8 and 24 bit bmp. With 8 bit uses a built-in palette or can import a custom one
'Declaration :
' Set MyObj = (New ImgClass)(name,width,height, orient,bits_per_pixel,palette_array)
' name:path and name of the file created
' width, height of the canvas
' orient is the way the coord increases, 1 to 4 think of the 4 cuadrants of the caterian plane
' 1 X:l>r Y:b>t 2 X:r>l Y:b>t 3 X:r>l Y:t>b 4 X:l>r Y:t>b
' bits_per_pixel can bs only 8 and 24
' palette array only to substitute the default palette for 8 bits, else put a 0
' it sets the origin at the corner of the image (bottom left if orient=1)
Class ImgClass
Private ImgL,ImgH,ImgDepth,bkclr,loc,tt
private xmini,xmaxi,ymini,ymaxi,dirx,diry
public ImgArray() 'rgb in 24 bit mode, indexes to palette in 8 bits
private filename
private Palette,szpal
Public Property Let depth (x)
if depth=8 or depth =24 then
Imgdepth=depth
else
Imgdepth=8
end if
bytepix=imgdepth/8
end property
Public Property Let Pixel (x,y,color)
If (x>=ImgL) or x<0 then exit property
if y>=ImgH or y<0 then exit property
ImgArray(x,y)=Color
End Property
Public Property Get Pixel (x,y)
If (x<ImgL) And (x>=0) And (y<ImgH) And (y>=0) Then
Pixel=ImgArray(x,y)
End If
End Property
Public Property Get ImgWidth ()
ImgWidth=ImgL-1
End Property
Public Property Get ImgHeight ()
ImgHeight=ImgH-1
End Property
'constructor (fn,w*2,h*2,32,0,0)
Public Default Function Init(name,w,h,orient,dep,bkg,mipal)
'offx, offy posicion de 0,0. si ofx+ , x se incrementa de izq a der, si offy+ y se incrementa de abajo arriba
dim i,j
ImgL=w
ImgH=h
tt=timer
set0 0,0 'origin blc positive up and right
redim imgArray(ImgL-1,ImgH-1)
bkclr=bkg
if bkg<>0 then
for i=0 to ImgL-1
for j=0 to ImgH-1
imgarray(i,j)=bkg
next
next
end if
Select Case orient
Case 1: dirx=1 : diry=1
Case 2: dirx=-1 : diry=1
Case 3: dirx=-1 : diry=-1
Case 4: dirx=1 : diry=-1
End select
filename=name
ImgDepth =dep
'load user palette if provided
if imgdepth=8 then
loadpal(mipal)
end if
set init=me
end function
private sub loadpal(mipale)
if isarray(mipale) Then
palette=mipale
szpal=UBound(mipale)+1
Else
szpal=256
'Default palette recycled from ATARI
End if
End Sub
public sub set0 (x0,y0) 'origin can be changed during drawing
if x0<0 or x0>=imgl or y0<0 or y0>imgh then err.raise 9
xmini=-x0
ymini=-y0
xmaxi=xmini+imgl-1
ymaxi=ymini+imgh-1
end sub
Private Sub Class_Terminate
if err <>0 then wscript.echo "Error " & err.number
wscript.echo "writing bmp to file"
savebmp
wscript.echo "opening " & filename
CreateObject("Shell.Application").ShellExecute filename
wscript.echo timer-tt & " seconds"
End Sub
'writes a 32bit integr value as binary to an utf16 string
function long2wstr( x) 'falta muy poco!!!
dim k1,k2,x1
k1= (x and &hffff&)' or (&H8000& And ((X And &h8000&)<>0)))
k2=((X And &h7fffffff&) \ &h10000&) Or (&H8000& And (x<0))
long2wstr=chrw(k1) & chrw(k2)
end function
function int2wstr(x)
int2wstr=ChrW((x and &h7fff) or (&H8000 And (X<0)))
End Function
Public Sub SaveBMP
'Save the picture to a bmp file
Dim s,ostream, x,y,loc
const hdrs=54 '14+40
dim bms:bms=ImgH* 4*(((ImgL*imgdepth\8)+3)\4) 'bitmap size including padding
dim palsize:if (imgdepth=8) then palsize=szpal*4 else palsize=0
with CreateObject("ADODB.Stream") 'auxiliary ostream, it creates an UNICODE with bom stream in memory
.Charset = "UTF-16LE" 'o "UTF16-BE"
.Type = 2' adTypeText
.open
'build a header
'bmp header: VBSCript does'nt have records nor writes binary values to files, so we use strings of unicode chars!!
'BMP header
.writetext ChrW(&h4d42) ' 0 "BM" 4d42
.writetext long2wstr(hdrs+palsize+bms) ' 2 fiesize
.writetext long2wstr(0) ' 6 reserved
.writetext long2wstr (hdrs+palsize) '10 image offset
'InfoHeader
.writetext long2wstr(40) '14 infoheader size
.writetext long2wstr(Imgl) '18 image length
.writetext long2wstr(imgh) '22 image width
.writetext int2wstr(1) '26 planes
.writetext int2wstr(imgdepth) '28 clr depth (bpp)
.writetext long2wstr(&H0) '30 compression used 0= NOCOMPR
.writetext long2wstr(bms) '34 imgsize
.writetext long2wstr(&Hc4e) '38 bpp hor
.writetext long2wstr(&hc43) '42 bpp vert
.writetext long2wstr(szpal) '46 colors in palette
.writetext long2wstr(&H0) '50 important clrs 0=all
'write bitmap
'precalc data for orientation
Dim x1,x2,y1,y2
If dirx=-1 Then x1=ImgL-1 :x2=0 Else x1=0:x2=ImgL-1
If diry=-1 Then y1=ImgH-1 :y2=0 Else y1=0:y2=ImgH-1
Select Case imgdepth
Case 32
For y=y1 To y2 step diry
For x=x1 To x2 Step dirx
'writelong fic, Pixel(x,y)
.writetext long2wstr(Imgarray(x,y))
Next
Next
Case 8
'palette
For x=0 to szpal-1
.writetext long2wstr(palette(x)) '52
Next
'image
dim pad:pad=ImgL mod 4
For y=y1 to y2 step diry
For x=x1 To x2 step dirx*2
.writetext chrw((ImgArray(x,y) and 255)+ &h100& *(ImgArray(x+dirx,y) and 255))
Next
'line padding
if pad and 1 then .writetext chrw(ImgArray(x2,y))
if pad >1 then .writetext chrw(0)
Next
Case Else
WScript.Echo "ColorDepth not supported : " & ImgDepth & " bits"
End Select
'use a second stream to save to file starting past the BOM the first ADODB.Stream has added
Dim outf:Set outf= CreateObject("ADODB.Stream")
outf.Type = 1 ' adTypeBinary
outf.Open
.position=2 'remove bom (1 wchar)
.CopyTo outf
.close
outf.savetofile filename,2 'adSaveCreateOverWrite
outf.close
end with
End Sub
End Class
function mandelpx(x0,y0,maxit)
dim x,y,xt,i,x2,y2
i=0:x2=0:y2=0
Do While i< maxit
i=i+1
xt=x2-y2+x0
y=2*x*y+y0
x=xt
x2=x*x:y2=y*y
If (x2+y2)>=4 Then Exit do
loop
if i=maxit then
mandelpx=0
else
mandelpx = i
end if
end function
Sub domandel(x1,x2,y1,y2)
Dim i,ii,j,jj,pix,xi,yi,ym
ym=X.ImgHeight\2
'get increments in the mandel plane
xi=Abs((x1-x2)/X.ImgWidth)
yi=Abs((y2-0)/(X.ImgHeight\2))
j=0
For jj=0. To y2 Step yi
i=0
For ii=x1 To x2 Step xi
pix=mandelpx(ii,jj,256)
'use simmetry
X.imgarray(i,ym-j)=pix
X.imgarray(i,ym+j)=pix
i=i+1
Next
j=j+1
next
End Sub
'main------------------------------------
Dim i,x
'custom palette
dim pp(255)
for i=1 to 255
pp(i)=rgb(0,0,255*(i/255)^.25) 'VBS' RGB function is for the web, it's bgr for Windows BMP !!
next
dim fn:fn=CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2)& "\mandel.bmp"
Set X = (New ImgClass)(fn,580,480,1,8,0,pp)
domandel -2.,1.,-1.2,1.2
Set X = Nothing
- Output:
Vedit macro language
Vedit macro language does not support floating point calculations, so fixed point arithmetic is used, with Value 10000 representing 1.0. The Mandelbrot image is drawn using ASCII characters 1-9 to show number of iterations. Iteration count 10 or more is represented with '@'. To compensate the aspect ratio of the font, step sizes in x and y directions are different.
#1 =-21000 // left edge = -2.1
#2 = 15000 // right edge = 1.5
#3 = 15000 // top edge = 1.5
#4 =-15000 // bottom edge = -1.5
#5 = 200 // max iteration depth
#6 = 350 // x step size
#7 = 750 // y step size
Buf_Switch(Buf_Free)
for (#12 = #3; #12 > #4; #12 -= #7) { // y0
for (#11 = #1; #11 < #2; #11 += #6) { // x0
#22 = 0 // y
#21 = 0 // x
#9 = ' ' // char to be displayed
for (#15 = 0; #15 < #5; #15++) { // iteration
#31 = (#21/10 * #21) / 1000 // x*x
#32 = (#22/10 * #22) / 1000 // y*y
if (#31 + #32 > 40000) {
#9 = '0' + #15 // print digit 0...9
if (#15 > 9) { // if iteration count > 9,
#9 = '@' // print '@'
}
break
}
#33 = #31 - #32 + #11 // temp = x*x - y*y + x0
#22 = (#21/10 * #22) / 500 + #12 // y = 2*x*y + y0
#21 = #33 // x = temp
}
Ins_Char(#9)
}
Ins_Newline
}
BOF
- Output:
1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111 1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211 1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 1111111111111112222222222222333333333333333333333333333333333333322222222222222222222222222222222222222 1111111111111222222222233333333333333333333333344444457655544443333332222222222222222222222222222222222 1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 11111111111222222333333333333333333333334444444445555678@@@@7654444443333332222222222222222222222222222 1111111112222223333333333333333333333444444444455556789@@@@98655544444433333332222222222222222222222222 1111111122222333333333333333333333344444444445556668@@@ @@@@76555544444333333322222222222222222222222 1111111122233333333333333333333344444444445566667778@@ @987666555544433333333222222222222222222222 111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@87777@95443333333322222222222222222222 1111112233333333333333333334444455555556678@@ @@ @@@@@@@8544333333333222222222222222222 1111122333333333333333334445555555555666789@@@ @86554433333333322222222222222222 1111123333333333333444466666555556666778@@@@ @@87655443333333332222222222222222 111123333333344444455568@887789@8777788@@@ @@@@65443333333332222222222222222 1111333344444444455556679@@@@@@@@@@@99@@@ @@765444333333333222222222222222 1111334444444455555567789@@ @@@@ @855444333333333222222222222222 11114444444455555668@99@@@ @ @@655444433333333322222222222222 11134555556666677789@@@ @ @86655444433333333322222222222222 111 @@876555444433333333322222222222222 11134555556666677789@@@ @ @86655444433333333322222222222222 11114444444455555668@99@@@ @ @@655444433333333322222222222222 1111334444444455555567789@@ @@@@ @855444333333333222222222222222 1111333344444444455556679@@@@@@@@@@@99@@@ @@765444333333333222222222222222 111123333333344444455568@887789@8777788@@@ @@@@65443333333332222222222222222 1111123333333333333444466666555556666778@@@@ @@87655443333333332222222222222222 1111122333333333333333334445555555555666789@@@ @86554433333333322222222222222222 1111112233333333333333333334444455555556678@@ @@ @@@@@@@8544333333333222222222222222222 111111122333333333333333333333444444455556@@@@@99@@@@@@ @@@@@@87777@95443333333322222222222222222222 1111111122233333333333333333333344444444445566667778@@ @987666555544433333333222222222222222222222 1111111122222333333333333333333333344444444445556668@@@ @@@@76555544444333333322222222222222222222222 1111111112222223333333333333333333333444444444455556789@@@@98655544444433333332222222222222222222222222 11111111111222222333333333333333333333334444444445555678@@@@7654444443333332222222222222222222222222222 1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222 1111111111111222222222233333333333333333333333344444457655544443333332222222222222222222222222222222222 1111111111111112222222222222333333333333333333333333333333333333322222222222222222222222222222222222222 1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222 1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222 1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211
V (Vlang)
Graphical
// updates and contributors at: github.com/vlang/v/blob/master/examples/gg/mandelbrot.v
// graphics are moveable by keyboard or mouse and resizable with window
import gg
import gx
import runtime
import time
const (
pwidth = 800
pheight = 600
chunk_height = 2 // image recalculated in chunks, each chunk processed in separate thread
zoom_factor = 1.1
max_iterations = 255
)
struct ViewRect {
mut:
x_min f64
x_max f64
y_min f64
y_max f64
}
fn (v &ViewRect) width() f64 {
return v.x_max - v.x_min
}
fn (v &ViewRect) height() f64 {
return v.y_max - v.y_min
}
struct AppState {
mut:
gg &gg.Context = unsafe { nil }
iidx int
pixels &u32 = unsafe { vcalloc(pwidth * pheight * sizeof(u32)) }
npixels &u32 = unsafe { vcalloc(pwidth * pheight * sizeof(u32)) } // drawings here, results swapped at the end
view ViewRect = ViewRect{-3.0773593290970673, 1.4952456603855397, -2.019938598189011, 2.3106642054225945}
scale int = 1
ntasks int = runtime.nr_jobs()
}
const colors = [gx.black, gx.blue, gx.red, gx.green, gx.yellow, gx.orange, gx.purple, gx.white,
gx.indigo, gx.violet, gx.black, gx.blue, gx.orange, gx.yellow, gx.green].map(u32(it.abgr8()))
struct MandelChunk {
cview ViewRect
ymin f64
ymax f64
}
fn (mut state AppState) update() {
mut chunk_channel := chan MandelChunk{cap: state.ntasks}
mut chunk_ready_channel := chan bool{cap: 1000}
mut threads := []thread{cap: state.ntasks}
defer {
chunk_channel.close()
threads.wait()
}
for t in 0 .. state.ntasks {
threads << spawn state.worker(t, chunk_channel, chunk_ready_channel)
}
//
mut oview := ViewRect{}
mut sw := time.new_stopwatch()
for {
sw.restart()
cview := state.view
if oview == cview {
time.sleep(5 * time.millisecond)
continue
}
// schedule chunks, describing the work:
mut nchunks := 0
for start := 0; start < pheight; start += chunk_height {
chunk_channel <- MandelChunk{
cview: cview
ymin: start
ymax: start + chunk_height
}
nchunks++
}
// wait for all chunks to be processed:
for _ in 0 .. nchunks {
_ := <-chunk_ready_channel
}
// everything is done, swap the buffer pointers
state.pixels, state.npixels = state.npixels, state.pixels
println('${state.ntasks:2} threads; ${sw.elapsed().milliseconds():3} ms / frame; scale: ${state.scale:4}')
oview = cview
}
}
[direct_array_access]
fn (mut state AppState) worker(id int, input chan MandelChunk, ready chan bool) {
for {
chunk := <-input or { break }
yscale := chunk.cview.height() / pheight
xscale := chunk.cview.width() / pwidth
mut x, mut y, mut iter := 0.0, 0.0, 0
mut y0 := chunk.ymin * yscale + chunk.cview.y_min
mut x0 := chunk.cview.x_min
for y_pixel := chunk.ymin; y_pixel < chunk.ymax && y_pixel < pheight; y_pixel++ {
yrow := unsafe { &state.npixels[int(y_pixel * pwidth)] }
y0 += yscale
x0 = chunk.cview.x_min
for x_pixel := 0; x_pixel < pwidth; x_pixel++ {
x0 += xscale
x, y = x0, y0
for iter = 0; iter < max_iterations; iter++ {
x, y = x * x - y * y + x0, 2 * x * y + y0
if x * x + y * y > 4 {
break
}
}
unsafe {
yrow[x_pixel] = colors[iter & 15]
}
}
}
ready <- true
}
}
fn (mut state AppState) draw() {
mut istream_image := state.gg.get_cached_image_by_idx(state.iidx)
istream_image.update_pixel_data(unsafe { &u8(state.pixels) })
size := gg.window_size()
state.gg.draw_image(0, 0, size.width, size.height, istream_image)
}
fn (mut state AppState) zoom(zoom_factor f64) {
c_x, c_y := (state.view.x_max + state.view.x_min) / 2, (state.view.y_max + state.view.y_min) / 2
d_x, d_y := c_x - state.view.x_min, c_y - state.view.y_min
state.view.x_min = c_x - zoom_factor * d_x
state.view.x_max = c_x + zoom_factor * d_x
state.view.y_min = c_y - zoom_factor * d_y
state.view.y_max = c_y + zoom_factor * d_y
state.scale += if zoom_factor < 1 { 1 } else { -1 }
}
fn (mut state AppState) center(s_x f64, s_y f64) {
c_x, c_y := (state.view.x_max + state.view.x_min) / 2, (state.view.y_max + state.view.y_min) / 2
d_x, d_y := c_x - state.view.x_min, c_y - state.view.y_min
state.view.x_min = s_x - d_x
state.view.x_max = s_x + d_x
state.view.y_min = s_y - d_y
state.view.y_max = s_y + d_y
}
// gg callbacks:
fn graphics_init(mut state AppState) {
state.iidx = state.gg.new_streaming_image(pwidth, pheight, 4, pixel_format: .rgba8)
}
fn graphics_frame(mut state AppState) {
state.gg.begin()
state.draw()
state.gg.end()
}
fn graphics_click(x f32, y f32, btn gg.MouseButton, mut state AppState) {
if btn == .right {
size := gg.window_size()
m_x := (x / size.width) * state.view.width() + state.view.x_min
m_y := (y / size.height) * state.view.height() + state.view.y_min
state.center(m_x, m_y)
}
}
fn graphics_move(x f32, y f32, mut state AppState) {
if state.gg.mouse_buttons.has(.left) {
size := gg.window_size()
d_x := (f64(state.gg.mouse_dx) / size.width) * state.view.width()
d_y := (f64(state.gg.mouse_dy) / size.height) * state.view.height()
state.view.x_min -= d_x
state.view.x_max -= d_x
state.view.y_min -= d_y
state.view.y_max -= d_y
}
}
fn graphics_scroll(e &gg.Event, mut state AppState) {
state.zoom(if e.scroll_y < 0 { zoom_factor } else { 1 / zoom_factor })
}
fn graphics_keydown(code gg.KeyCode, mod gg.Modifier, mut state AppState) {
s_x := state.view.width() / 5
s_y := state.view.height() / 5
// movement
mut d_x, mut d_y := 0.0, 0.0
if code == .enter {
println('> ViewRect{${state.view.x_min}, ${state.view.x_max}, ${state.view.y_min}, ${state.view.y_max}}')
}
if state.gg.pressed_keys[int(gg.KeyCode.left)] {
d_x -= s_x
}
if state.gg.pressed_keys[int(gg.KeyCode.right)] {
d_x += s_x
}
if state.gg.pressed_keys[int(gg.KeyCode.up)] {
d_y -= s_y
}
if state.gg.pressed_keys[int(gg.KeyCode.down)] {
d_y += s_y
}
state.view.x_min += d_x
state.view.x_max += d_x
state.view.y_min += d_y
state.view.y_max += d_y
// zoom in/out
if state.gg.pressed_keys[int(gg.KeyCode.left_bracket)]
|| state.gg.pressed_keys[int(gg.KeyCode.z)] {
state.zoom(1 / zoom_factor)
return
}
if state.gg.pressed_keys[int(gg.KeyCode.right_bracket)]
|| state.gg.pressed_keys[int(gg.KeyCode.x)] {
state.zoom(zoom_factor)
return
}
}
fn main() {
mut state := &AppState{}
state.gg = gg.new_context(
width: 800
height: 600
create_window: true
window_title: 'The Mandelbrot Set'
init_fn: graphics_init
frame_fn: graphics_frame
click_fn: graphics_click
move_fn: graphics_move
keydown_fn: graphics_keydown
scroll_fn: graphics_scroll
user_data: state
)
spawn state.update()
state.gg.run()
}
Wren
import "graphics" for Canvas, Color
import "dome" for Window
var MaxIters = 570
var Zoom = 150
class MandelbrotSet {
construct new(width, height) {
Window.title = "Mandelbrot Set"
Window.resize(width, height)
Canvas.resize(width, height)
_w = width
_h = height
}
init() {
createMandelbrot()
}
createMandelbrot() {
for (x in 0..._w) {
for (y in 0..._h) {
var zx = 0
var zy = 0
var cX = (x - 400) / Zoom
var cY = (y - 300) / Zoom
var i = MaxIters
while (zx * zx + zy * zy < 4 && i > 0) {
var tmp = zx * zx - zy * zy + cX
zy = 2 * zx * zy + cY
zx = tmp
i = i - 1
}
var r = i * 255 / MaxIters
Canvas.pset(x, y, Color.rgb(r, r, r))
}
}
}
update() {}
draw(alpha) {}
}
var Game = MandelbrotSet.new(800, 600)
- Output:
XPL0
include c:\cxpl\codes; \intrinsic 'code' declarations
int X, Y, \screen coordinates of current point
Cnt; \iteration counter
real Cx, Cy, \coordinates scaled to +/-2 range
Zx, Zy, \complex accumulator
Temp; \temporary scratch
[SetVid($112); \set 640x480x24 graphics mode
for Y:= 0 to 480-1 do \for all points on the screen...
for X:= 0 to 640-1 do
[Cx:= (float(X)/640.0 - 0.5) * 4.0; \range: -2.0 to +2.0
Cy:= (float(Y-240)/240.0) * 1.5; \range: -1.5 to +1.5
Cnt:= 0; Zx:= 0.0; Zy:= 0.0; \initialize
loop [if Zx*Zx + Zy*Zy > 2.0 then \Z heads toward infinity
[Point(X, Y, Cnt<<21+Cnt<<10+Cnt<<3); \set color of pixel to
quit; \ rate it approached infinity
]; \move on to next point
Temp:= Zx*Zy;
Zx:= Zx*Zx - Zy*Zy + Cx; \calculate next iteration of Z
Zy:= 2.0*Temp + Cy;
Cnt:= Cnt+1; \count number of iterations
if Cnt >= 1000 then quit; \assume point is in Mandelbrot
]; \ set and leave it colored black
];
X:= ChIn(1); \wait for keystroke
SetVid($03); \restore normal text display
]
- Output:
XSLT
The fact that you can create an image of the Mandelbrot Set with XSLT is sometimes under-appreciated. However, it has been discussed extensively on the internet so is best reproduced here, and the code can be executed directly in your browser at that site.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- XSLT Mandelbrot - written by Joel Yliluoma 2007, http://iki.fi/bisqwit/ -->
<xsl:output method="html" indent="no"
doctype-public="-//W3C//DTD HTML 4.01//EN"
doctype-system="http://www.w3.org/TR/REC-html40/strict.dtd"
/>
<xsl:template match="/fractal">
<html>
<head>
<title>XSLT fractal</title>
<style type="text/css">
body { color:#55F; background:#000 }
pre { font-family:monospace; font-size:7px }
pre span { background:<xsl:value-of select="background" /> }
</style>
</head>
<body>
<div style="position:absolute;top:20px;left:20em">
Copyright © 1992,2007 Joel Yliluoma
(<a href="http://iki.fi/bisqwit/">http://iki.fi/bisqwit/</a>)
</div>
<h1 style="margin:0px">XSLT fractal</h1>
<pre><xsl:call-template name="bisqwit-mandelbrot" /></pre>
</body>
</html>
</xsl:template>
<xsl:template name="bisqwit-mandelbrot"
><xsl:call-template name="bisqwit-mandelbrot-line">
<xsl:with-param name="y" select="y/min"/>
</xsl:call-template
></xsl:template>
<xsl:template name="bisqwit-mandelbrot-line"
><xsl:param name="y"
/><xsl:call-template name="bisqwit-mandelbrot-column">
<xsl:with-param name="x" select="x/min"/>
<xsl:with-param name="y" select="$y"/>
</xsl:call-template
><xsl:if test="$y < y/max"
><br
/><xsl:call-template name="bisqwit-mandelbrot-line">
<xsl:with-param name="y" select="$y + y/step"/>
</xsl:call-template
></xsl:if
></xsl:template>
<xsl:template name="bisqwit-mandelbrot-column"
><xsl:param name="x"
/><xsl:param name="y"
/><xsl:call-template name="bisqwit-mandelbrot-slot">
<xsl:with-param name="x" select="$x" />
<xsl:with-param name="y" select="$y" />
<xsl:with-param name="zr" select="$x" />
<xsl:with-param name="zi" select="$y" />
</xsl:call-template
><xsl:if test="$x < x/max"
><xsl:call-template name="bisqwit-mandelbrot-column">
<xsl:with-param name="x" select="$x + x/step"/>
<xsl:with-param name="y" select="$y" />
</xsl:call-template
></xsl:if
></xsl:template>
<xsl:template name="bisqwit-mandelbrot-slot"
><xsl:param name="x"
/><xsl:param name="y"
/><xsl:param name="zr"
/><xsl:param name="zi"
/><xsl:param name="iter" select="0"
/><xsl:variable name="zrsqr" select="($zr * $zr)"
/><xsl:variable name="zisqr" select="($zi * $zi)"
/><xsl:choose>
<xsl:when test="(4*scale*scale >= $zrsqr + $zisqr) and (maxiter > $iter+1)"
><xsl:call-template name="bisqwit-mandelbrot-slot">
<xsl:with-param name="x" select="$x" />
<xsl:with-param name="y" select="$y" />
<xsl:with-param name="zi" select="(2 * $zr * $zi) div scale + $y" />
<xsl:with-param name="zr" select="($zrsqr - $zisqr) div scale + $x" />
<xsl:with-param name="iter" select="$iter + 1" />
</xsl:call-template
></xsl:when>
<xsl:otherwise
><xsl:variable name="magnitude" select="magnitude[@value=$iter]"
/><span style="color:{$magnitude/color}"
><xsl:value-of select="$magnitude/symbol"
/></span></xsl:otherwise>
</xsl:choose
></xsl:template>
</xsl:stylesheet>
Z80 Assembly
;
; Compute a Mandelbrot set on a simple Z80 computer.
;
; Porting this program to another Z80 platform should be easy and straight-
; forward: The only dependencies on my homebrew machine are the system-calls
; used to print strings and characters. These calls are performed by loading
; IX with the number of the system-call and performing an RST 08. To port this
; program to another operating system just replace these system-calls with
; the appropriate versions. Only three system-calls are used in the following:
; _crlf: Prints a CR/LF, _puts: Prints a 0-terminated string (the adress of
; which is expected in HL), and _putc: Print a single character which is
; expected in A. RST 0 give control back to the monitor.
;
#include "mondef.asm"
org ram_start
scale equ 256 ; Do NOT change this - the
; arithmetic routines rely on
; this scaling factor! :-)
divergent equ scale * 4
ld hl, welcome ; Print a welcome message
ld ix, _puts
rst 08
; for (y = <initial_value> ; y <= y_end; y += y_step)
; {
outer_loop ld hl, (y_end) ; Is y <= y_end?
ld de, (y)
and a ; Clear carry
sbc hl, de ; Perform the comparison
jp m, mandel_end ; End of outer loop reached
; for (x = x_start; x <= x_end; x += x_step)
; {
ld hl, (x_start) ; x = x_start
ld (x), hl
inner_loop ld hl, (x_end) ; Is x <= x_end?
ld de, (x)
and a
sbc hl, de
jp m, inner_loop_end ; End of inner loop reached
; z_0 = z_1 = 0;
ld hl, 0
ld (z_0), hl
ld (z_1), hl
; for (iteration = iteration_max; iteration; iteration--)
; {
ld a, (iteration_max)
ld b, a
iteration_loop push bc ; iteration -> stack
; z2 = (z_0 * z_0 - z_1 * z_1) / SCALE;
ld de, (z_1) ; Compute DE HL = z_1 * z_1
ld bc, de
call mul_16
ld (z_0_square_low), hl ; z_0 ** 2 is needed later again
ld (z_0_square_high), de
ld de, (z_0) ; Compute DE HL = z_0 * z_0
ld bc, de
call mul_16
ld (z_1_square_low), hl ; z_1 ** 2 will be also needed
ld (z_1_square_high), de
and a ; Compute subtraction
ld bc, (z_0_square_low)
sbc hl, bc
ld (scratch_0), hl ; Save lower 16 bit of result
ld hl, de
ld bc, (z_0_square_high)
sbc hl, bc
ld bc, (scratch_0) ; HL BC = z_0 ** 2 - z_1 ** 2
ld c, b ; Divide by scale = 256
ld b, l ; Discard the rest
push bc ; We need BC later
; z3 = 2 * z0 * z1 / SCALE;
ld hl, (z_0) ; Compute DE HL = 2 * z_0 * z_1
add hl, hl
ld de, hl
ld bc, (z_1)
call mul_16
ld b, e ; Divide by scale (= 256)
ld c, h ; BC contains now z_3
; z1 = z3 + y;
ld hl, (y)
add hl, bc
ld (z_1), hl
; z_0 = z_2 + x;
pop bc ; Here BC is needed again :-)
ld hl, (x)
add hl, bc
ld (z_0), hl
; if (z0 * z0 / SCALE + z1 * z1 / SCALE > 4 * SCALE)
ld hl, (z_0_square_low) ; Use the squares computed
ld de, (z_1_square_low) ; above
add hl, de
ld bc, hl ; BC contains lower word of sum
ld hl, (z_0_square_high)
ld de, (z_1_square_high)
adc hl, de
ld h, l ; HL now contains (z_0 ** 2 +
ld l, b ; z_1 ** 2) / scale
ld bc, divergent
and a
sbc hl, bc
; break;
jp c, iteration_dec ; No break
pop bc ; Get latest iteration counter
jr iteration_end ; Exit loop
; iteration++;
iteration_dec pop bc ; Get iteration counter
djnz iteration_loop ; We might fall through!
; }
iteration_end
; printf("%c", display[iteration % 7]);
ld a, b
and $7 ; lower three bits only (c = 0)
sbc hl, hl
ld l, a
ld de, display ; Get start of character array
add hl, de ; address and load the
ld a, (hl) ; character to be printed
ld ix, _putc ; Print the character
rst 08
ld de, (x_step) ; x += x_step
ld hl, (x)
add hl, de
ld (x), hl
jp inner_loop
; }
; printf("\n");
inner_loop_end ld ix, _crlf ; Print a CR/LF pair
rst 08
ld de, (y_step) ; y += y_step
ld hl, (y)
add hl, de
ld (y), hl ; Store new y-value
jp outer_loop
; }
mandel_end ld hl, finished ; Print finished-message
ld ix, _puts
rst 08
rst 0 ; Return to the monitor
welcome defb "Generating a Mandelbrot set"
defb cr, lf, eos
finished defb "Computation finished.", cr, lf, eos
iteration_max defb 10 ; How many iterations
x defw 0 ; x-coordinate
x_start defw -2 * scale ; Minimum x-coordinate
x_end defw 5 * scale / 10 ; Maximum x-coordinate
x_step defw 4 * scale / 100 ; x-coordinate step-width
y defw -1 * scale ; Minimum y-coordinate
y_end defw 1 * scale ; Maximum y-coordinate
y_step defw 1 * scale / 10 ; y-coordinate step-width
z_0 defw 0
z_1 defw 0
scratch_0 defw 0
z_0_square_high defw 0
z_0_square_low defw 0
z_1_square_high defw 0
z_1_square_low defw 0
display defb " .-+*=#@" ; 8 characters for the display
;
; Compute DEHL = BC * DE (signed): This routine is not too clever but it
; works. It is based on a standard 16-by-16 multiplication routine for unsigned
; integers. At the beginning the sign of the result is determined based on the
; signs of the operands which are negated if necessary. Then the unsigned
; multiplication takes place, followed by negating the result if necessary.
;
mul_16 xor a ; Clear carry and A (-> +)
bit 7, b ; Is BC negative?
jr z, bc_positive ; No
sub c ; A is still zero, complement
ld c, a
ld a, 0
sbc a, b
ld b, a
scf ; Set carry (-> -)
bc_positive bit 7, D ; Is DE negative?
jr z, de_positive ; No
push af ; Remember carry for later!
xor a
sub e
ld e, a
ld a, 0
sbc a, d
ld d, a
pop af ; Restore carry for complement
ccf ; Complement Carry (-> +/-?)
de_positive push af ; Remember state of carry
and a ; Start multiplication
sbc hl, hl
ld a, 16 ; 16 rounds
mul_16_loop add hl, hl
rl e
rl d
jr nc, mul_16_exit
add hl, bc
jr nc, mul_16_exit
inc de
mul_16_exit dec a
jr nz, mul_16_loop
pop af ; Restore carry from beginning
ret nc ; No sign inversion necessary
xor a ; Complement DE HL
sub l
ld l, a
ld a, 0
sbc a, h
ld h, a
ld a, 0
sbc a, e
ld e, a
ld a, 0
sbc a, d
ld d, a
ret
- Output:
Generating a Mandelbrot set ....... @@@@@@@@@@@@@@@@@@@@########===*+ . *######@@@@@ ...... @@@@@@@@@@@@@@@@@@@@#########====+-. -*===#####@@@@ ..... @@@@@@@@@@@@@@@@@@@@#########===**+- +*====####@@ .... @@@@@@@@@@@@@@@@@@@########==*+-.-+-.. .-+****+*##@ ... @@@@@@@@@@@@@@@@@#####=====**+- -=# .. @@@@@@@@@@@@@@@###=========***+- -*== ..@@@@@@@@@@####==- +*******++++- -+= . @@@@#######===**- ... -* .@@#######======++- += .#######=****+- +*= .=**++ .-.... .+*== .#=====****+++. -*== .@#######=====*--- .*= .@@@########====*++. += . @@@@@@@######==*+ .-++- --++--. = .. @@@@@@@@@@@@@##==*=======****+ -+*= ... @@@@@@@@@@@@@@@@####=======***+- +== ... @@@@@@@@@@@@@@@@@@@######====*- . --+- *## .... @@@@@@@@@@@@@@@@@@@@########==****++- .-+**====###@ ..... @@@@@@@@@@@@@@@@@@@@##########===*+ *===#####@@@ ....... @@@@@@@@@@@@@@@@@@@@@########===*+-. .+*=######@@@@@ Computation finished.
zkl
Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl
![](http://static.miraheze.org/rosettacodewiki/thumb/0/03/Mandelbrot.zkl.jpg/300px-Mandelbrot.zkl.jpg)
fcn mandelbrot{ // lord this is slooooow
bitmap:=PPM(640,480);
foreach y,x in ([0..479],[0..639]){
cx:=(x.toFloat()/640 - 0.5)*4.0; //range: -2.0 to +2.0
cy:=((y-240).toFloat()/240.0)*1.5; //range: -1.5 to +1.5
cnt:=0; zx:=0.0; zy:=0.0;
do(1000){
if(zx*zx + zy*zy > 2.0){ //z heads toward infinity
//set color of pixel to rate it approaches infinity
bitmap[x,y]=cnt.shiftLeft(21) + cnt.shiftLeft(10) + cnt*8;
break;
}
temp:=zx*zy;
zx=zx*zx - zy*zy + cx; //calculate next iteration of z
zy=2.0*temp + cy;
cnt+=1;
}
}
bitmap.write(File("foo.ppm","wb"));
}();
- WikipediaSourced
- Programming Tasks
- Fractals
- Graphics
- Raster graphics operations
- 11l
- ACL2
- AArch64 Assembly
- GNU Compiler Collection
- Ada
- Lumen
- ALGOL 68
- ALGOL W
- Amazing Hopper
- Arturo
- ATS
- SDL2
- Ats2-xprelude
- AutoHotkey
- AWK
- B
- Bc
- Pages with broken file links
- BASIC
- AmigaBASIC
- Applesoft BASIC
- ARM BBC BASIC
- BASIC256
- BBC BASIC
- Commander X16 BASIC
- Commodore BASIC
- VIC-20 with Super Expander cartridge
- C-64 with Super Expander 64
- Commodore-16 / 116 / Plus/4
- Commodore 128 (40-column display)
- Commodore 128 (80-column display)
- Commodore PET
- DEC BASIC-PLUS
- FreeBASIC
- GW-BASIC
- Liberty BASIC
- Locomotive Basic
- Microsoft Small Basic
- Microsoft Super Extended Color BASIC (Tandy Color Computer 3)
- MSX Basic
- Nascom BASIC
- OS/8 BASIC
- PureBasic
- QBasic
- Quite BASIC
- Run BASIC
- Sinclair ZX81 BASIC
- SmileBASIC
- TI-Basic Color
- True BASIC
- Visual BASIC for Applications on Excel
- Yabasic
- Befunge
- Brace
- Brainf***
- C
- GLUT
- C sharp
- C++
- C3
- Cixl
- Clojure
- COBOL
- Common Lisp
- Cowgol
- Craft Basic
- D
- QD
- SDL
- Phobos
- Dart
- Dc
- Delphi
- DWScript
- EasyLang
- EC
- EchoLisp
- Elixir
- Emacs Lisp
- Erlang
- ERRE
- F Sharp
- Factor
- Fennel
- FOCAL
- Forth
- Fortran
- Frink
- Furor
- Futhark
- Futhark examples needing attention
- Examples needing attention
- FutureBasic
- Fōrmulæ
- GLSL
- Gnuplot
- Go
- Golfscript
- Hare
- Haskell
- Haxe
- Huginn
- Icon
- Unicon
- Icon Programming Library
- Unicon examples needing attention
- IDL
- Inform 7
- Glimmr Drawing Commands by Erik Temple
- Insitux
- J
- Java
- Swing
- AWT
- JavaScript
- Jq
- Julia
- Kotlin
- LabVIEW
- Lang5
- Lambdatalk
- Lasso
- LIL
- Logo
- Lua
- M2000 Interpreter
- M4
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Maxima
- Metapost
- MiniScript
- Modula-3
- MySQL
- Nim
- Imageman
- ObjectIcon
- OCaml
- Octave
- Ol
- OpenEdge/Progress
- PARI/GP
- Pascal
- Peri
- Perl
- Phix
- PHP
- GD Graphics Library
- Picat
- PicoLisp
- PostScript
- PowerShell
- Processing
- Processing Python mode
- Prolog
- Python
- Matplotlib
- NumPy
- Q
- R
- Racket
- Raku
- REXX
- Ring
- Ruby
- RubyGems
- JRubyArt
- Rust
- Sass/SCSS
- Scala
- Scheme
- Scratch
- Seed7
- SenseTalk
- SequenceL
- CImg
- Sidef
- Simula
- Spin
- SparForte
- SPL
- Swift
- Tcl
- Tk
- PlainTeX
- Pst-fractal
- LaTeX
- PGF
- LuaTeX
- TI-83 BASIC
- Transact-SQL
- TXR
- UBasic/4tH
- Uiua
- UNIX Shell
- Vala
- VBScript
- Vedit macro language
- V (Vlang)
- Wren
- DOME
- XPL0
- XSLT
- M4/Omit
- Z80 Assembly
- Zkl
- Lilypond/Omit
- ML/I/Omit
- Geometry
- Pages with too many expensive parser function calls