diff --git a/examples/lattice_demo.py b/examples/lattice_demo.py
new file mode 100644
index 0000000..4a15906
--- /dev/null
+++ b/examples/lattice_demo.py
@@ -0,0 +1,37 @@
+from abp.viz import VisibleGraphState
+import numpy as np
+import time
+import itertools
+
+square_unit_cell = (((0, 0), (0, 1)), ((0, 0), (1, 0)), ((1, 0), (1, 1)), ((0, 1), (1, 1)))
+funny_unit_cell = (((0, 0), (0, 1)), ((0, 0), (1, 0)), ((1, 0), (1, 1)), ((0, 1), (1, 1)), ((0, 0), (.5, .5)))
+
+def add_offset(vector, offset):
+ """ Offset a vector in n-dimensional space """
+ return tuple(v+o for v, o in zip(vector, offset))
+
+def offset_unit_cell(unit_cell, offset):
+ """ Offset a unit cell """
+ return {(add_offset(a, offset), add_offset(b, offset)) for a, b in unit_cell}
+
+def lattice(unit_cell, size):
+ """ Generate a lattice from a unit cell """
+ edges = set()
+ for offset in itertools.product(*map(range, size)):
+ edges |= offset_unit_cell(unit_cell, offset)
+
+ nodes = set(itertools.chain(*edges))
+ return nodes, edges
+
+#s = VisibleGraphState()
+nodes, edges = lattice(funny_unit_cell, (10, 10))
+
+psi = VisibleGraphState()
+for node in nodes:
+ pos = {"x": node[0], "y": node[1], "z": 0}
+ psi.add_node(str(node), meta={"position":pos})
+
+for edge in edges:
+ psi.add_edge(str(edge[0]), str(edge[1]))
+
+
diff --git a/examples/visualization_demo.py b/examples/visualization_demo.py
index 8d4d445..c5e7b4d 100644
--- a/examples/visualization_demo.py
+++ b/examples/visualization_demo.py
@@ -6,7 +6,7 @@ s = VisibleGraphState()
for i in range(200):
x = 10*np.cos(np.pi*2*i/60)
y = 10*np.sin(np.pi*2*i/60)
- s.add_node(i, {"position": (round(x, 2), round(y, 2), round(i/50., 2))})
+ s.add_node(i, {"position": {"x":round(x, 2), "y":round(y, 2), "z":round(i/50., 2)}})
s.act_local_rotation(i, "hadamard")
for i in range(200-1):
s.act_cz(i, i+1)
diff --git a/static/scripts/anders_briegel.js b/static/scripts/anders_briegel.js
index 893ca31..73a316f 100644
--- a/static/scripts/anders_briegel.js
+++ b/static/scripts/anders_briegel.js
@@ -1,15 +1,9 @@
var abj = {};
-abj.ngbh = {};
-abj.vops = {};
-abj.meta = {};
-ngbh = abj.ngbh;
-vops = abj.vops;
-meta = abj.meta;
abj.add_node = function(node, m) {
- ngbh[node] = {};
- vops[node] = tables.clifford.hadamard;
- meta[node] = m ? m : {};
+ abj.ngbh[node] = {};
+ abj.vops[node] = tables.clifford.hadamard;
+ abj.meta[node] = m ? m : {};
};
abj.add_nodes = function(nodes) {
@@ -17,8 +11,8 @@ abj.add_nodes = function(nodes) {
};
abj.add_edge = function(a, b) {
- ngbh[a][b] = true;
- ngbh[b][a] = true;
+ abj.ngbh[a][b] = true;
+ abj.ngbh[b][a] = true;
};
abj.add_edges = function(edges) {
@@ -28,12 +22,12 @@ abj.add_edges = function(edges) {
};
abj.del_edge = function(a, b) {
- delete ngbh[a][b];
- delete ngbh[b][a];
+ delete abj.ngbh[a][b];
+ delete abj.ngbh[b][a];
};
abj.has_edge = function(a, b) {
- return Object.prototype.hasOwnProperty.call(ngbh[a], b);
+ return Object.prototype.hasOwnProperty.call(abj.ngbh[a], b);
};
abj.toggle_edge = function(a, b) {
@@ -45,7 +39,7 @@ abj.toggle_edge = function(a, b) {
};
abj.get_swap = function(node, avoid) {
- for (var i in ngbh[node]) {
+ for (var i in abj.ngbh[node]) {
if (i != avoid) {
return i;
}
@@ -55,7 +49,7 @@ abj.get_swap = function(node, avoid) {
abj.remove_vop = function(node, avoid) {
var swap_qubit = get_swap(node, avoid);
- var decomposition = decompositions[vops[node]];
+ var decomposition = decompositions[abj.vops[node]];
for (var i = decomposition.length - 1; i >= 0; --i) {
var v = decomposition[i];
local_complementation(v == "x" ? a : swap_qubit);
@@ -63,19 +57,19 @@ abj.remove_vop = function(node, avoid) {
};
abj.local_complementation = function(node) {
- var keys = Object.keys(ngbh[node]);
+ var keys = Object.keys(abj.ngbh[node]);
for (var i = 0; i < keys.length; ++i) {
for (var j = i + 1; j < keys.length; ++j) {
toggle_edge(keys[i], keys[j]);
}
- vops[i] = tables.times_table[vops[keys[i]]][sqz_h];
+ abj.vops[i] = tables.times_table[abj.vops[keys[i]]][sqz_h];
}
- vops[node] = tables.times_table[vops[node]][msqx_h];
+ abj.vops[node] = tables.times_table[abj.vops[node]][msqx_h];
};
abj.act_local_rotation = function(node, operation) {
var rotation = tables.clifford[operation];
- vops[node] = tables.times_table[rotation][vops[node]];
+ abj.vops[node] = tables.times_table[rotation][abj.vops[node]];
};
abj.act_hadamard = function(node) {
@@ -87,19 +81,19 @@ abj.is_sole_member = function(node, group) {
};
abj.act_cz = function(a, b) {
- if (is_sole_member(ngbh[a], b)) {
+ if (is_sole_member(abj.ngbh[a], b)) {
remove_vop(a, b);
}
- if (is_sole_member(ngbh[b], a)) {
+ if (is_sole_member(abj.ngbh[b], a)) {
remove_vop(b, a);
}
- if (is_sole_member(ngbh[a], b)) {
+ if (is_sole_member(abj.ngbh[a], b)) {
remove_vop(a, b);
}
var edge = has_edge(a, b);
- var new_state = tables.cz_table[edge ? 1 : 0][vops[a]][vops[b]];
- vops[a] = new_state[1];
- vops[b] = new_state[2];
+ var new_state = tables.cz_table[edge ? 1 : 0][abj.vops[a]][abj.vops[b]];
+ abj.vops[a] = new_state[1];
+ abj.vops[b] = new_state[2];
if (new_state[0] != edge) {
toggle_edge(a, b);
}
@@ -108,8 +102,8 @@ abj.act_cz = function(a, b) {
abj.edgelist = function() {
var seen = {};
var output = [];
- for (var i in ngbh) {
- for (var j in ngbh[i]) {
+ for (var i in abj.ngbh) {
+ for (var j in abj.ngbh[i]) {
if (!Object.prototype.hasOwnProperty.call(seen, j)) {
output.push([i, j]);
}
@@ -120,7 +114,7 @@ abj.edgelist = function() {
};
abj.log_graph_state = function() {
- console.log(JSON.stringify(vops));
- console.log(JSON.stringify(ngbh));
+ console.log(JSON.stringify(abj.vops));
+ console.log(JSON.stringify(abj.ngbh));
};
diff --git a/static/scripts/graph.js b/static/scripts/graph.js
index 822639c..5fc2866 100644
--- a/static/scripts/graph.js
+++ b/static/scripts/graph.js
@@ -7,24 +7,25 @@ graph.hook = function() {
};
graph.update = function(json) {
- anders_briegel.vops = json.vops;
- anders_briegel.ngbh = json.ngbh;
- anders_briegel.meta = json.meta;
+ abj.vops = json.vops;
+ abj.ngbh = json.ngbh;
+ abj.meta = json.meta;
graph.updateScene();
};
graph.updateScene = function() {
- var oldState = scene.getObjectByName("graphstate");
- scene.remove(oldState);
- oldState = null;
+ if (graph.object){gui.scene.remove(graph.object);}
+ graph.object = null;
+ console.log("update");
var geometry = new THREE.Geometry();
+ geometry.colors = [];
for (var i in abj.vops) {
var vop = abj.vops[i];
var pos = abj.meta[i].position;
var vertex = new THREE.Vector3(pos.x, pos.y, pos.z);
geometry.vertices.push(vertex);
- geometry.colors[i] = new THREE.Color(colors[abj.vops[i] % colors.length]);
+ geometry.colors.push(new THREE.Color(graph.colors[abj.vops[i] % graph.colors.length]));
}
var edges = new THREE.Object3D();
@@ -32,18 +33,18 @@ graph.updateScene = function() {
for (i = 0; i < my_edges.length; ++i) {
var edge = my_edges[i];
var start = abj.meta[edge[0]].position;
- var startpos = new THREE.Vector3(start[0], start[1], start[2]);
+ var startpos = new THREE.Vector3(start.x, start.y, start.z);
var end = abj.meta[edge[1]].position;
- var endpos = new THREE.Vector3(end[0], end[1], end[2]);
- var newEdge = makeCurve(startpos, endpos);
+ var endpos = new THREE.Vector3(end.x, end.y, end.z);
+ var newEdge = materials.makeCurve(startpos, endpos);
edges.add(newEdge);
}
var particles = new THREE.Points(geometry, materials.qubit);
- var newState = new THREE.Object3D();
- newState.name = "graphstate";
- newState.add(particles);
- newState.add(edges);
- scene.add(newState);
- render();
+ graph.object = new THREE.Object3D();
+ graph.object.name = "graphstate";
+ graph.object.add(particles);
+ graph.object.add(edges);
+ gui.scene.add(graph.object);
+ gui.render();
};
diff --git a/static/scripts/gui.js b/static/scripts/gui.js
index 1f93a42..70cbb48 100644
--- a/static/scripts/gui.js
+++ b/static/scripts/gui.js
@@ -1,6 +1,8 @@
var gui = {};
gui.construct = function() {
- gui.renderer = new THREE.WebGLRenderer();
+ gui.renderer = new THREE.WebGLRenderer({
+ "antialias": true
+ });
gui.renderer.setSize(window.innerWidth, window.innerHeight);
gui.renderer.setClearColor(0xffffff, 1);
document.querySelector("body").appendChild(gui.renderer.domElement);
@@ -10,10 +12,10 @@ gui.construct = function() {
gui.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.3, 1000);
gui.controls = new THREE.OrbitControls(gui.camera);
+ gui.controls.addEventListener("change", gui.render);
gui.controls.center.set(0, 0, 0);
gui.controls.rotateSpeed = 0.2;
gui.camera.position.set(0, 0, 20);
- gui.controls.addEventListener("change", gui.render);
};
// Someone resized the window
@@ -27,8 +29,9 @@ gui.onWindowResize = function(evt) {
// Render the current frame to the screen
gui.render = function() {
- console.log("render");
- gui.renderer.render(gui.scene, gui.camera);
+ requestAnimationFrame(function() {
+ gui.renderer.render(gui.scene, gui.camera);
+ });
};
// Make the extra bits of gui
@@ -41,8 +44,25 @@ gui.makeScene = function() {
};
// Put an HTML message to the screen
-gui.serverMessage = function(msgtext){
+gui.serverMessage = function(msgtext) {
message.innerHTML = msgtext;
message.className = "visible";
};
+gui.loop = function() {
+ gui.controls.update();
+ requestAnimationFrame(gui.loop);
+}
+
+// Try to add a qubit at the current mouse position
+gui.addQubitAtMouse = function(event) {
+ this.raycaster.setFromCamera(mouse, camera);
+ var intersection = this.raycaster.ray.intersectPlane(this.plane);
+ intersection.x = Math.round(intersection.x);
+ intersection.y = Math.round(intersection.y);
+ abj.add_node(Object.keys(vops).length, {
+ "position": intersection
+ });
+ graph.updateScene();
+}
+
diff --git a/static/scripts/main.js b/static/scripts/main.js
index 2be64e4..602f3e5 100644
--- a/static/scripts/main.js
+++ b/static/scripts/main.js
@@ -1,5 +1,6 @@
window.onload = function() {
graph.hook();
+ materials.load();
gui.construct();
- gui.render();
+ gui.loop();
};
diff --git a/static/scripts/materials.js b/static/scripts/materials.js
index 87bce3e..047dc79 100644
--- a/static/scripts/materials.js
+++ b/static/scripts/materials.js
@@ -1,38 +1,32 @@
var materials = {};
-materials.textures = {
- sprite: new THREE.Texture()
-};
-materials.load = function() {
- materials.textures.sprite = new THREE.Texture(document.getElementById("ball"));
- materials.textures.sprite.needsUpdate = true;
+var curveProperties = {
+ splineDensity: 8,
+ curvature: 20
};
-materials.curveProperties = {
- splineDensity: 10,
- curvature: 100
-};
-
-materials.materials = {
- edge: new THREE.LineBasicMaterial({
+materials.load = function() {
+ var sprite = new THREE.Texture(document.getElementById("ball"));
+ sprite.needsUpdate = true;
+ materials.edge = new THREE.LineBasicMaterial({
color: "gray",
transparent: false,
linewidth: 1
- }),
- point: new THREE.PointsMaterial({
+ });
+ materials.point = new THREE.PointsMaterial({
size: 0.1,
- map: materials.textures.sprite,
+ map: sprite,
alphaTest: 0.5,
transparent: true,
vertexColors: THREE.VertexColors
- }),
- qubit: qubit = new THREE.PointsMaterial({
- size: 0.8,
- map: materials.textures.sprite,
+ });
+ materials.qubit = new THREE.PointsMaterial({
+ size: 0.3,
+ map: sprite,
alphaTest: 0.5,
transparent: true,
vertexColors: THREE.VertexColors
- })
+ });
};
materials.makeCurve = function(a, b) {
@@ -43,6 +37,6 @@ materials.makeCurve = function(a, b) {
var geometry = new THREE.Geometry();
var splinePoints = spline.getPoints(curveProperties.splineDensity);
Array.prototype.push.apply(geometry.vertices, splinePoints);
- return new THREE.Line(geometry, materials.materials.edge);
+ return new THREE.Line(geometry, materials.edge);
};
diff --git a/static/scripts/orbitcontrols.js b/static/scripts/orbitcontrols.js
index f394b42..b46c6ba 100644
--- a/static/scripts/orbitcontrols.js
+++ b/static/scripts/orbitcontrols.js
@@ -224,6 +224,7 @@ THREE.OrbitControls = function ( object, domElement ) {
if ( scope.enabled === false ) return;
if ( scope.userRotate === false ) return;
+
event.preventDefault();
if ( state === STATE.NONE )
diff --git a/static/scripts/websocket.js b/static/scripts/websocket.js
index 2f93505..c44b054 100644
--- a/static/scripts/websocket.js
+++ b/static/scripts/websocket.js
@@ -19,7 +19,7 @@ websocket.connect = function(update){
ws.onclose = function(evt)
{
- gui.serverMessage("Connection to server lost. Reconnect.");
+ gui.serverMessage("Connection to server lost. Reconnect.");
};
};