根据任意函数分布点云的问题与将灰度图像抖动为黑白图像是同构的。这些算法都具有与 O(N) 成正比的运行时复杂度(其中 N 是原始图像/位图/网格/无论什么)中的点数,使用简单的方法,例如拜耳矩阵有序抖动,每个点仅执行一个浮点比较,以及更复杂的误差扩散方法,其运行时间更像 O(24N),但产生的结果更好,伪影更少。
使用简单的高斯密度函数,简单的拜耳矩阵方法可以在小至 32x32 矩阵的情况下产生令人惊讶的好结果:

给定所讨论的矩阵,可以以直接的方式生成基于矩阵的有序抖动:
matrix = generate_bayer(32);
for (y=0; y<height; y++) {
for (var x=0; x<width; x++) {
i = x % matrix.length;
j = y % matrix.length;
function_val = gaussian(x, y); #returns a value 0<=x<=1
scaled_val = function_val * matrix.length * matrix.length; #scale to the max element in the matrix
if (scaled_val > matrix[j][i]) {
draw_pixel(x, y);
}
}
}
生成矩阵稍微复杂一些,但这里有一种迭代方法,用于边长为 2 的幂的矩阵:
//size should be a power of 2, and is the length of a side of the matrix
function generate_bayer(size) {
base = [[0, 2],
[3, 1]];
old_matrix = base;
mult = 4;
//successively double the size of the matrix, using the previous one as the base
while (old_matrix.length < size) {
//generate a new matrix of the proper dimensions
new_size = old_matrix.length * 2;
matrix = new Array[new_size][new_size];
for (y=0; y<old_matrix.length; y++) {
for (x=0; x<old_matrix[y].length; x++) {
//fill in the new 4x4 submatrix
matrix[y*2] [x*2] = old_matrix[y][x] + (mult * base[0][0]);
matrix[y*2] [x*2 + 1] = old_matrix[y][x] + (mult * base[0][1]);
matrix[y*2 + 1][x*2] = old_matrix[y][x] + (mult * base[1][0]);
matrix[y*2 + 1][x*2 + 1] = old_matrix[y][x] + (mult * base[1][1]);
}
}
mult *= 4;
old_matrix = matrix;
}
return old_matrix;
}