mirror of
https://github.com/JustinSDK/dotSCAD.git
synced 2025-08-06 06:47:46 +02:00
add wf_collapse
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
use <util/flat.scad>;
|
use <util/flat.scad>;
|
||||||
use <util/has.scad>;
|
use <util/has.scad>;
|
||||||
|
use <util/sum.scad>;
|
||||||
|
use <util/rand.scad>;
|
||||||
use <util/slice.scad>;
|
use <util/slice.scad>;
|
||||||
use <util/every.scad>;
|
use <util/every.scad>;
|
||||||
use <util/map/hashmap.scad>;
|
use <util/map/hashmap.scad>;
|
||||||
@@ -91,16 +93,71 @@ function wf_remove(wf, x, y, removedStates) =
|
|||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function wf_collapse(wf, x, y) =
|
||||||
|
let(
|
||||||
|
weights = wf_weights(wf),
|
||||||
|
states_xy = wf_eigenstates_at(wf, x, y),
|
||||||
|
weights_xy = hashmap([
|
||||||
|
for(state = hashmap_keys(weights))
|
||||||
|
if(has(states_xy, state))
|
||||||
|
[state, hashmap_get(weights, state)]
|
||||||
|
]),
|
||||||
|
totalWeights = sum(hashmap_values(weights_xy)),
|
||||||
|
threshold = rand() * totalWeights,
|
||||||
|
states_weights = hashmap_entries(weights_xy)
|
||||||
|
)
|
||||||
|
_wf_collapse(wf, x, y, states_weights, len(states_weights), threshold);
|
||||||
|
|
||||||
|
function _wf_collapse(wf, x, y, states_weights, leng, threshold, i = 0) =
|
||||||
|
i == leng ? wf :
|
||||||
|
let(
|
||||||
|
state = states_weights[i][0],
|
||||||
|
weight = states_weights[i][1],
|
||||||
|
t = threshold - weight
|
||||||
|
)
|
||||||
|
t < 0 ? _oneStateAt(wf, x, y, state) : _wf_collapse(wf, x, y, states_weights, leng, t, i + 1);
|
||||||
|
|
||||||
|
function _oneStateAt(wf, x, y, state) =
|
||||||
|
let(
|
||||||
|
eigenstates = wf_eigenstates(wf),
|
||||||
|
rowsBeforeY = slice(eigenstates, 0, y),
|
||||||
|
rowY = eigenstates[y],
|
||||||
|
rowsAfterY = slice(eigenstates, y + 1),
|
||||||
|
statesBeforeX = slice(rowY, 0, x),
|
||||||
|
states = [state],
|
||||||
|
statesAfterX = slice(rowY, x + 1),
|
||||||
|
newRowY = concat(
|
||||||
|
statesBeforeX,
|
||||||
|
[[state]],
|
||||||
|
statesAfterX
|
||||||
|
)
|
||||||
|
)
|
||||||
|
[
|
||||||
|
wf_width(wf),
|
||||||
|
wf_height(wf),
|
||||||
|
wf_weights(wf),
|
||||||
|
concat(
|
||||||
|
rowsBeforeY,
|
||||||
|
[newRowY],
|
||||||
|
rowsAfterY
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
width = len(sample[0]);
|
width = len(sample[0]);
|
||||||
height = len(sample);
|
height = len(sample);
|
||||||
weights = weightsOfTiles(sample);
|
weights = weightsOfTiles(sample);
|
||||||
|
|
||||||
wf = waveFunction(width, height, weights);
|
wf = waveFunction(width, height, weights);
|
||||||
eigenstates = initialEigenstates(width, height, weights);
|
|
||||||
|
|
||||||
assert(wf_width(wf) == width);
|
assert(wf_width(wf) == width);
|
||||||
assert(wf_height(wf) == height);
|
assert(wf_height(wf) == height);
|
||||||
assert(wf_eigenstates(wf) == eigenstates);
|
assert(wf_eigenstates(wf) == initialEigenstates(width, height, weights));
|
||||||
assert(wf_isAllCollapsed(wf) == false);
|
assert(wf_isAllCollapsed(wf) == false);
|
||||||
assert(wf_remove(wf, 0, 0, []) == wf);
|
assert(wf_remove(wf, 0, 0, []) == wf);
|
||||||
assert(wf_eigenstates_at(wf_remove(wf, 0, 0, ["CE"]), 0, 0) == ["C0", "C1", "CS", "C2", "C3", "S", "CW", "CN", "L"]);
|
assert(wf_eigenstates_at(wf_remove(wf, 0, 0, ["CE"]), 0, 0) == ["C0", "C1", "CS", "C2", "C3", "S", "CW", "CN", "L"]);
|
||||||
|
for(y = [0:height - 1]) {
|
||||||
|
for(x = [0:width - 1]) {
|
||||||
|
assert(len(wf_eigenstates_at(wf_collapse(wf, x, y), x, y)) == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user