Skip to content

Instantly share code, notes, and snippets.

@jcreedcmu
Created February 8, 2022 23:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcreedcmu/0985039bc981f7e9f241aea1e935dbef to your computer and use it in GitHub Desktop.
Save jcreedcmu/0985039bc981f7e9f241aea1e935dbef to your computer and use it in GitHub Desktop.
Make a wibbly image
// for any integer coordinates x, y, returns a float in [0,1] which is
// interpreted as threshold a float-valued function should have to
// reach in order to make a bitmap pixel.
function odither(x: number, y: number): number {
return (x == 0 && y == 0
? 0
: ([0, 2, 3, 1][(y % 2) * 2 + (x % 2)] + dither(x >> 1, y >> 1)) / 4);
}
function dither(x: number, y: number): number {
return odither(x, y + Math.floor(x / Math.sqrt(3)));
}
function tableau(edge: number, f: (x: number, y: number) => number): number[][] {
const table: number[][] = [...Array(edge).keys()].map(k => []);
for (let ii = 0; ii < edge; ii++) {
for (let jj = 0; jj < edge; jj++) {
if (f(ii / edge, jj / edge) > dither(ii, jj))
table[ii][jj] = 1;
}
}
return table;
}
function poster(n: number, x: number): number {
return Math.floor(x * n) / n;
}
function func(x: number, y: number): number {
const dx = x + 0.04 * Math.sin(y * 20);
const dy = y + 0.03 * Math.sin(x * 20);
const ddx = dx + 0.04 * Math.sin(dy * 20);
const ddy = dy + 0.03 * Math.sin(dx * 20);
return poster(9, 7 * (Math.pow(ddx - 0.5, 2) + Math.pow(ddy - 0.5, 2))) + 0.2 * Math.sin(30 * y);
}
function bitmap(edge: number): string {
const tab = tableau(edge, func);
let str = `P1 ${tab.length} ${tab.length}\n`;
for (let i = 0; i < tab.length; i++) {
for (let j = 0; j < tab.length; j++) {
str += (tab[i][j] ? 1 : 0) + ' ';
}
str += '\n';
}
return str;
}
import * as fs from 'fs';
fs.writeFileSync('/tmp/a.pbm', bitmap(800), 'utf8');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment