Anders and Briegel in Python
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
6.5KB

  1. // IE9
  2. if (typeof console === "undefined") {
  3. var console = {
  4. log: function(logMsg) {}
  5. };
  6. }
  7. var controls, renderer, raycaster, scene, info, nodeGeometry, selection;
  8. var mouse = {
  9. "x": 0,
  10. "y": 0
  11. };
  12. var materials = {};
  13. var curveProperties = {
  14. splineDensity: 30,
  15. curvature: 10
  16. };
  17. var camera;
  18. var qubits;
  19. // Run on startup
  20. window.onload = init;
  21. // Add a curved edge between two points
  22. function makeEdge(e) {
  23. // Make the geometry of the curve
  24. var a = new THREE.Vector3(e.start[0], e.start[1], e.start[2]);
  25. var b = new THREE.Vector3(e.end[0], e.end[1], e.end[2]);
  26. var length = new THREE.Vector3().subVectors(a, b).length();
  27. var bend = new THREE.Vector3(length / curveProperties.curvature, length / curveProperties.curvature, 0);
  28. var mid = new THREE.Vector3().add(a).add(b).multiplyScalar(0.5).add(bend);
  29. var spline = new THREE.CatmullRomCurve3([a, mid, b]);
  30. var geometry = new THREE.Geometry();
  31. var splinePoints = spline.getPoints(curveProperties.splineDensity);
  32. Array.prototype.push.apply(geometry.vertices, splinePoints);
  33. // Make the actual Object3d thing
  34. var line = new THREE.Line(geometry, materials.edge);
  35. return line;
  36. }
  37. function makeQubits() {
  38. qubitGeometry = new THREE.Geometry();
  39. qubitGeometry.labels = [];
  40. var vertex = new THREE.Vector3(0, 0, 0);
  41. qubitGeometry.vertices.push(vertex);
  42. particles = new THREE.Points(qubitGeometry, materials.qubit);
  43. return particles;
  44. }
  45. // Clear the whole scene
  46. function makeScene() {
  47. // Scene, controls, camera and so on
  48. var myScene = new THREE.Scene();
  49. // Materials
  50. var lineStyle = {
  51. color: "gray",
  52. transparent: false,
  53. linewidth: 1
  54. };
  55. materials.edge = new THREE.LineBasicMaterial(lineStyle);
  56. var pointStyle = {
  57. color: "0xcccccc",
  58. size: 0.1,
  59. map: materials.sprite,
  60. alphaTest: 0.5,
  61. transparent: true,
  62. };
  63. materials.point = new THREE.PointsMaterial(pointStyle);
  64. var qubitStyle = {
  65. size: 0.6,
  66. map: materials.sprite,
  67. alphaTest: 0.5,
  68. transparent: true,
  69. color: "red"
  70. };
  71. materials.qubit = new THREE.PointsMaterial(qubitStyle);
  72. // Build all the edges
  73. //var edgeGroup = new THREE.Object3D();
  74. qubits = makeQubits();
  75. myScene.add(qubits);
  76. // Build all the nodes
  77. nodeGeometry = new THREE.Geometry();
  78. nodeGeometry.labels = [];
  79. for (var i = 0; i < 10; ++i) {
  80. for (var j = 0; j < 10; ++j) {
  81. var vertex = new THREE.Vector3(i - 5, j - 5, 0);
  82. nodeGeometry.vertices.push(vertex);
  83. nodeGeometry.labels.push("Click to add a qubit at (" + i + ", " + j + ")");
  84. }
  85. }
  86. var particles = new THREE.Points(nodeGeometry, materials.point);
  87. var grid = makeGrid(10, 10, "lightgray");
  88. myScene.add(grid);
  89. // Add the above stuff into the scene and return
  90. //myScene.add(edgeGroup);
  91. myScene.add(particles);
  92. return myScene;
  93. }
  94. // Gets a reference to the node nearest to the mouse cursor
  95. function nearestNode() {
  96. raycaster.setFromCamera(mouse, camera);
  97. for (var i = 0; i < nodeGeometry.vertices.length; ++i) {
  98. if (raycaster.ray.distanceSqToPoint(nodeGeometry.vertices[i]) < 0.01) {
  99. return i;
  100. }
  101. }
  102. return undefined;
  103. }
  104. // Find out: what is the mouse pointing at?
  105. function checkIntersections() {
  106. var new_selection = nearestNode();
  107. if (new_selection != selection) {
  108. selection = new_selection;
  109. info.className = selection ? "visible" : "hidden";
  110. info.innerHTML = selection ? nodeGeometry.labels[new_selection] : info.innerHTML;
  111. render();
  112. }
  113. }
  114. // Make a grid
  115. function makeGrid(side, n, color) {
  116. var markers = new THREE.Object3D();
  117. var gridStyle = {
  118. color: color,
  119. transparent: true,
  120. linewidth: 1,
  121. opacity: 0.5
  122. };
  123. var material = new THREE.LineBasicMaterial(gridStyle);
  124. for (var i = -n / 2; i < n / 2; ++i) {
  125. var geometry = new THREE.Geometry();
  126. geometry.vertices.push(new THREE.Vector3(side * i / n, -side / 2, 0));
  127. geometry.vertices.push(new THREE.Vector3(side * i / n, side / 2, 0));
  128. var line = new THREE.Line(geometry, material);
  129. var line90 = line.clone();
  130. line90.rotation.z = Math.PI / 2;
  131. markers.add(line);
  132. markers.add(line90);
  133. }
  134. return markers;
  135. }
  136. // Handle mouse movement
  137. function onMouseMove(event) {
  138. mouse.wasClick = false;
  139. mouse.absx = event.clientX;
  140. mouse.absy = event.clientY;
  141. mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  142. mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  143. w = 200;
  144. h = 15;
  145. info.style.top = mouse.absy - h - 40 + "px";
  146. info.style.left = mouse.absx - w / 2 + "px";
  147. checkIntersections();
  148. }
  149. function onClick(event){
  150. if (!selection){return;}
  151. console.log(nodeGeometry.vertices[selection]);
  152. qubits.geometry.dynamic = true;
  153. qubits.geometry.vertices.push(nodeGeometry.vertices[selection].clone());
  154. qubits.geometry.verticesNeedUpdate = true;
  155. }
  156. // Render the current frame to the screen
  157. function render() {
  158. renderer.render(scene, camera);
  159. }
  160. // This is the main control loop
  161. function loopForever() {
  162. controls.update();
  163. requestAnimationFrame(loopForever);
  164. }
  165. // This just organises kickoff
  166. function startMainLoop() {
  167. scene = makeScene();
  168. renderer.domElement.addEventListener("mousemove", onMouseMove, false);
  169. renderer.domElement.addEventListener("click", onClick, false);
  170. controls.addEventListener("change", render);
  171. loopForever();
  172. }
  173. // Called on startup
  174. function init() {
  175. // Measure things, get references
  176. var width = window.innerWidth;
  177. var height = window.innerHeight;
  178. info = document.getElementById("infoholder");
  179. materials.sprite = new THREE.Texture(document.getElementById("ball"));
  180. materials.sprite.needsUpdate = true;
  181. // Renderer
  182. renderer = new THREE.WebGLRenderer({
  183. antialias: true
  184. });
  185. renderer.setSize(width, height);
  186. renderer.setClearColor(0xffffff, 1);
  187. document.querySelector("body").appendChild(renderer.domElement);
  188. // Camera, controls, raycaster
  189. camera = new THREE.PerspectiveCamera(45, width / height, 0.3, 100);
  190. controls = new THREE.OrbitControls(camera);
  191. raycaster = new THREE.Raycaster();
  192. // Center the camera
  193. controls.center.set(0, 0, 0);
  194. controls.rotateSpeed = 0.2;
  195. camera.position.set(0, 0, 20);
  196. // Start polling
  197. setInterval(poll, 1000);
  198. // Run
  199. startMainLoop();
  200. }