public void ComputeConvexHullTest()
        {
            var result = ConvexHull.ComputeConvexHull(m_vertices);

            Assert.AreEqual(m_hull, result);

            var result2 = ConvexHull.ComputeConvexHull(m_polygon);

            Assert.AreEqual(result, result2);
        }
예제 #2
0
        private int HullRate()
        {
            m_selected_Hull = ConvexHull.ComputeConvexHull(m_selected_points.Select(v => v.Pos));

            if (m_selected_Hull.VertexCount < 3)
            {
                return(0);
            }

            int tot = m_selected_Hull.VertexCount;

            foreach (var point in m_points)
            {
                if (m_selected_Hull.ContainsInside(point.Pos))
                {
                    tot++;
                }
            }
            m_selected_Hull.SetPointNumber(tot);

            //Draw new convex hull line segments.
            foreach (var segmesh in lineMeshes)
            {
                Destroy(segmesh);
            }
            lineMeshes.Clear();
            foreach (var seg in m_selected_Hull.Segments)
            {
                //Add a line renderer
                // instantiate new road mesh
                var roadmesh = Instantiate(m_userLineMeshPrefab, Vector3.forward, Quaternion.identity) as GameObject;
                roadmesh.transform.parent = this.transform;
                instantObjects.Add(roadmesh);
                lineMeshes.Add(roadmesh);

                //roadmesh.GetComponent<P1HullSegment>().Segment =seg;

                var roadmeshScript = roadmesh.GetComponent <ReshapingMesh>();
                roadmeshScript.CreateNewMesh(seg.Point1, seg.Point2);
            }

            //Update current area in information panel
            GameObject.Find("PointsNumber").GetComponent <Text>().text = m_selected_Hull.PointNumber.ToString();

            // 60%, 80%, 95% pass level
            for (int i = 0; i < m_rateList.Count; i++)
            {
                if (m_selected_Hull.PointNumber < (int)(m_rateList[i] * m_solutionHull.PointNumber))
                {
                    return(i);
                }
            }

            return(m_rateList.Count - 1);
        }
예제 #3
0
        private Polygon2D FindPolygon(int playerIndex, Vector2 startPoint)
        {
            var edges  = PlayerSegments[playerIndex];
            var points = PlayerPoints[playerIndex];

            if (points.Count < 3)
            {
                return(null);
            }


            //turn the egdge set into nodelink list
            int[,] edgeList = new int[points.Count, points.Count];
            int[] edgeNum = new int[points.Count];

            foreach (P2Segment edge in edges)
            {
                int i, j;
                if (PlayerPointsOnPolygons[playerIndex].Contains(edge.Segment.Point1) || PlayerPointsOnPolygons[playerIndex].Contains(edge.Segment.Point2))
                {
                    continue;
                }
                i = points.IndexOf(edge.Segment.Point1);
                j = points.IndexOf(edge.Segment.Point2);

                edgeList[i, edgeNum[i]++] = j;
                edgeList[j, edgeNum[j]++] = i;
            }

            //DFS from startPoint to find cycle;
            bool[] visited = new bool[m_totoalPointNum];
            int[]  pre     = new int[m_totoalPointNum];
            bool[,] edgeUsed = new bool[m_totoalPointNum, m_totoalPointNum];

            List <int> cycle = new List <int>();


            for (var i = 0; i < m_totoalPointNum; i++)
            {
                visited[i] = false;
                pre[i]     = -1;
                for (int j = 0; j < m_totoalPointNum; j++)
                {
                    edgeUsed[i, j] = false;
                }
            }

            int vi = points.IndexOf(startPoint);

            //There will be only one cycle created

            if (DFS(points.IndexOf(startPoint), points.IndexOf(startPoint), ref pre, ref visited, ref edgeUsed, edgeList, edgeNum, ref cycle))
            {
                //Debug.Log("Cycle!!");
                List <Vector2> CyclePoints;
                CyclePoints = new List <Vector2>();


                //Debug.Log(cycle.Count);

                foreach (var pointNum in cycle)
                {
                    CyclePoints.Add(points[pointNum]);
                }


                //Copmute the Convex HUll
                Polygon2D newHull = ConvexHull.ComputeConvexHull(CyclePoints);
                //Debug.Log("HullVNum: " + newHull.VertexCount);


                return(newHull);
            }
            else
            {
                return(null);
            }
        }
예제 #4
0
        public void Merge()
        {
            //check validness (1) 2 polygon, (2) mergechance > 1;
            if (m_selected_convexhulls.Count < 2)
            {
                return;
            }
            foreach (GameObject hullObject in m_selected_convexhulls)
            {
                if (!hullObject.GetComponent <P2Hull>().mergeChance)
                {
                    return;
                }
            }

            //Compute new convex hull,  add new convex hull to current player, update score

            operated = true;

            Polygon2D newhull = ConvexHull.ComputeConvexHull(m_selected_convexhulls[0].GetComponent <P2Hull>().hull, m_selected_convexhulls[1].GetComponent <P2Hull>().hull);

            Debug.Log(m_selected_convexhulls[0].GetComponent <P2Hull>().hull.Area + ", " + m_selected_convexhulls[1].GetComponent <P2Hull>().hull.Area + "=" + newhull.Area);

            PlayerPolygons[playerIndex].Add(newhull);
            foreach (var v in newhull.Vertices)
            {
                PlayerPointsOnPolygons[playerIndex].Add(v);
            }

            CanvasPlayerPolygons[playerIndex].Add(PolygonOnCanvas(newhull));

            foreach (var v in newhull.Vertices)
            {
                PlayerPoints[playerIndex].Add(v);
            }
            foreach (var seg in newhull.Segments)
            {
                PlayerSegments[playerIndex].Add(new P2Segment(seg.Point1, seg.Point2, player1Turn));
            }


            //disable merges
            m_selected_convexhulls[0].GetComponent <P2Hull>().mergeChance = false;
            m_selected_convexhulls[1].GetComponent <P2Hull>().mergeChance = false;

            foreach (Polygon2D polygon in PlayerPolygons[1 - playerIndex])
            {
                int i = PlayerPolygons[1 - playerIndex].IndexOf(polygon);

                if (Intersector.ifIntersect(PolygonOnCanvas(polygon), PolygonOnCanvas(newhull)))
                {
                    PlayerPolygonObjects[1 - playerIndex][i].GetComponent <P2Hull>().mergeChance = false;
                }
            }

            UpdateMesh(newhull, playerIndex, false);


            if (newhull.VertexCount > 0)
            {
                PlayerScore[playerIndex] += newhull.Area;
            }
            UpdateScore();

            UpdateTrapezoidalDecomposition();
        }
예제 #5
0
    public void Start()
    {
        gameManager = GameObject.Find("GameManager").GetComponent <GameManager>();
        if (transform.childCount == 0)
        {
            vertices = new GameObject[verticesList.Count];
            int k = 0;
            foreach (KeyValuePair <string, Vector3> entry in verticesList)
            {
                vertices[k]                  = GameObject.Instantiate(gameManager.vertexPrefab, (Vector3)entry.Value, Quaternion.identity) as GameObject;
                vertices[k].name             = (string)entry.Key;
                vertices[k].tag              = "Vertex";
                vertices[k].transform.parent = transform;
                k++;
            }
            k = 0;
        }
        else
        {
            vertices = GameObject.FindGameObjectsWithTag("Vertex").ToList().OrderBy(go => go.name).ToList().ToArray();
        }

        if (debugRawData == true)
        {
            string s = "";
            s += "vertices: \n" + vertices.Select(i => i.name + " -> " + i.transform.position.ToString() + "\n").Aggregate((i, j) => i + "" + j);
            if (adjacencyList.Length != 0)
            {
                s += "adjacency: \n" + adjacencyList.Select(i => i.ToString() + "\n").Aggregate((i, j) => i + "" + j);
            }
            Debug.Log(s);
        }

        originalPositionVertices = new Vector3[vertices.Length];
        centroid      = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        centroid.name = "centroid";
        centroid.GetComponent <Renderer>().enabled       = false;
        centroid.GetComponent <SphereCollider>().enabled = false;

        Vector2 radius            = new Vector2(15, 15);
        Vector3 centroid_position = Vector3.zero;

        Vector3[] points = new Vector3[vertices.Length];



        for (int i = 0; i < vertices.Length; i++)
        {
            int flag = isVertexinAdjacencyList(vertices[i].name);

            if (flag >= 0)
            {
                foreach (string vertex in RHS(adjacencyList)[flag].Split(","[0]))
                {
                    vertices[i].GetComponent <Vertex>().AddNeighbour(FindVertexByName(vertex));
                }
            }
        }


        for (int i = 0; i < vertices.Length; i++)
        {
            originalPositionVertices[i] = vertices[i].transform.position;

            float _i    = (i * 1.0f) / vertices.Length;
            float angle = _i * Mathf.PI * 2;

            points[i] = originalPositionVertices[i];
            vertices[i].transform.position = new Vector3(Mathf.Sin(angle) * radius.x, Mathf.Cos(angle) * radius.y, 0.0f);

            if (vertices[i].GetComponent <Vertex>() != null)
            {
                if (vertices[i].GetComponent <Vertex>().getNeighbours() != null)
                {
                    foreach (GameObject neighbour in vertices[i].GetComponent <Vertex>().getNeighbours())
                    {
                        if (neighbour != null && neighbour.GetComponent <Vertex>().getNeighbours() != null)
                        {
                            if (!neighbour.GetComponent <Vertex>().getNeighbours().Contains(vertices[i]))
                            {
                                neighbour.GetComponent <Vertex>().AddNeighbour(vertices[i]);
                                if (!vertices[i].GetComponent <Vertex>().getNeighbours().Contains(neighbour))
                                {
                                    vertices[i].GetComponent <Vertex>().AddNeighbour(neighbour);
                                }
                            }
                        }
                    }
                }
            }
            //Debug.Log(originalPositionVertices[i]);
            centroid_position += originalPositionVertices[i];
        }
        centroid_position          /= vertices.Length;
        centroid.transform.position = centroid_position;
        List <Vector3> convexHull = ConvexHull.ComputeConvexHull(points);

        area = ConvexHull.PolygonArea(convexHull);
    }
예제 #6
0
        public void InitLevel()
        {
            if (m_levelCounter >= m_levels.Count)
            {
                SceneManager.LoadScene(m_victoryScene);
                return;
            }

            // clear old level
            Clear();

            //affine transformation


            // initialize settlements
            for (var i = 0; i < m_levels[m_levelCounter].Points.Count; i++)
            {
                m_levels[m_levelCounter].Points[i] += new Vector2(epsilon * (Random.Range(0f, 1f) - 0.5f), epsilon * (Random.Range(0f, 0.1f)));

                var point = m_levels[m_levelCounter].Points[i];

                var obj = Instantiate(m_pointPrefab, point, Quaternion.identity) as GameObject;
                obj.transform.parent = this.transform;
                instantObjects.Add(obj);
            }

            foreach (var point in m_levels[m_levelCounter].Points)
            {
            }

            m_pointSelection = false;


            //Make vertex list
            m_points = FindObjectsOfType <P1HullPoint>().ToList();


            // set maximum number of selected m_points
            var convexhulltemp = ConvexHull.ComputeConvexHull(m_points.Select(v => v.Pos));

            m_pointNumberLimit = Random.Range(3, convexhulltemp.VertexCount + 1);
            if (m_pointNumberLimit < 3)
            {
                m_pointNumberLimit = 3;
            }

            // set selected number panel
            GameObject.Find("MaximumNumber").GetComponent <Text>().text  = m_pointNumberLimit.ToString();
            GameObject.Find("SelectedNumber").GetComponent <Text>().text = "0";


            // compute maximum k-gon (Area)
            if (m_pointNumberLimit >= convexhulltemp.VertexCount)
            {
                m_solutionHull = convexhulltemp;
            }
            else
            {
                m_solutionHull = MaximumKgon.ComputeMaximumAreaKgon(m_points.Select(v => v.Pos), m_pointNumberLimit);
            }


            // set hint button

            Debug.Log(m_hint);
            foreach (var seg in m_solutionHull.Segments)
            {
                //Add a line renderer
                // instantiate new road mesh

                var hintmesh = Instantiate(m_hintLineMeshPrefab, Vector3.forward, Quaternion.identity) as GameObject;
                hintmesh.transform.parent = m_hint.transform;
                instantObjects.Add(hintmesh);
                hintMeshes.Add(hintmesh);

                hintmesh.GetComponent <P1HullSegment>().Segment = seg;

                var hintmeshScript = hintmesh.GetComponent <ReshapingMesh>();
                hintmeshScript.CreateNewMesh(seg.Point1, seg.Point2);
            }
            m_hint.SetActive(false);

            //set stars information
            GameObject.Find("Area").GetComponent <Text>().text = "0";
            m_rateList = new List <float>()
            {
                0.6f, 0.8f, 0.95f, 1.0f
            };
            Debug.Log(m_rateList.Count);
            for (int i = 1; i < m_rateList.Count; i++)
            {
                var objName = "Star" + i;
                Debug.Log(objName);
                var starArea = m_rateList[i - 1] * m_solutionHull.Area;
                GameObject.Find(objName).GetComponent <Text>().text = starArea.ToString();
            }



            m_advanceButton.Disable();
        }