I figured I'd have a go at rendering the duck fractal described here:
http://www.algorithmic-worlds.net/blog/blog.php?Post=20110227Now I think I'm doing it more or less right because I'm getting the duck shape (with a different orientation, probably because of how I'm rendering it vis à vis mapping the subset of the complex plane I'm looking at to pixels) ... but contrast is not good. Here is how it is shown in the blog:
and here's mine:
Right now I'm taking cumulative moving averages of the magnitude of z at each point, multiplying that by 100, then using floor() to make sure they're all integers. Then I find the minimum and maximum averages and create a linear gradient from white to black with [(maximum avg - minimum avg) + 1] steps. Then I biject from the averages to the list representing the gradient.
For whatever its worth, here is the code, in OCaml (ps I see too many posts where no one uses the code tags; they're there for a reason!):
open Complex;;
open Batteries_uni;;
let x = 500;;
let y = 875;;
let nw_corner = {re = (-1.); im = 0.};;
let se_corner = {re = 1.; im = Float.neg (4. *. atan 1.)};;
let width = se_corner.re -. nw_corner.re;;
let height = nw_corner.im -. se_corner.im;;
let () = begin
prerr_float width; prerr_newline ();
prerr_float height; prerr_newline ();
end;;
let pixel_coordinates_to_complex_plane (i, j) (x, y) origin width height =
{re = origin.re +. width *. (float_of_int i /. float_of_int x);
im = origin.im -. height *. (float_of_int j /. float_of_int y)};;
let labs z =
if z.im >= 0.
then z
else conj z;;
let matrix_of_means_of_norms_of_z = Array.make_matrix y x 0.;;
let z = ref zero;;
let iterations = 50;;
let () = for i = 0 to x - 1 do
prerr_int i; prerr_newline ();
for j = 0 to y - 1 do
let point = pixel_coordinates_to_complex_plane
(i, j)
(x, y)
nw_corner
width
height in begin
(* prerr_int i; prerr_string " "; prerr_int j; prerr_string ": ";
prerr_float point.re; prerr_string " "; prerr_float point.im;
prerr_newline (); *)
z := zero;
for t = 0 to iterations - 1 do begin
z := Complex.log (Complex.add (labs !z) point);
(* cumulative moving average *)
matrix_of_means_of_norms_of_z.(j).(i) <-
(norm !z +. (float_of_int t) *. matrix_of_means_of_norms_of_z.(j).(i))
/. float_of_int (t + 1)
end done
end
done
done;;
let magnification = 100.;;
let color_matrix = matrix_of_means_of_norms_of_z |>
Array.map (fun row ->
row |> Array.map (fun mean ->
mean *. magnification |> floor |> int_of_float));;
let () = begin Array.to_list color_matrix
|> Array.concat
|> Array.fold_left max 0
|> prerr_int; prerr_newline();
Array.to_list color_matrix
|> Array.concat
|> Array.fold_left min max_int
|> prerr_int; prerr_newline();
end;;
let palette = [[255; 255; 255];
[255; 255; 255];
[254; 254; 254];
[253; 253; 253];
[252; 252; 252];
[251; 251; 251];
[250; 250; 250];
[249; 249; 249];
[249; 249; 249];
[248; 248; 248];
[247; 247; 247];
[246; 246; 246];
[245; 245; 245];
[244; 244; 244];
[243; 243; 243];
[242; 242; 242];
[242; 242; 242];
[241; 241; 241];
[240; 240; 240];
[239; 239; 239];
[238; 238; 238];
[237; 237; 237];
[236; 236; 236];
[235; 235; 235];
[235; 235; 235];
[234; 234; 234];
[233; 233; 233];
[232; 232; 232];
[231; 231; 231];
[230; 230; 230];
[229; 229; 229];
[229; 229; 229];
[228; 228; 228];
[227; 227; 227];
[226; 226; 226];
[225; 225; 225];
[224; 224; 224];
[223; 223; 223];
[222; 222; 222];
[222; 222; 222];
[221; 221; 221];
[220; 220; 220];
[219; 219; 219];
[218; 218; 218];
[217; 217; 217];
[216; 216; 216];
[215; 215; 215];
[215; 215; 215];
[214; 214; 214];
[213; 213; 213];
[212; 212; 212];
[211; 211; 211];
[210; 210; 210];
[209; 209; 209];
[209; 209; 209];
[208; 208; 208];
[207; 207; 207];
[206; 206; 206];
[205; 205; 205];
[204; 204; 204];
[203; 203; 203];
[202; 202; 202];
[202; 202; 202];
[201; 201; 201];
[200; 200; 200];
[199; 199; 199];
[198; 198; 198];
[197; 197; 197];
[196; 196; 196];
[195; 195; 195];
[195; 195; 195];
[194; 194; 194];
[193; 193; 193];
[192; 192; 192];
[191; 191; 191];
[190; 190; 190];
[189; 189; 189];
[188; 188; 188];
[188; 188; 188];
[187; 187; 187];
[186; 186; 186];
[185; 185; 185];
[184; 184; 184];
[183; 183; 183];
[182; 182; 182];
[182; 182; 182];
[181; 181; 181];
[180; 180; 180];
[179; 179; 179];
[178; 178; 178];
[177; 177; 177];
[176; 176; 176];
[175; 175; 175];
[175; 175; 175];
[174; 174; 174];
[173; 173; 173];
[172; 172; 172];
[171; 171; 171];
[170; 170; 170];
[169; 169; 169];
[168; 168; 168];
[168; 168; 168];
[167; 167; 167];
[166; 166; 166];
[165; 165; 165];
[164; 164; 164];
[163; 163; 163];
[162; 162; 162];
[162; 162; 162];
[161; 161; 161];
[160; 160; 160];
[159; 159; 159];
[158; 158; 158];
[157; 157; 157];
[156; 156; 156];
[155; 155; 155];
[155; 155; 155];
[154; 154; 154];
[153; 153; 153];
[152; 152; 152];
[151; 151; 151];
[150; 150; 150];
[149; 149; 149];
[148; 148; 148];
[148; 148; 148];
[147; 147; 147];
[146; 146; 146];
[145; 145; 145];
[144; 144; 144];
[143; 143; 143];
[142; 142; 142];
[141; 141; 141];
[141; 141; 141];
[140; 140; 140];
[139; 139; 139];
[138; 138; 138];
[137; 137; 137];
[136; 136; 136];
[135; 135; 135];
[135; 135; 135];
[134; 134; 134];
[133; 133; 133];
[132; 132; 132];
[131; 131; 131];
[130; 130; 130];
[129; 129; 129];
[128; 128; 128];
[128; 128; 128];
[127; 127; 127];
[126; 126; 126];
[125; 125; 125];
[124; 124; 124];
[123; 123; 123];
[122; 122; 122];
[121; 121; 121];
[121; 121; 121];
[120; 120; 120];
[119; 119; 119];
[118; 118; 118];
[117; 117; 117];
[116; 116; 116];
[115; 115; 115];
[115; 115; 115];
[114; 114; 114];
[113; 113; 113];
[112; 112; 112];
[111; 111; 111];
[110; 110; 110];
[109; 109; 109];
[108; 108; 108];
[108; 108; 108];
[107; 107; 107];
[106; 106; 106];
[105; 105; 105];
[104; 104; 104];
[103; 103; 103];
[102; 102; 102];
[101; 101; 101];
[101; 101; 101];
[100; 100; 100];
[99; 99; 99];
[98; 98; 98];
[97; 97; 97];
[96; 96; 96];
[95; 95; 95];
[94; 94; 94];
[94; 94; 94];
[93; 93; 93];
[92; 92; 92];
[91; 91; 91];
[90; 90; 90];
[89; 89; 89];
[88; 88; 88];
[88; 88; 88];
[87; 87; 87];
[86; 86; 86];
[85; 85; 85];
[84; 84; 84];
[83; 83; 83];
[82; 82; 82];
[81; 81; 81];
[81; 81; 81];
[80; 80; 80];
[79; 79; 79];
[78; 78; 78];
[77; 77; 77];
[76; 76; 76];
[75; 75; 75];
[74; 74; 74];
[74; 74; 74];
[73; 73; 73];
[72; 72; 72];
[71; 71; 71];
[70; 70; 70];
[69; 69; 69];
[68; 68; 68];
[68; 68; 68];
[67; 67; 67];
[66; 66; 66];
[65; 65; 65];
[64; 64; 64];
[63; 63; 63];
[62; 62; 62];
[61; 61; 61];
[61; 61; 61];
[60; 60; 60];
[59; 59; 59];
[58; 58; 58];
[57; 57; 57];
[56; 56; 56];
[55; 55; 55];
[54; 54; 54];
[54; 54; 54];
[53; 53; 53];
[52; 52; 52];
[51; 51; 51];
[50; 50; 50];
[49; 49; 49];
[48; 48; 48];
[47; 47; 47];
[47; 47; 47];
[46; 46; 46];
[45; 45; 45];
[44; 44; 44];
[43; 43; 43];
[42; 42; 42];
[41; 41; 41];
[41; 41; 41];
[40; 40; 40];
[39; 39; 39];
[38; 38; 38];
[37; 37; 37];
[36; 36; 36];
[35; 35; 35];
[34; 34; 34];
[34; 34; 34];
[33; 33; 33];
[32; 32; 32];
[31; 31; 31];
[30; 30; 30];
[29; 29; 29];
[28; 28; 28];
[27; 27; 27];
[27; 27; 27];
[26; 26; 26];
[25; 25; 25];
[24; 24; 24];
[23; 23; 23];
[22; 22; 22];
[21; 21; 21];
[21; 21; 21];
[20; 20; 20];
[19; 19; 19];
[18; 18; 18];
[17; 17; 17];
[16; 16; 16];
[15; 15; 15];
[14; 14; 14];
[14; 14; 14];
[13; 13; 13];
[12; 12; 12];
[11; 11; 11];
[10; 10; 10];
[9; 9; 9];
[8; 8; 8];
[7; 7; 7];
[7; 7; 7];
[6; 6; 6];
[5; 5; 5];
[4; 4; 4];
[3; 3; 3];
[2; 2; 2];
[1; 1; 1]];;
let () =
Printf.printf "P3\n";
Printf.printf "%d %d\n" x y;
Printf.printf "255\n";
for j = 0 to y - 1 do
for i = 0 to x - 1 do
let color = List.nth palette color_matrix.(j).(i) in
let r = List.nth color 0
and g = List.nth color 1
and b = List.nth color 2 in
Printf.printf "%d\t%d\t%d\t" r g b;
done;
print_newline ();
done;;
The output is PNM, as described here:
http://en.wikipedia.org/wiki/Netpbm_formatStatements with prerr are notifications and you can overlook them.
What can I be doing better?