1
0
mirror of https://github.com/JustinSDK/dotSCAD.git synced 2025-08-21 05:52:16 +02:00

reuse calculated weights

This commit is contained in:
Justin Lin
2022-03-21 15:26:28 +08:00
parent 7e66869bca
commit 71815a2cdc

View File

@@ -1,6 +1,7 @@
use <util/rand.scad>; use <util/rand.scad>;
use <util/some.scad>; use <util/some.scad>;
use <util/sum.scad>; use <util/sum.scad>;
use <util/sort.scad>;
use <util/map/hashmap.scad>; use <util/map/hashmap.scad>;
use <util/map/hashmap_put.scad>; use <util/map/hashmap_put.scad>;
use <util/map/hashmap_get.scad>; use <util/map/hashmap_get.scad>;
@@ -53,11 +54,12 @@ function wf_weights(wf) = wf[2];
function wf_eigenstates(wf) = wf[3]; function wf_eigenstates(wf) = wf[3];
function wf_eigenstates_at(wf, x, y) = wf_eigenstates(wf)[y][x]; function wf_eigenstates_at(wf, x, y) = wf_eigenstates(wf)[y][x];
function wf_collapse(wf, x, y) = function wf_collapse(wf, x, y, wets) =
let( let(
states = wf_eigenstates_at(wf, x, y), states = wf_eigenstates_at(wf, x, y),
all_weights = wf_weights(wf), weights = is_undef(wets) ?
weights = [for(state = states) hashmap_get(all_weights, state)], let(all_weights = wf_weights(wf)) [for(state = states) hashmap_get(all_weights, state)] :
wets,
threshold = rand() * sum(weights) threshold = rand() * sum(weights)
) )
_wf_collapse(wf, x, y, states, weights, len(states), threshold); _wf_collapse(wf, x, y, states, weights, len(states), threshold);
@@ -70,14 +72,14 @@ function _wf_collapse(wf, x, y, states, weights, leng, threshold, i = 0) =
); );
// Shannon entropy // Shannon entropy
function wf_entropy(wf, x, y) = function wf_entropy_weights(wf, x, y) =
let( let(
all_weights = wf_weights(wf), all_weights = wf_weights(wf),
weights = [for(state = wf_eigenstates_at(wf, x, y)) hashmap_get(all_weights, state)], weights = [for(state = wf_eigenstates_at(wf, x, y)) hashmap_get(all_weights, state)],
sumOfWeights = sum(weights), sumOfWeights = sum(weights),
sumOfWeightLogWeights = sum([for(w = weights) w * ln(w)]) sumOfWeightLogWeights = sum([for(w = weights) w * ln(w)])
) )
ln(sumOfWeights) - (sumOfWeightLogWeights / sumOfWeights); [ln(sumOfWeights) - (sumOfWeightLogWeights / sumOfWeights) - rand() / 1000, weights];
function _replaceStatesAt(wf, x, y, states) = function _replaceStatesAt(wf, x, y, states) =
let( let(
@@ -106,22 +108,16 @@ function wf_not_collapsed_coords(wf, notCollaspedCoords) =
if(len(wf_eigenstates_at(wf, coord.x, coord.y)) != 1) coord if(len(wf_eigenstates_at(wf, coord.x, coord.y)) != 1) coord
]; ];
function wf_coord_min_entropy(wf, notCollaspedCoords) = function wf_coord_min_entropy_weights(wf, notCollaspedCoords) =
let( let(
entropyCoord = notCollaspedCoords[0], ewlt = [
entropy = wf_entropy(wf, entropyCoord.x, entropyCoord.y) - (rand() / 1000), for(coord = notCollaspedCoords)
min_coord = _wf_coord_min_entropy(wf, notCollaspedCoords, len(notCollaspedCoords), entropy, entropyCoord) let(x = coord.x, y = coord.y)
[x, y, wf_entropy_weights(wf, coord.x, coord.y)]
],
sorted = sort(ewlt, by = function(a, b) a[2][0] - b[2][0])
) )
min_coord; sorted[0];
function _wf_coord_min_entropy(wf, coords, coords_leng, entropy, entropyCoord, i = 1) =
i == coords_leng ? entropyCoord :
let(
coord = coords[i],
noisedEntropy = wf_entropy(wf, coord.x, coord.y) - (rand() / 1000),
nee = noisedEntropy < entropy ? [noisedEntropy, coord] : [entropy, entropyCoord]
)
_wf_coord_min_entropy(wf, coords, coords_leng, nee[0], nee[1], i + 1);
/* /*
@@ -200,14 +196,14 @@ function _doDirs(compatibilities, wf, stack, cx, cy, current_tiles, dirs, leng,
function generate(w, h, compatibilities, wf, notCollaspedCoords) = function generate(w, h, compatibilities, wf, notCollaspedCoords) =
len(notCollaspedCoords) == 0 ? collapsed_tiles(wf) : len(notCollaspedCoords) == 0 ? collapsed_tiles(wf) :
let( let(
min_coord = wf_coord_min_entropy(wf, notCollaspedCoords), entropy_weights = wf_coord_min_entropy_weights(wf, notCollaspedCoords),
x = min_coord.x, x = entropy_weights.x,
y = min_coord.y, y = entropy_weights.y,
nwf = propagate(w, h, compatibilities, wf_collapse(wf, x, y), x, y) weights = entropy_weights[2][1],
nwf = propagate(w, h, compatibilities, wf_collapse(wf, x, y, weights), x, y)
) )
generate(w, h, compatibilities, nwf, wf_not_collapsed_coords(nwf)); generate(w, h, compatibilities, nwf, wf_not_collapsed_coords(nwf));
function neighbor_dirs(x, y, width, height) = [ function neighbor_dirs(x, y, width, height) = [
if(x > 0) [-1, 0], // left if(x > 0) [-1, 0], // left
if(x < width - 1) [ 1, 0], // right if(x < width - 1) [ 1, 0], // right