Exemplo n.º 1
0
    public bool IsValidConnection(GameObject thisSystem, GameObject targetSystem)                                       //Returns true if no intersection
    {
        Vector3 lineA = MathsFunctions.ABCLineEquation(thisSystem.transform.position, targetSystem.transform.position); //Line equation from current system to target system

        Vector3 roughCentre = (thisSystem.transform.position + targetSystem.transform.position) / 2f;

        if (roughCentre.x < 65f && roughCentre.x > 55f)        //If the intersection exists in the galactic core, ignore it
        {
            if (roughCentre.y < 65f && roughCentre.y > 55f)
            {
                return(false);
            }
        }

        for (int i = 0; i < coordinateList.Count; ++i)                                                    //For all existing connections
        {
            if (coordinateList[i].systemOne == thisSystem && coordinateList[i].systemTwo == targetSystem) //If a connection already exists between the current system and the target system, continue to the next connection
            {
                continue;
            }
            if (coordinateList[i].systemTwo == thisSystem && coordinateList[i].systemOne == targetSystem)            //Continuation of above
            {
                continue;
            }
            if (coordinateList[i].systemOne == thisSystem || coordinateList[i].systemTwo == thisSystem)            //If the connection contains this system it will not make intersections with the temporary connection
            {
                continue;
            }
            if (coordinateList[i].systemOne == targetSystem || coordinateList[i].systemTwo == targetSystem)            //If the connection contains the target system it will not make intersections with the temporary connection
            {
                continue;
            }

            //if(CheckIfIntersectionCouldOccur(thisSystem, targetSystem, coordinateList[i].systemOne, coordinateList[i].systemTwo) == false)
            //{
            //	continue;
            //

            Vector3 lineB = MathsFunctions.ABCLineEquation(coordinateList[i].systemOne.transform.position, coordinateList[i].systemTwo.transform.position); //Get the line equation between of the connection

            Vector2 intersection = MathsFunctions.IntersectionOfTwoLines(lineA, lineB);                                                                     //Find the intersection of the two lines

            if (intersection == Vector2.zero)                                                                                                               //If the lines are parallel the method returns a zero vector continue to the next connection
            {
                continue;
            }

            if (MathsFunctions.PointLiesOnLine(thisSystem.transform.position, targetSystem.transform.position, intersection))                                     //If the intersection lies on the temporary connection
            {
                if (MathsFunctions.PointLiesOnLine(coordinateList[i].systemOne.transform.position, coordinateList[i].systemTwo.transform.position, intersection)) //And it lies on the current permanent connection
                {
                    return(false);                                                                                                                                //Return true, an intersection does exist
                }
            }
        }

        return(true);
    }
    public bool CheckIsDelaunay(Triangle triOne, Triangle triTwo)
    {
        List <GameObject> sharedSides = MasterScript.triangulation.CheckIfSharesSide(triOne, triTwo);                                                                  //Find if triangles share a side (this actually returns the 2 shared and 2 unshared vertices)

        if (sharedSides.Count == 4)                                                                                                                                    //If 4 vertices are shared
        {
            GameObject sharedPointA = sharedSides[0];                                                                                                                  //Assign the shared points
            GameObject sharedPointB = sharedSides[1];
            GameObject unsharedPointA = sharedSides[2];                                                                                                                //Assign the unshared points
            GameObject unsharedPointB = sharedSides[3];
            float      angleAlpha = 0f, angleBeta = 0f;                                                                                                                //Set some angles to 0

            angleAlpha = MathsFunctions.AngleBetweenLineSegments(unsharedPointA.transform.position, sharedPointA.transform.position, sharedPointB.transform.position); //First angle is at one unshared point

            angleBeta = MathsFunctions.AngleBetweenLineSegments(unsharedPointB.transform.position, sharedPointA.transform.position, sharedPointB.transform.position);  //Second angle is at the other unshared point

            Vector3 sharedPointLine   = MathsFunctions.ABCLineEquation(sharedPointA.transform.position, sharedPointB.transform.position);                              //Get the line between the shared points
            Vector3 unsharedPointLine = MathsFunctions.ABCLineEquation(unsharedPointA.transform.position, unsharedPointB.transform.position);                          //Get the line between the unshared points
            Vector2 intersection      = MathsFunctions.IntersectionOfTwoLines(sharedPointLine, unsharedPointLine);                                                     //Find the intersection of the two lines

            if (MathsFunctions.PointLiesOnLine(sharedPointA.transform.position, sharedPointB.transform.position, intersection) == false)                               //If the intersection does not lie between the shared points then this is a non convex hull
            {
                return(true);                                                                                                                                          //So it cannot be flipped, continue to the next triangle
            }

            if (angleAlpha + angleBeta > 180f)                                        //If the polygon is convex, and the two angles combine to be greater than 180 degrees, the triangles are non delaunay, so we flip them
            {
                int triPosOne = MasterScript.triangulation.triangles.IndexOf(triOne); //Find the position of the two triangles in the triangles list
                int triPosTwo = MasterScript.triangulation.triangles.IndexOf(triTwo);

                triOne.points[0] = unsharedPointA;                 //Reassign the vertices of tri one to make the previously unshared vertices the shared vertices. One of the previously shared vertices is now the unshared vertex.
                triOne.points[1] = unsharedPointB;
                triOne.points[2] = sharedPointA;
                triOne.lines[0]  = MathsFunctions.ABCLineEquation(triOne.points[0].transform.position, triOne.points[1].transform.position);                 //Get the line equations for all the sides
                triOne.lines[1]  = MathsFunctions.ABCLineEquation(triOne.points[1].transform.position, triOne.points[2].transform.position);
                triOne.lines[2]  = MathsFunctions.ABCLineEquation(triOne.points[2].transform.position, triOne.points[0].transform.position);
                MasterScript.triangulation.triangles[triPosOne] = triOne; //Replace the original triangle with this new, flipped triangle

                triTwo.points[0] = unsharedPointA;                        //Do the same for tri two
                triTwo.points[1] = unsharedPointB;
                triTwo.points[2] = sharedPointB;
                triTwo.lines[0]  = MathsFunctions.ABCLineEquation(triTwo.points[0].transform.position, triTwo.points[1].transform.position);
                triTwo.lines[1]  = MathsFunctions.ABCLineEquation(triTwo.points[1].transform.position, triTwo.points[2].transform.position);
                triTwo.lines[2]  = MathsFunctions.ABCLineEquation(triTwo.points[2].transform.position, triTwo.points[0].transform.position);
                MasterScript.triangulation.triangles[triPosTwo] = triTwo;

                ++flips;                 //Increase the number of flips that have been made this pass.

                return(false);           //Return false (a flip has been made)
            }
        }

        return(true);        //Otherwise continue to the next triangle
    }
Exemplo n.º 3
0
    private bool IsIllegalIntersection(int externalPoint, int unvisitedPoint, Vector3 curToExtLine)
    {
        for (int j = 0; j < triangles.Count; ++j)        //For every triangle
        {
            if (triangles[j].isInternal == true)         //If the triangle is internal we don't need to worry about it, so move onto the next triangle
            {
                continue;
            }

            for (int k = 0; k < 3; ++k)            //For each line in that triangle
            {
                GameObject pointA = null;          //Get the points at each end of the line
                GameObject pointB = null;

                if (k == 0)
                {
                    pointA = triangles[j].points[0];
                    pointB = triangles[j].points[1];
                }
                if (k == 1)
                {
                    pointA = triangles[j].points[1];
                    pointB = triangles[j].points[2];
                }
                if (k == 2)
                {
                    pointA = triangles[j].points[2];
                    pointB = triangles[j].points[0];
                }

                if (pointA.name == externalPoints[externalPoint].name || pointB.name == externalPoints[externalPoint].name)                //If the line contains the external point we can ignore it
                {
                    continue;
                }

                Vector2 intersection = MathsFunctions.IntersectionOfTwoLines(curToExtLine, triangles[j].lines[k]);                                                     //Get the intersection of the line with the current star to external point line

                if (MathsFunctions.PointLiesOnLine(externalPoints[externalPoint].transform.position, unvisitedStars[unvisitedPoint].transform.position, intersection)) //If the point lies elsewhere on the line
                {
                    if (MathsFunctions.PointLiesOnLine(pointA.transform.position, pointB.transform.position, intersection))
                    {
                        return(true);                        //This IS an illegal intersection so return that, otherwise keep checking
                    }
                }
            }
        }

        return(false);
    }
Exemplo n.º 4
0
    private void CheckForNonDelaunayTriangles()
    {
        List <Triangle> numberofnondelaunay = new List <Triangle>();

        for (int i = 0; i < triangles.Count; ++i)
        {
            for (int j = 0; j < triangles.Count; ++j)
            {
                if (i == j)
                {
                    continue;
                }

                List <GameObject> sharedSides = CheckIfSharesSide(triangles[i], triangles[j]);

                if (sharedSides.Count == 4)
                {
                    GameObject sharedPointA = sharedSides[0];
                    GameObject sharedPointB = sharedSides[1];
                    GameObject unsharedPointA = sharedSides[2];
                    GameObject unsharedPointB = sharedSides[3];
                    float      angleAlpha = 0f, angleBeta = 0f;

                    angleAlpha = MathsFunctions.AngleBetweenLineSegments(unsharedPointA.transform.position, sharedPointA.transform.position, sharedPointB.transform.position);

                    angleBeta = MathsFunctions.AngleBetweenLineSegments(unsharedPointB.transform.position, sharedPointA.transform.position, sharedPointB.transform.position);

                    Vector3 sharedPointLine   = MathsFunctions.ABCLineEquation(sharedPointA.transform.position, sharedPointB.transform.position);
                    Vector3 unsharedPointLine = MathsFunctions.ABCLineEquation(unsharedPointA.transform.position, unsharedPointB.transform.position);
                    Vector2 intersection      = MathsFunctions.IntersectionOfTwoLines(sharedPointLine, unsharedPointLine);

                    if (MathsFunctions.PointLiesOnLine(sharedPointA.transform.position, sharedPointB.transform.position, intersection) == false)                    //Is non-convex
                    {
                        continue;
                    }

                    if (angleBeta + angleAlpha > 180)
                    {
                        numberofnondelaunay.Add(triangles[i]);
                    }
                }
            }
        }

        Debug.Log(numberofnondelaunay.Count + " | " + triangles.Count);
    }
    public void CreateVoronoiCells()     //This appears to be fine
    {
        MasterScript.triangulation.SimpleTriangulation();

        for (int j = 0; j < MasterScript.systemListConstructor.systemList.Count; ++j)                                                       //For all systems
        {
            VoronoiCellVertices newCell = new VoronoiCellVertices();                                                                        //Create new voronoi cell

            Vector3 voronoiCentre = MasterScript.systemListConstructor.systemList[j].systemObject.transform.position;                       //Centre of voronoi cell is the current system location

            for (int i = 0; i < MasterScript.triangulation.triangles.Count; ++i)                                                            //For all triangles
            {
                if (MasterScript.triangulation.triangles[i].points.Contains(MasterScript.systemListConstructor.systemList[j].systemObject)) //If the triangle has the current system as one of it's vertices
                {
                    Vector3 systemA = MasterScript.triangulation.triangles[i].points[0].transform.position;                                 //System A equals this system
                    Vector3 systemB = MasterScript.triangulation.triangles[i].points[1].transform.position;                                 //System B is another point in the triangle
                    Vector3 systemC = MasterScript.triangulation.triangles[i].points[2].transform.position;                                 //System C is the final point in the triangle

                    Vector3 lineAB = MathsFunctions.PerpendicularLineEquation(systemA, systemB);                                            //Get the line equations of the line perpendicular to the midpoint between two points
                    Vector3 lineBC = MathsFunctions.PerpendicularLineEquation(systemB, systemC);

                    Vector3 voronoiVertex = MathsFunctions.IntersectionOfTwoLines(lineAB, lineBC); //One of the voronoi vertices is the circumcentre of the triangle

                    float angle = MathsFunctions.RotationOfLine(voronoiVertex, voronoiCentre);     //Get the angle of the vertex relative to the centre of the voronoi cell

                    newCell.vertexAngles.Add(angle);                                               //Add the angle to the cells angle list (this is to sort the vertices clockwise)
                    newCell.vertices.Add(voronoiVertex);                                           //Add the vertex to the cells vertex list
                }
            }

            voronoiVertices.Add(newCell);              //Add the cell to the list of cells
        }

        for (int i = 0; i < voronoiVertices.Count; ++i)                     //For all voronoi cells
        {
            for (int j = voronoiVertices[i].vertexAngles.Count; j > 0; --j) //For all vertices in the cell
            {
                bool swapsMade = false;

                for (int k = 1; k < j; ++k)                                                          //While k is less than j (anything above current j value is sorted)
                {
                    if (voronoiVertices[i].vertexAngles[k] < voronoiVertices[i].vertexAngles[k - 1]) //Sort smallest to largest
                    {
                        float   tempAng = voronoiVertices[i].vertexAngles[k];
                        Vector3 tempPos = voronoiVertices[i].vertices[k];
                        voronoiVertices[i].vertexAngles[k]     = voronoiVertices[i].vertexAngles[k - 1];
                        voronoiVertices[i].vertices[k]         = voronoiVertices[i].vertices[k - 1];
                        voronoiVertices[i].vertexAngles[k - 1] = tempAng;
                        voronoiVertices[i].vertices[k - 1]     = tempPos;
                        swapsMade = true;
                    }
                }

                if (swapsMade == false)        //If no swaps made, list must have been sorted
                {
                    break;                     //So break
                }
            }

            for (int j = 1; j < voronoiVertices[i].vertices.Count; ++j)                   //For all the vertices
            {
                if (voronoiVertices[i].vertices[j] == voronoiVertices[i].vertices[j - 1]) //If there are duplicates
                {
                    voronoiVertices[i].vertices.RemoveAt(j);                              //Remove one
                    --j;
                }
            }
        }

        for (int i = 0; i < voronoiVertices.Count; ++i)                          //For all cells
        {
            GameObject newCell = new GameObject("Voronoi Cell");                 //Create new gameobject
            newCell.AddComponent("MeshRenderer");                                //Add meshrenderer to create a mesh
            newCell.AddComponent("MeshFilter");                                  //Add meshfilter to apply materials
            newCell.AddComponent("MeshCollider");                                //Add meshcollider (why?)

            MeshFilter newMesh = (MeshFilter)newCell.GetComponent("MeshFilter"); //Get a reference to the meshfilter

            List <Vector3> vertices = new List <Vector3>();                      //Create new list of vertices

            for (int j = 0; j < voronoiVertices[i].vertices.Count; ++j)          //For all the voronoi cell's vertices
            {
                int nextVertex = j + 1;                                          //Get the next vertex

                if (nextVertex == voronoiVertices[i].vertices.Count)
                {
                    nextVertex = 0;
                }

                int prevVertex = j - 1;                 //Get the previous vertex

                if (prevVertex == -1)
                {
                    prevVertex = voronoiVertices[i].vertices.Count - 1;
                }

                Vector3 lineA = voronoiVertices[i].vertices[prevVertex] - voronoiVertices[i].vertices[j];                                                                                         //Line from vertex to next vertex
                Vector3 lineB = voronoiVertices[i].vertices[nextVertex] - voronoiVertices[i].vertices[j];                                                                                         //Line from vertex to previous vertex

                Vector3 bisector          = (lineA.normalized + lineB.normalized) / 2f;                                                                                                           //Bisector line
                float   yIntersect        = voronoiVertices[i].vertices[j].y - (bisector.y / bisector.x) * voronoiVertices[i].vertices[j].x;                                                      //Cintersect = y - mx
                Vector3 bisectorIntersect = new Vector3(0f, yIntersect, 0f);                                                                                                                      //Get the y intersect of the bisector

                float vertAngle = MathsFunctions.AngleBetweenLineSegments(voronoiVertices[i].vertices[j], voronoiVertices[i].vertices[prevVertex], voronoiVertices[i].vertices[nextVertex]) / 2f; //Get the angle between the lines

                float hypotenuseLength = 0.5f / Mathf.Sin(vertAngle * Mathf.Deg2Rad);                                                                                                             //Find the length of the hypotenuse (how far in the new vertex should be

                Vector3 dir = bisectorIntersect - voronoiVertices[i].vertices[j];                                                                                                                 //Find the direction that the new vertex points to from the current vertex
                dir = bisector.normalized;                                                                                                                                                        //Normalise the direction
                vertices.Add(voronoiVertices[i].vertices[j]);                                                                                                                                     //Add the original vertex to the new vertex list
                vertices.Add(voronoiVertices[i].vertices[j] + (dir * hypotenuseLength));                                                                                                          //Add this indented vertex to the new vertex list
            }

            for (int j = 0; j < vertices.Count; ++j)                                                                                 //For all the vertices
            {
                float   x      = vertices[j].x - MasterScript.systemListConstructor.systemList[i].systemObject.transform.position.x; //Set the x relative to the centre (used to be prevent the vertices being offset from the gameobject centre)
                float   y      = vertices[j].y - MasterScript.systemListConstructor.systemList[i].systemObject.transform.position.y; //Do the same for the y
                Vector3 newPos = new Vector3(x, y, 0f);
                vertices[j] = newPos;
            }

            newMesh.mesh.vertices = vertices.ToArray();   //Add the vertices to the mesh vertex list

            List <int> tris = new List <int>();           //Create new tris

            for (int j = 0; j < vertices.Count; ++j)      //Create tris from the vertices
            {
                int nextVertex      = j + 1;
                int afterNextVertex = j + 2;

                if (nextVertex == vertices.Count)
                {
                    nextVertex      = 0;
                    afterNextVertex = 1;
                }

                if (afterNextVertex == vertices.Count)
                {
                    afterNextVertex = 0;
                }

                if (j % 2 != 0)
                {
                    tris.Add(afterNextVertex);
                    tris.Add(nextVertex);
                    tris.Add(j);
                }

                else
                {
                    tris.Add(j);
                    tris.Add(nextVertex);
                    tris.Add(afterNextVertex);
                }
            }

            List <Vector2> uvs = new List <Vector2>();

            for (int j = 0; j < newMesh.mesh.vertices.Length; ++j)
            {
                Vector2 uvCoordinate = new Vector2(newMesh.mesh.vertices[j].x, newMesh.mesh.vertices[j].z);
                uvs.Add(uvCoordinate);
            }

            newMesh.mesh.triangles = tris.ToArray();
            newMesh.mesh.uv        = uvs.ToArray();

            newMesh.mesh.RecalculateNormals();
            newMesh.mesh.RecalculateBounds();
            newMesh.mesh.Optimize();

            newCell.renderer.material        = MasterScript.turnInfoScript.emptyMaterial;
            newCell.renderer.material.shader = Shader.Find("Transparent/Diffuse");
            Color newColour = newCell.renderer.material.color;
            newColour = new Color(newColour.r, newColour.g, newColour.b, 0f);
            newCell.renderer.material.color = newColour;
            newCell.AddComponent <SystemRotate>();
            newCell.name = "Voronoi Cell" + i.ToString();
            newCell.tag  = "VoronoiCell";
            newCell.transform.position = new Vector3(MasterScript.systemListConstructor.systemList[i].systemObject.transform.position.x, MasterScript.systemListConstructor.systemList[i].systemObject.transform.position.y, 0f);
            newCell.transform.parent   = voronoiCellContainer.transform;

            //voronoiCells.Add (newCell);
        }
    }