float calcGeometricEntropy(Vector3[] handPositions) { float distance = 0; for (int i = 1; i < 25; i++) { distance += Vector3.Distance(handPositions[i - 1], handPositions[i]); } Vector3[] convexHull = JarvisMarchAlgorithm.GetConvexHull(handPositions); float perimeterAroundConvexHull = 0; for (int i = 1; i < convexHull.Length; i++) { perimeterAroundConvexHull += Vector3.Distance(convexHull[i - 1], convexHull[i]); } float h = Mathf.Log((2 * distance) / perimeterAroundConvexHull); return(h); }
public IEnumerator Start() { Instance = this; num = Random.Range(1, num); while (cubes.Count < num) { var bc = BonedCube.Make(); bc.transform.SetParent(this.transform); // The cubes are children of this transform so they can be placed on a ground plane in AR bc.a.transform.position = this.transform.position + new Vector3(LeModular.GetClosest(Random.Range(minXZ, maxXZ)), LeModular.GetClosest(Random.Range((maxHeight * -1), maxHeight)), LeModular.GetClosest(Random.Range(minXZ, maxXZ))); bc.Set(Random.Range(minXZ, maxXZ), Random.Range(minXZ, maxXZ), Random.Range(minXZ, maxXZ)); cubes.Add(bc); } int count = 0; foreach (var bc in cubes) { if (bc == null) { continue; } // Add ModulorAgent script that will handle it's building behaviour var modulorAgent = bc.gameObject.AddComponent <ModulorAgent>(); modulorAgent.bc = bc; modulorAgent.id = alphabet[count]; agentDict.Add(modulorAgent, new List <Vector3>()); // transform the world position of this transform to the local space of bc if (bc.a.position.y < this.transform.position.y) { // if i'm 10 meters tall and located at -1 then the visible section of me is going to be 4 // if 10 meters tall and locate at +1 then the visible section of me is going to be 6 float val = Random.Range(0f, 1f); Color col = val > 0.5f ? Color.white : Color.black; col.a = 0.5f; bc.GetComponentInChildren <Renderer>().material.color = col; bc.a.position = new Vector3(bc.a.transform.position.x, this.transform.position.y, bc.a.transform.position.z); bc.b.position = new Vector3(bc.b.transform.position.x, this.transform.position.y, bc.b.transform.position.z); modulorAgent.offGround = false; } else { float val = Random.Range(0f, 1f); Color col = val > 0.5f ? Color.blue : Color.red; col.a = 0.5f; bc.GetComponentInChildren <Renderer>().material.color = col; modulorAgent.offGround = true; } count++; } yield return(new WaitUntil(() => ready == cubes.Count)); yield return(new WaitForSeconds(0.5f)); Dictionary <float, Level> tmpLevels = new Dictionary <float, Level>(); List <float> heights = new List <float>(); foreach (Vector3 point in CubeGenerator.Instance.points) { if (!tmpLevels.ContainsKey(point.y)) { tmpLevels.Add(point.y, new Level(point)); tmpLevels[point.y].vertexPoints.Add(new Vertex(point)); } else { tmpLevels[point.y].points.Add(point); tmpLevels[point.y].vertexPoints.Add(new Vertex(point)); } } heights.AddRange(tmpLevels.Keys); heights.Sort(); foreach (var f in heights) { Debug.Log(string.Format("Level {0}", f)); } var tmpHeights = new List <float>(); for (int i = 0; i < heights.Count; i++) { if (i < heights.Count - 1 && heights[i] != -1.1f) { var dif = heights[i + 1] - heights[i]; if (dif > 0.6) { if (tmpLevels.ContainsKey(heights[i])) { levels.Add(heights[i], tmpLevels[heights[i]]); } } else { if (tmpLevels.ContainsKey(heights[i])) { tmpLevels[heights[i]].vertexPoints.AddRange(tmpLevels[heights[i + 1]].vertexPoints); levels.Add(heights[i], tmpLevels[heights[i]]); heights[i + 1] = 1.1f; } } } } indexLevels.AddRange(levels.Values); foreach (var entry in levels) { entry.Value.convexVertexes = JarvisMarchAlgorithm.GetConvexHull(entry.Value.vertexPoints); Debug.Log(string.Format("Merged Levels {0}", entry.Key)); } foreach (var item in indexLevels) { if (item.convexVertexes == null) { continue; } var go = new GameObject(); lrGos.Add(go); go.transform.SetParent(this.transform); LineRenderer lr = go.AddComponent <LineRenderer>(); lr.material = new Material(Shader.Find("Sprites/Default")); lr.positionCount = item.GetPointsFromVertexes().Count; lr.SetPositions(item.GetPointsFromVertexes().ToArray()); lr.loop = true; lr.startWidth = 0.1f; lr.endWidth = 0.1f; } // this.transform.localScale = Vector3.one * scale; // Debug.Log(string.Format("Ready {0}", cubes.Count)); }
/// <summary> /// Draws a tight fitting convex polygon around the swarm in the x-z plane, and then sets swarmCenterPos to the centroid of that shape. /// swarmCenterDir is set as in SetSwarmCentersByCOM() /// </summary> /// <param name="drawShape">determines whether or not to draw the bounding convex shape of the swarm</param> private void SetSwarmCentersByShape(bool drawShape) { swarmCenterDir = Vector3.zero; List <Vector3> vertices = new List <Vector3>(); //The bot positions, used by the Jarvis March Algorithm foreach (GameObject bot in swarm) { vertices.Add(bot.transform.position); swarmCenterDir += bot.transform.forward; } swarmCenterDir /= swarm.Count; swarmCenterDir.Normalize(); //Special cases that Jarvis March can't handle switch (vertices.Count) { case 0: return; case 1: swarmCenterPos = swarm[0].transform.position; return; case 2: swarmCenterPos = (swarm[0].transform.position + swarm[1].transform.position) / 2; return; } List <Vector3> hull = JarvisMarchAlgorithm.GetConvexHull(vertices); LineRenderer lr = null; if (drawShape) { lr = GetComponent <LineRenderer>() ? GetComponent <LineRenderer>() : gameObject.AddComponent <LineRenderer>(); lr.material = new Material(Shader.Find("Particles/Additive")); lr.widthMultiplier = 0.2f; lr.positionCount = hull.Count + 1; } float sX = 0, sY = 0, sZ = 0, sDist = 0; for (int i = 0; i < hull.Count; i++) { if (drawShape) { lr.SetPosition(i, hull[i]); //set the points in the line renderer that will draw the shape... } //This is basically just the formula for calculating the centroid. I don't know how it works, but it does. Vector3 prev = i == 0 ? hull.Last() : hull[i - 1]; Vector3 curr = hull[i]; float dist = Vector3.Distance(prev, curr); sX += (prev.x + curr.x) / 2 * dist; sY += (prev.y + curr.y) / 2 * dist; sZ += (prev.z + curr.z) / 2 * dist; sDist += dist; } if (drawShape) { lr.SetPosition(hull.Count, hull[0]); //...and finally draw a line from the last point to the first to close the shape } swarmCenterPos = new Vector3(sX / sDist, sY / sDist, sZ / sDist); //final step in centroid formula }