Skip to content

Commit

Permalink
[js] Add assembly groups feature
Browse files Browse the repository at this point in the history
Specify groups of species that will be assembled together
  • Loading branch information
Akodiat committed Aug 31, 2022
1 parent e226469 commit ae551d8
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 77 deletions.
5 changes: 2 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,10 @@ <h3>So what do I do?</h3>
<button onclick="system.regenerate()">Update</button>
<input type="checkbox" id="autoUpdate" checked="True", onchange="system.regenerate()">Auto update
</span>
<label for="assemblyMode">Assembly mode:</label>
<label for="assemblyMode">Seeding:</label>
<select id="assemblyMode" onchange="system.resetAssemblyMode(this.value)">
<option value="stochastic">Stochastic</option>
<option value="stochastic">Unseeded</option>
<option value="seeded" selected>Seeded</option>
<option value="ordered">Ordered</option>
</select>
<span style="display: flex;">
<input type="checkbox" id="torsion" checked="True", onchange="system.torsion=this.checked; system.regenerate()">Torsion
Expand Down
8 changes: 7 additions & 1 deletion js/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ function createPolycubeSystem() {
}
let assemblyMode = getUrlParam("assemblyMode", 'seeded');

let groupsStr = getUrlParam("groups", undefined);
let groups
if (groupsStr) {
groups = JSON.parse(groupsStr)
}

try {
document.getElementById('assemblyMode').value = assemblyMode;
} catch (error) {
Expand All @@ -26,7 +32,7 @@ function createPolycubeSystem() {
let torsion = document.getElementById('torsion').checked;
let allowMismatches = document.getElementById('mismatches').checked;

system = new PolycubeSystem(rule, scene, nMaxCubes, maxCoord, assemblyMode, undefined, torsion, allowMismatches);
system = new PolycubeSystem(rule, scene, nMaxCubes, maxCoord, assemblyMode, undefined, torsion, allowMismatches, groups);

orbit.target = system.centerOfMass;

Expand Down
3 changes: 1 addition & 2 deletions js/klossSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ class KlossSystem {
if (this.compatibleColors(patch.color, species[i].color)) {
// Set the same orientation
let q = patch.q.clone().multiply(species[i].q.clone().invert());
//let q = species[i].q.clone().multiply(patch.q.clone().invert());

q.premultiply(new THREE.Quaternion().setFromAxisAngle(
patch.alignDir, Math.PI)
Expand All @@ -269,7 +268,7 @@ class KlossSystem {

return {
'i': i,
'q': q//q1.multiply(q2)
'q': q
};
}
}
Expand Down
119 changes: 48 additions & 71 deletions js/polycubeSystem.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class PolycubeSystem {

constructor(rule, scene, nMaxCubes=1000, maxCoord=100, assemblyMode='seeded', buildConfmap=true, torsion = true, allowMismatches = true) {
constructor(rule, scene, nMaxCubes=1000, maxCoord=100, assemblyMode='seeded', buildConfmap=true, torsion = true, allowMismatches = true, groups=undefined) {
this.moves = {};
this.moveKeys = [];
this.untried = [];
this.cubeMap = new Map();
this.centerOfMass = new THREE.Vector3();
this.nMaxCubes = nMaxCubes;
Expand All @@ -11,7 +12,9 @@ class PolycubeSystem {
this.allowMismatches = allowMismatches;

this.assemblyMode = assemblyMode;
this.orderIndex = 0;

this.groupIndex = 0;
this.groups = groups;

this.cubeTypeCount = rule.map(r=>0);

Expand Down Expand Up @@ -88,6 +91,7 @@ class PolycubeSystem {
this.objGroup.children = [];
this.moves = {};
this.moveKeys = [];
this.untried = [];
this.cubeMap = new Map();
if (this.confMap) {
this.confMap = new Map;
Expand All @@ -103,7 +107,7 @@ class PolycubeSystem {
m.transparent = false;
m.opacity = 1;
});
this.orderIndex = 0;
this.groupIndex = 0;
if (!this.background) {
render();
}
Expand Down Expand Up @@ -135,6 +139,7 @@ class PolycubeSystem {

resetRule(rule) {
this.reset();
this.groups = undefined;
this.rule = rule;

let nColors = Math.max.apply(Math, rule.map(x => Math.max.apply(
Expand Down Expand Up @@ -259,80 +264,51 @@ class PolycubeSystem {
}

processMoves() {
let nMoves = this.moveKeys.length;
if (nMoves > 0) { // While we have moves to process
// If we should assemble everything in order
if (this.assemblyMode == 'ordered') {
// Go through moves in random order
let tried = new Set();
let untried = this.moveKeys.slice(); //Make shallow copy
while(untried.length > 0){
// Get a random untried move key
let i = Math.floor(untried.length * Math.random());
let key = untried[i];
// Try to add the current cube type
let result = this.tryProcessMove(key, this.orderIndex);
if (result) {
// Remove processed move
delete this.moves[key];
this.moveKeys.splice(this.moveKeys.indexOf(key), 1);
}
tried.add(key);
// Movekeys might have updated, if we added cubes
untried = this.moveKeys.filter(i=>!tried.has(i));

// Check if polycube is getting too large
if (this.cubeMap.size >= this.nMaxCubes) {
if (!this.background) {
render();
window.dispatchEvent(new Event('oub'));
}
console.log("Unbounded");
return 'oub';
}
}
// When we have tried the current cube type for all moves
// in queue, increase index to try the next one next time
this.orderIndex++;
if (this.orderIndex >= this.rule.length) {
if (!this.background) {
window.dispatchEvent(new Event('movesProcessed'));
}
return true;
}
} else {
// Pick a random move
let key = this.moveKeys[Math.floor(Math.random()*nMoves)];
// Pick a random rule order
let ruleIdxs = randOrdering(this.rule.length);
// Check if we have a rule that fits this move
for (let r=0; r<this.rule.length; r++) {
let result = this.tryProcessMove(key, ruleIdxs[r]);
if (result) {
break;
}
}
// Remove processed move
delete this.moves[key];
this.moveKeys.splice(this.moveKeys.indexOf(key), 1);
}

// Check if polycube is getting too large
if (this.cubeMap.size >= this.nMaxCubes) {
if (!this.background) {
render();
window.dispatchEvent(new Event('oub'));
}
console.log("Unbounded");
return 'oub';
}
let groups;
if (this.groups === undefined) {
// Add all species to a single group
groups = [this.rule.map((_,i)=>i)];
} else {
groups = this.groups;
}
if (this.untried.length == 0) {
this.groupIndex++;
this.untried = this.moveKeys.slice();
}
if (this.groupIndex >= groups.length) {
if (!this.background) {
window.dispatchEvent(new Event('movesProcessed'));
}
return true;
}
let group = groups[this.groupIndex];
console.log(`Trying group ${group}`)
// Traverse in random order
let key = this.untried[Math.floor(Math.random()*this.untried.length)];
console.log(`Trying key ${key}`)
// Traverse the species in this group in a random order
let shuffledGroup = randOrdering(group.length).map(i=>group[i]);
// Check if we have a species that fits this move
for (let i=0; i<group.length; i++) {
let result = this.tryProcessMove(key, shuffledGroup[i]);
if (result) {
// Remove processed move
delete this.moves[key];
// Remove key
this.moveKeys.splice(this.moveKeys.indexOf(key), 1);
// Check if polycube is getting too large
if (this.cubeMap.size >= this.nMaxCubes) {
if (!this.background) {
render();
window.dispatchEvent(new Event('oub'));
}
console.log("Unbounded");
return 'oub';
}
break;
}
}
//render();
this.untried.splice(this.untried.indexOf(key), 1);
if (!this.background) {
requestAnimationFrame(this.processMoves.bind(this, false));
}
Expand Down Expand Up @@ -367,6 +343,7 @@ class PolycubeSystem {
'pos': movePos,
'rule': [null,null,null,null,null,null]};
this.moveKeys.push(key);
this.untried.push(key);
}
let r = position.clone().sub(movePos);
let dirIdx = ruleOrder.findIndex(
Expand Down

0 comments on commit ae551d8

Please sign in to comment.