3 // XXXbz I would dearly like to wrap it up into a function to avoid polluting
4 // the global scope, but the function ends up heavyweight, and then we lose on
6 load(libdir + "mandelbrot-results.js");
7 //function testMandelbrotAll() {
8 // Configuration options that affect which codepaths we follow.
9 var doImageData = true;
10 var avoidSparseArray = true;
12 // Control of iteration numbers and sizing. We'll do
13 // scaler * colorNames.length iterations or so before deciding that we
43 const threshold = (colorNames.length - 1) * scaler;
45 // Now set up our colors
47 // 3-part for loop (iterators buggy, we will add a separate test for them)
48 for (var colorNameIdx = 0; colorNameIdx < colorNames.length; ++colorNameIdx) {
49 //for (var colorNameIdx in colorNames) {
50 colorNameIdx = parseInt(colorNameIdx);
51 colors.push([colorNameIdx, colorNameIdx, colorNameIdx, 0]);
54 // Storage for our point data
59 function complexMult(a, b) {
60 var newr = a.r * b.r - a.i * b.i;
61 var newi = a.r * b.i + a.i * b.r;
66 function complexAdd(a, b) {
67 scratch.r = a.r + b.r;
68 scratch.i = a.i + b.i;
72 return Math.sqrt(a.r * a.r + a.i * a.i);
75 function escapeAbsDiff(normZ, absC) {
76 var absZ = Math.sqrt(normZ);
77 return normZ > absZ + absC;
80 function escapeNorm2(normZ) {
84 function fuzzyColors(i) {
85 return Math.floor(i / scaler) + 1;
88 function moddedColors(i) {
89 return (i % (colorNames.length - 1)) + 1;
92 function computeEscapeSpeedObjects(real, imag) {
93 var c = { r: real, i: imag }
94 scratchZ.r = scratchZ.i = 0;
96 for (var i = 0; i < threshold; ++i) {
97 scratchZ = complexAdd(c, complexMult(scratchZ, scratchZ));
98 if (escape(scratchZ.r * scratchZ.r + scratchZ.i * scratchZ.i,
106 function computeEscapeSpeedOneObject(real, imag) {
107 // fold in the fact that we start with 0
110 var absC = abs({r: real, i: imag});
111 for (var j = 0; j < threshold; ++j) {
114 if (escape(r2 + i2, absC)) {
117 i = 2 * r * i + imag;
123 function computeEscapeSpeedDoubles(real, imag) {
124 // fold in the fact that we start with 0
127 var absC = Math.sqrt(real * real + imag * imag);
128 for (var j = 0; j < threshold; ++j) {
131 if (escape(r2 + i2, absC)) {
134 i = 2 * r * i + imag;
140 var computeEscapeSpeed = computeEscapeSpeedDoubles;
141 var escape = escapeNorm2;
142 var colorMap = fuzzyColors;
144 function addPointOrig(pointArray, n, i, j) {
147 points[n].push([i, j, 1, 1]);
149 var point = points[n][points[n].length-1];
150 if (point[0] == i && point[1] == j - point[3]) {
153 points[n].push([i, j, 1, 1]);
158 function addPointImagedata(pointArray, n, col, row) {
159 var slotIdx = ((row * numCols) + col) * 4;
160 pointArray[slotIdx] = colors[n][0];
161 pointArray[slotIdx+1] = colors[n][1];
162 pointArray[slotIdx+2] = colors[n][2];
163 pointArray[slotIdx+3] = colors[n][3];
166 function createMandelSet() {
167 var realRange = { min: -2.1, max: 1 };
168 var imagRange = { min: -1.5, max: 1.5 };
172 addPoint = addPointImagedata;
173 points = new Array(4*numCols*numRows);
174 if (avoidSparseArray) {
175 for (var idx = 0; idx < 4*numCols*numRows; ++idx) {
180 addPoint = addPointOrig;
183 var realStep = (realRange.max - realRange.min)/numCols;
184 var imagStep = (imagRange.min - imagRange.max)/numRows;
185 for (var i = 0, curReal = realRange.min;
187 ++i, curReal += realStep) {
188 for (var j = 0, curImag = imagRange.max;
190 ++j, curImag += imagStep) {
191 var n = computeEscapeSpeed(curReal, curImag);
192 addPoint(points, n, i, j)
197 if (colorMap == fuzzyColors) {
198 result = mandelbrotImageDataFuzzyResult;
200 result = mandelbrotImageDataModdedResult;
203 result = mandelbrotNoImageDataResult;
205 return points.toSource() == result;
208 const escapeTests = [ escapeAbsDiff ];
209 const colorMaps = [ fuzzyColors, moddedColors ];
210 const escapeComputations = [ computeEscapeSpeedObjects,
211 computeEscapeSpeedOneObject,
212 computeEscapeSpeedDoubles ];
213 // Test all possible escape-speed generation codepaths, using the
214 // imageData + sparse array avoidance storage.
216 avoidSparseArray = true;
217 for (var escapeIdx in escapeTests) {
218 escape = escapeTests[escapeIdx];
219 for (var colorMapIdx in colorMaps) {
220 colorMap = colorMaps[colorMapIdx];
221 for (var escapeComputationIdx in escapeComputations) {
222 computeEscapeSpeed = escapeComputations[escapeComputationIdx];
223 assertEq(createMandelSet(), true);
228 // Test all possible storage strategies. Note that we already tested
229 // doImageData == true with avoidSparseArray == true.
230 escape = escapeAbsDiff;
231 colorMap = fuzzyColors; // This part doesn't really matter too much here
232 computeEscapeSpeed = computeEscapeSpeedDoubles;
235 avoidSparseArray = false;
236 assertEq(createMandelSet(), true);
238 escape = escapeNorm2;
239 doImageData = false; // avoidSparseArray doesn't matter here
240 assertEq(createMandelSet(), true);
242 //testMandelbrotAll();