-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathspanning-tree.js
More file actions
115 lines (88 loc) · 2.97 KB
/
spanning-tree.js
File metadata and controls
115 lines (88 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* MoMath Math Square Behavior
*
* Title: Spanning Tree
* Description: Construct a minimum spanning tree between users
* Scheduler ID: 6
* Framework: THREE
* Author: ?
* Created: ?
* Updated: 2017-04 for SDK by dylan
* Status: works
*/
import THREEContext from 'threectx';
import * as THREE from 'three';
import * as Display from 'display';
var context;
var shortestPairing = new Object();
var lines = new Array();
function init(container) {
context = new THREEContext(container);
behavior.userUpdate = context.userUpdate.bind(context);
}
function createRandomPointsAndConnect(floor){
// particles
for(var l in lines) context.scene.remove(lines[l]);
lines = [];
var points = new Array();
for(var user of floor.users){
var newPosition = new THREE.Vector3(user.x, user.y);
points.push(newPosition);
}
// TODO: need some initial ghost creation to avoid this case?
if(points.length == 0)
return;
// Prim's Algorithm
// 1. get random starting position, add as connected point
var connectedPoints = new Array();
var pointPairings = new Array();
var startingPoint = points[Math.floor(Math.random() * points.length)];
startingPoint.connected = true;
connectedPoints.push(startingPoint);
var allPointsConnected = false;
while(!allPointsConnected){
var shortestLength = 100000000000.0;
var shortestWinnerRef = -1;
// 2. iterate through connected points, looking for nearest neighbor, add nearest to connected set
var connectedPointsSize = connectedPoints.length;
while(connectedPointsSize--){
var thisConnectedPoint = connectedPoints[connectedPointsSize];
var allPoints = points.length;
// 3. get shortest connection
while(allPoints--){
var currentPoint = points[allPoints];
if(currentPoint != thisConnectedPoint && !currentPoint.connected){
var dist = currentPoint.distanceTo(thisConnectedPoint);
if(dist < shortestLength/* && dist != 0*/){
shortestPairing.start = thisConnectedPoint.clone();
shortestPairing.end = currentPoint.clone();
shortestWinnerRef = allPoints;
shortestLength = dist;
}
}
}
}
if(shortestWinnerRef >= 0){
var geometry = new THREE.Geometry();
connectedPoints.push(points[shortestWinnerRef])
points[shortestWinnerRef].connected = true;
geometry.vertices.push(shortestPairing.start);
geometry.vertices.push(shortestPairing.end);
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0xffff7D, linewidth: 2 } ) );
context.scene.add(line);
lines.push(line);
}
allPointsConnected = (connectedPoints.length == points.length);
}
}
function animate(floor) {
createRandomPointsAndConnect(floor);
context.render();
}
export const behavior = {
title: "Minimum Spanning Tree",
frameRate: 'sensors',
numGhosts: 2,
init: init,
render: animate
};
export default behavior;