Created
July 18, 2022 15:24
-
-
Save marmakoide/fc8316a4a1642e5d6db0372122b4cfdc to your computer and use it in GitHub Desktop.
Generates a very accurate antialiased disk, without super sampling a very large bitmap. Works correctly only for even values of N.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy | |
import scipy.integrate as integrate | |
def get_disk_mask(N): | |
def F(x): | |
return (1 - x ** 2) ** .5 | |
# Build a quarter | |
M = N // 2 | |
quarter = numpy.zeros((M, M)) | |
for i in range(M): | |
max_slice_len = F((i + 0) / M) | |
min_slice_len = F((i + 1) / M) | |
j_max = int(numpy.floor(M * max_slice_len)) | |
j_min = int(numpy.floor(M * min_slice_len)) | |
if i <= j_max: | |
column_area, err = integrate.quad(F, i / M, (i + 1) / M) | |
delta = column_area - j_min / M ** 2 | |
fraction = delta * M ** 2 | |
if j_max == j_min: | |
quarter[i,:j_min], quarter[i,j_min] = 1, fraction | |
quarter[:j_min, i], quarter[j_min,i] = 1, fraction | |
else: | |
if fraction < 1: | |
quarter[i,:j_min], quarter[i,j_min] = 1, fraction | |
quarter[:j_min,i], quarter[j_min,i] = 1, fraction | |
else: | |
quarter[i,:j_max], quarter[i,j_max] = 1, fraction - 1 | |
quarter[:j_max,i], quarter[j_max,i] = 1, fraction - 1 | |
# Assemble the quarters | |
ret = numpy.zeros((N, N)) | |
ret[M:,M:] = quarter | |
ret[:M,M:] = numpy.flip(quarter, axis = 0) | |
ret[M:,:M] = numpy.flip(quarter, axis = 1) | |
ret[:M,:M] = numpy.flip(quarter, axis = (0, 1)) | |
# Job done | |
return ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment