void KMeansClustering() { print("k-means started.."); // calculate centroid points int k_means = k_clusters; int[] k_calculations = new int[k_means]; for (int i = 0; i < k_means; i++) { decimal f = Decimal.Divide(i, k_means); float division = (float)f; k_calculations[i] = Mathf.RoundToInt(colombs_nodes.Count * (division)); print("k means calculation: " + f + " = " + i + " / " + k_means); } print("step 0, k_means = " + k_means); int k_num = 0; foreach (int num in k_calculations) { //print(k_num +" : "+num); k_num++; } // Assigning centroids GameObject[] centroids = new GameObject[k_means]; VisualNode[] vs_c = new VisualNode[k_means]; ArrayList[] clusternodes = new ArrayList[k_means]; for (int i = 0; i < k_means; i++) { centroids[i] = (GameObject)colombs_nodes[k_calculations[i]]; vs_c[i] = centroids[i].GetComponent <VisualNode>(); vs_c[i].distinct_node = true; Vector3 localScale = vs_c[i].transform.localScale; if (transform.localScale.x < 2) { //vs_c[i].transform.localScale = new Vector3(localScale.x * 2, localScale.y * 2, localScale.z * 2); } clusternodes[i] = new ArrayList(); clusternodes[i].Add(vs_c[i]); } print("step 1"); // Assigning nodes to centroids on Euclidean Distance foreach (GameObject g in colombs_nodes) { if (centroids.Contains(g) == false) { VisualNode n = g.GetComponent <VisualNode>(); float[] dist_array = new float[k_means]; for (int i = 0; i < dist_array.Length; i++) { dist_array[i] = Vector3.Distance(g.transform.localPosition, centroids[i].transform.localPosition); } float smallest_dist = dist_array.Min(); int smallest_index = 0; for (int i = 0; i < dist_array.Length; i++) { if (dist_array[i] == smallest_dist) { smallest_index = i; } } clusternodes[smallest_index].Add(n); } } print("step 2"); // Create Cluster Objects GameObject[] clusterObjects = new GameObject[k_means]; for (int i = 0; i < k_means; i++) { clusterObjects[i] = new GameObject(); clusterObjects[i].AddComponent <ClusterBehaviour>(); clusterObjects[i].GetComponent <ClusterBehaviour>().setArrayList(clusternodes[i]); clusterObjects[i].GetComponent <ClusterBehaviour>().setClusterCentre(centroids[i]); } print("step 3"); int cluster_index = 0; // Go through the three centroids and generate the clusters foreach (GameObject cluster_object in clusterObjects) { ClusterBehaviour clu = cluster_object.GetComponent <ClusterBehaviour>(); // return nodes of cluster c ArrayList cluster_array = clu.returnClusterNodes(); // setup meshfilters for child objects MeshFilter[] meshFilters = new MeshFilter[clu.returnClusterNodes().Count + 1]; // combine instance mesh array CombineInstance[] combine = new CombineInstance[meshFilters.Length]; // Color of cluster Color col = UnityEngine.Random.ColorHSV(0.1f, 0.8f, 0.7f, 1f, 0.5f, 1f); // go through each child node and add to meshFilter array // first cluster node GameObject first_node = clu.gameObject; meshFilters[0] = centroids[cluster_index].GetComponent <MeshFilter>(); combine[0].mesh = meshFilters[0].sharedMesh; combine[0].transform = meshFilters[0].transform.localToWorldMatrix; meshFilters[0].gameObject.SetActive(false); nodes_already_clustered.Add(first_node.GetComponent <VisualNode>()); // add boxcollider for each node BoxCollider b = cluster_object.AddComponent <BoxCollider>(); b.size = new Vector3(0.05f, 0.05f, 0.05f); b.center = clu.transform.position; b.isTrigger = true; /* * ArrayList edge = n.getAllocatedEdges(); * if (edge.Count > 0) { * GameObject index0 = edge[0] as GameObject; * foreach (GameObject ga in edge) { * LineRenderer l = ga.GetComponent<LineRenderer>(); * l.material.SetColor("_TintColor", new Color(col.r, col.g, col.b, 0.01f)); * } * } */ int k = 1; foreach (VisualNode v in clu.returnClusterNodes()) { if (nodes_already_clustered.Contains(v) == false) { GameObject g = v.gameObject; meshFilters[k] = g.GetComponent <MeshFilter>(); combine[k].mesh = meshFilters[k].sharedMesh; combine[k].transform = meshFilters[k].transform.localToWorldMatrix; meshFilters[k].gameObject.SetActive(false); //nodes.Add(v); nodes_already_clustered.Add(v); // add boxcollider for each node BoxCollider b1 = cluster_object.AddComponent <BoxCollider>(); b1.size = new Vector3(0.05f, 0.05f, 0.05f); b1.center = g.transform.position; b1.isTrigger = true; ArrayList edge1 = v.getAllocatedEdges(); v.transform.parent = cluster_object.transform; vs_c[cluster_index].addClusterNode(v); if (edge1.Count > 0) { GameObject index0 = edge1[0] as GameObject; foreach (GameObject ga in edge1) { //LineRenderer l = ga.GetComponent<LineRenderer>(); //l.material.SetColor("_TintColor", new Color(col.r, col.g, col.b, 0.01f)); } } } else { } k++; } // set the parent of the cluster to visualization object cluster_object.transform.parent = this.transform; // set the name of the cluster //cluster_object.transform.name = first_node.transform.name + " cluster"; // add meshfilter to new cluster cluster_object.AddComponent <MeshFilter>(); cluster_object.AddComponent <MeshRenderer>(); cluster_object.GetComponent <MeshFilter>().mesh = new Mesh(); // combine all the meshes in the mesh array "combine" cluster_object.GetComponent <MeshFilter>().mesh.CombineMeshes(combine); cluster_object.GetComponent <MeshRenderer>().material = nodeMat; // assign random color to cluster cluster_object.GetComponent <MeshRenderer>().material.color = col; clusters.Add(clu); cluster_index++; } EdgeManager edgeManager = Camera.main.GetComponent <EdgeManager> (); ArrayList glEdges = edgeManager.getEdges(); print(glEdges.Count + "glEdge count"); for (int i = 0; i < glEdges.Count; i++) { Edge e = (Edge)glEdges[i]; e.setColor(e.getTransformRef().parent.GetComponent <MeshRenderer>().material.color); } print("step 4 DONE"); clusterAllNodes = true; graph_layout_recognized = false; }
// on interacting with button void OnCollisionEnter(Collision other) { if (other.gameObject.tag == "Controller") { if (d.getVisualNode().hiding() == true) { off = 1; gameObject.GetComponent <Image>().color = Color.black; print("on"); } if (d.getVisualNode().hiding() == false) { off = 0; gameObject.GetComponent <Image>().color = Color.white; print("off"); } // unhighlight previous node if (visualnode != null && d.getVisualNode() != visualnode) { visualnode.transform.parent.GetComponent <ClusterBehaviour>().ExitHighlight(); } // set UI to white // Get cluster nodes and cluster class ClusterBehaviour c = d.getVisualNode().transform.parent.GetComponent <ClusterBehaviour>(); ArrayList clusterNodes = c.returnClusterNodes(); // if filtering cluster nodes if (off == 0) { d.getVisualNode().setHiding(true); foreach (VisualNode v in clusterNodes) { if (v != d.getVisualNode()) { graph.addIgnoreNode(v); } } foreach (VisualNode v in clusterNodes) { if (v != d.getVisualNode()) { v.OnHideEdges(); } } } // if unfiltering cluster nodes if (off == 1) { d.getVisualNode().setHiding(false); foreach (VisualNode v in clusterNodes) { if (v != d.getVisualNode()) { graph.removeIgnoreNode(v); } } foreach (VisualNode v in clusterNodes) { if (v != d.getVisualNode()) { v.UnHideEdges(); } } } off++; // reset back to 0 if greater than 1 if (off > 1) { off = 0; } c.RecreateCluster(); visualnode = d.getVisualNode(); } }