import {toFixed, mul} from './fixed.js'; let toFixedLog = toFixed; function toFixed16(val) { // 4.12 return Math.round(val * (2 ** 12)) } let four16 = toFixed16(4); function imul(a, b) { return Math.imul(a, b) >> 12; } function logmul(a, b) { if ((a | b) == 0) { return 0; } let neg = 0; if (a < 0) { a = -a; neg++; } if (b < 0) { b = -b; neg++; } let product = mul(a, b); if (neg == 1) { product = -product; } return product; } let fourLog = toFixedLog(4); let max = 256; let width = 256; let height = 256; let zoom = 0; let offsetX = 0; let offsetY = 0; function scale() { return 1 / (2 ** zoom); } let cancelled = false; async function cancel() { cancelled = true; return await nap(100); } let black = 0xff000000; let tricolor = [ 0xffff0000, 0xff00ff00, 0xff0000ff, ]; let palette = new Uint32Array(256); palette[0] = black; for (let i = 0; i < 255; i++) { palette[i + 1] = tricolor[i % 3]; } function nap(ms=0) { return new Promise((resolve) => setTimeout(() => resolve(), ms)); } function attach(id, func) { document.getElementById(id).addEventListener('click', (_event) => { cancel().then(() => { func(); run(); }); }); } attach('zoom-in', () => { zoom++; }); attach('zoom-out', () => { if (zoom >= 1) { zoom--; } }); attach('left', () => { offsetX -= scale(); }); attach('right', () => { offsetX += scale(); }); attach('up', () => { offsetY -= scale(); }); attach('down', () => { offsetY += scale(); }); async function setup(id, iterfunc) { let canvas = document.getElementById(id); let ctx = canvas.getContext('2d'); let imageData = ctx.createImageData(width, height); let rgba = new Uint32Array(imageData.data.buffer); cancelled = false; for (let y = 0; y < height; y++) { let cy = scale() * (y * 2 - height) / (height / 2) + offsetY; for (let x = 0; x < width; x++) { let cx = scale() * (x * 2 - width) / (width / 2) + offsetX; let i = iterfunc(cx, cy); let color = palette[i]; rgba[y * width + x] = color; if (x % 256 == 255) { ctx.putImageData(imageData, 0, 0); await nap(); if (cancelled) { return; } } } } } function run() { setup('float', (cx, cy) => { let zx = 0; let zy = 0; let zx_2 = 0; let zy_2 = 0; let zx_zy = 0; for (let i = 1; i < max; i++) { zx = zx_2 - zy_2 + cx; zy = zx_zy + zx_zy + cy; zx_2 = zx * zx; zy_2 = zy * zy; zx_zy = zx * zy; if (zx_2 + zy_2 >= 4) { return i; } } return 0; }).then(() => { console.log('float done'); }); setup('imul', (cx, cy) => { cx = toFixed16(cx); cy = toFixed16(cy); let zx = 0; let zy = 0; let zx_2 = 0; let zy_2 = 0; let zx_zy = 0; for (let i = 1; i < max; i++) { zx = zx_2 - zy_2 + cx; zy = zx_zy + zx_zy + cy; zx_2 = imul(zx, zx); zy_2 = imul(zy, zy); zx_zy = imul(zx, zy); if (zx_2 + zy_2 >= four16) { return i; } } return 0; }).then(() => { console.log('imul done'); }); setup('log', (cx, cy) => { cx = toFixedLog(cx); cy = toFixedLog(cy); let zx = 0; let zy = 0; let zx_2 = 0; let zy_2 = 0; let zx_zy = 0; for (let i = 1; i < max; i++) { zx = zx_2 - zy_2 + cx; zy = zx_zy + zx_zy + cy; zx_2 = logmul(zx, zx); zy_2 = logmul(zy, zy); zx_zy = logmul(zx, zy); if (zx_2 + zy_2 >= fourLog) { return i; } } return 0; }).then(() => { console.log('log done'); }); } run();