Пример #1
0
    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);
    }
Пример #2
0
    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));
    }
Пример #3
0
    /// <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
    }