Example #1
0
            public Polygon CreatePolygon()
            {
                Polygon result = new Polygon();

                LinkedListNode <PointChain> current = closedPolygons.First;

                while (current != null)
                {
                    SimpleClosedPath path = new SimpleClosedPath(result);

                    LinkedListNode <Vector2> innerCurrent = current.Value.First;

                    while (innerCurrent != null)
                    {
                        path.Add(innerCurrent.Value);

                        innerCurrent = innerCurrent.Next;
                    }

                    result.Add(path);

                    current = current.Next;
                }

                return(result);
            }
Example #2
0
            void UpdatePossibleBridges(SimpleClosedPath exterior, SimpleClosedPath mainHole)
            {
                possibleBridges.Clear();

                foreach (Vector2 from in mainHole.Points())
                {
                    foreach (SimpleClosedPath hole in exterior.Holes())
                    {
                        if (hole == mainHole)
                        {
                            continue;
                        }

                        foreach (Vector2 to in hole.Points())
                        {
                            possibleBridges.Add(new ExtendedEdge(from, to));
                        }
                    }

                    foreach (Vector2 to in exterior.Points())
                    {
                        possibleBridges.Add(new ExtendedEdge(from, to));
                    }
                }

                // possibleBridges.Sort(bridgeComparer);
            }
Example #3
0
    void Start()
    {
        Triangulator tri = new Triangulator();

        // Vector2 p0 = new Vector2( 0.0f, 0.0f);
        // Vector2 p1 = new Vector2( 0.0f, 1.0f);
        // Vector2 p2 = new Vector2(-0.5f, 0.0f);

        // Debug.Log("Orientation of [" + p0 + p1 + "] [" + p2 + "] : " + Orientation(p0, p1, p2));

        // p0 = new Vector2( 0.0f,  0.0f);
        // p1 = new Vector2( 0.0f,  1.0f);
        // p2 = new Vector2(+4.5f, -1.0f);

        // Debug.Log("Orientation of [" + p0 + p1 + "] [" + p2 + "] : " + Orientation(p0, p1, p2));

        MartinezClipping clippingAlgo = new MartinezClipping();

        Polygon subject = new Polygon();
        Polygon clipper = new Polygon();

        SimpleClosedPath subjectContour = new SimpleClosedPath(subject);
        SimpleClosedPath clipperContour = new SimpleClosedPath(clipper);

        foreach (Vector2 vertex in subjectVerts)
        {
            subjectContour.Add(vertex);
        }
        foreach (Vector2 vertex in clipperVerts)
        {
            clipperContour.Add(vertex);
        }

        subject.Add(subjectContour);
        clipper.Add(clipperContour);

        subject.ComputeHoles();
        clipper.ComputeHoles();

        clippingAlgo.subject = subject;
        clippingAlgo.clipper = clipper;

        Polygon result = clippingAlgo.Compute(operationType);

        result.ComputeHoles();

        //result = tri.Simplify(result);

        polyRenderer.AddPolygon(subject, Color.red);
        polyRenderer.AddPolygon(clipper, Color.blue);
        polyRenderer.AddPolygon(result, Color.green);
        polyRenderer.AddEdges(clippingAlgo.DebugLines);
    }
Example #4
0
            bool IsBridgeValid(SimpleClosedPath exterior, ExtendedEdge bridge)
            {
                foreach (Edge e in exterior.AllEdges())
                {
                    List <Vector2> intersections = bridge.GetIntersectionsWith(e);

                    if (intersections.Count > 0 && !e.HasEqualEndpoint(bridge))
                    {
                        return(false);
                    }
                }

                return(true);
            }
Example #5
0
            bool IsJoiningHole(SimpleClosedPath path, Edge joiningEdge)
            {
                foreach (Edge e in path.AllEdges())
                {
                    List <Vector2> intersections = joiningEdge.GetIntersectionsWith(e);

                    if (intersections.Count > 0 && !e.HasEqualEndpoint(joiningEdge))
                    {
                        return(false);
                    }
                }

                return(true);
            }
Example #6
0
            public IEnumerable <Edge> AllEdges()
            {
                foreach (Edge e in OwnEdgesOnly())
                {
                    yield return(e);
                }

                for (int i = 0; i < holes.Count; ++i)
                {
                    SimpleClosedPath hole = GetHole(i);

                    foreach (Edge e in hole.OwnEdgesOnly())
                    {
                        yield return(e);
                    }
                }
            }
Example #7
0
            public SimpleClosedPath(SimpleClosedPath c, Polygon owner)
            {
                this.owner = owner;

                foreach (Vector2 p in c.points)
                {
                    points.Add(new Vector2(p.x, p.y));
                }
                foreach (int holeIndex in c.holes)
                {
                    holes.Add(holeIndex);
                }

                isHole             = c.isHole;
                alreadyCalled      = c.alreadyCalled;
                isCounterClockwise = c.isCounterClockwise;
            }
Example #8
0
            /// <summary>
            /// Converts a polygon with holes to a polygon without holes
            /// </summary>

            public Polygon Simplify(Polygon inputPolygon)
            {
                Polygon result = new Polygon();

                foreach (SimpleClosedPath exterior in inputPolygon.Exteriors())
                {
                    Vector2 firstPointOnExterior = exterior.GetPoint(0);

                    SimpleClosedPath newExterior = new SimpleClosedPath(exterior, result);

                    foreach (SimpleClosedPath hole in exterior.Holes())
                    {
                        float   minDistance        = hole.Points().Min(p => Vector2.Distance(firstPointOnExterior, p));
                        Vector2 closestPointOnHole = hole.Points().Where(p => Vector2.Distance(firstPointOnExterior, p) == minDistance).FirstOrDefault();

                        Edge edge = new Edge(firstPointOnExterior, closestPointOnHole);

                        if (IsJoiningHole(exterior, edge))
                        {
                            newExterior = Join(exterior, hole, edge);
                        }
                        else // find correct pair : O(n³) where n equals max(points of exterior, points of interior)
                        {
                            foreach (Vector2 outside in exterior.Points())
                            {
                                foreach (Vector2 inside in hole.Points())
                                {
                                    edge = new Edge(outside, inside);

                                    if (IsJoiningHole(exterior, edge)) // O(n)
                                    {
                                        newExterior = Join(newExterior, hole, edge);
                                    }
                                }
                            }
                        }
                    } // foreach hole

                    result.Add(newExterior);
                } // foreach exterior

                return(result);
                //throw new InvalidOperationException("Can't find edges to join exteriors and interiors!");
            }
Example #9
0
            SimpleClosedPath Join(SimpleClosedPath exterior, SimpleClosedPath hole, Edge edge)
            {
                connector.Clear();

                connector.Add(new Edge(edge.To, edge.From));

                foreach (Edge e in exterior.OwnEdgesOnly())
                {
                    connector.Add(e);
                }

                foreach (Edge e in hole.OwnEdgesOnly())
                {
                    connector.Add(e);
                }

                connector.Add(edge);

                return(connector.CreatePolygon().GetPath(0));
            }
Example #10
0
            SimpleClosedPath Simplify(SimpleClosedPath exterior, Polygon newPolygon)
            {
                SimpleClosedPath result = new SimpleClosedPath(newPolygon);

                foreach (SimpleClosedPath hole in exterior.Holes())
                {
                    UpdatePossibleBridges(exterior, hole);

                    while (!possibleBridges.IsEmpty())
                    {
                        ExtendedEdge bridge = possibleBridges.ExtractFirst();

                        if (IsBridgeValid(exterior, bridge))
                        {
                            //result.JoinByBridge(bridge);
                        }
                    }
                }

                return(result);
            }
    void DrawPolygons()
    {
        float show = System.Convert.ToSingle(showGradients);

        float z = 3.0f;

        for (int polygonIndex = 0; polygonIndex < polygons.Count; ++polygonIndex)
        {
            if (!showOperands && polygonIndex <= 1)
            {
                continue;
            }
            if (!showResult && polygonIndex == 2)
            {
                continue;
            }

            Polygon polygon      = polygons[polygonIndex];
            Color   polygonColor = colors[polygonIndex];

            int   depth    = 0;
            float maxDepth = 3.0f;

            for (int pathIndex = 0; pathIndex < polygon.GetNumPaths(); ++pathIndex)
            {
                SimpleClosedPath path = polygon.GetPath(pathIndex);

                maxDepth = path.GetNumEdges() + 1;

                z -= 0.05f;

                //foreach (Edge edge in path.OwnEdgesOnly())
                foreach (Edge edge in path.AllEdges())
                {
                    GL.Begin(GL.LINES);
                    lineMat.SetPass(0);
                    GL.Color(polygonColor * (1.0f - ((float)depth / maxDepth) * show));
                    GL.Vertex3(edge.From.x, edge.From.y, z);
                    GL.Color(polygonColor * (1.0f - ((float)++depth / maxDepth) * show));
                    GL.Vertex3(edge.To.x, edge.To.y, z);
                    GL.End();
                }
            }
        }

        if (showResult || showOperands)
        {
            return;
        }

        z = 3.0f;

        for (int i = 0; i < edges.Count; ++i)
        {
            Edge edge = edges[i].Edge;

            Color color = !edges[i].InOut ? Color.white : Color.green;

            if (edges[i].Type == EdgeType.NON_CONTRIBUTING)
            {
                color = Color.red;
            }
            else if (edges[i].Type == EdgeType.SAME_TRANSITION)
            {
                color = Color.blue;
            }

            if (edges[i].Final)
            {
                color = edges[i].Sign;
            }

            Vector2 middle = Vector2.Lerp(edge.From, edge.To, 0.75f);

            z -= 0.05f;

            GL.Begin(GL.LINES);
            lineMat.SetPass(0);
            GL.Color(color);
            GL.Vertex3(edge.From.x, edge.From.y, z);
            GL.Vertex3(middle.x, middle.y, z);
            GL.Vertex3(middle.x, middle.y, z);
            GL.Color(edges[i].Final ? color : color * 0.25f);
            GL.Vertex3(edge.To.x, edge.To.y, z);
            GL.End();
        }
    }
Example #12
0
 public void Add(SimpleClosedPath c)
 {
     paths.Add(c);
 }
Example #13
0
            // public int[] Triangulate(Polygon p)
            // {
            // Polygon shell = Simplify(p);

            // foreach (SimpleClosedPath path in shell)
            // {

            // }
            // }

            List <int> TriangulateSimpleClosedPath(SimpleClosedPath path)
            {
                List <Vector2> points  = new List <Vector2>();
                List <int>     indices = new List <int>();

                int n = points.Count;

                if (n < 3)
                {
                    return(indices);
                }

                int[] V = new int[n];

                // path needs to be counter clockwise

                int nv    = n;
                int count = 2 * nv;

                for (int m = 0, v = nv - 1; nv > 2;)
                {
                    if (count-- <= 0)
                    {
                        return(indices);
                    }

                    int u = v;
                    if (nv <= u)
                    {
                        u = 0;
                    }

                    v = u + 1;
                    if (nv <= v)
                    {
                        v = 0;
                    }

                    int w = v + 1;
                    if (nv <= w)
                    {
                        w = 0;
                    }

                    if (Snip(u, v, w, nv, V, points))
                    {
                        int a, b, c, s, t;
                        a = V[u];
                        b = V[v];
                        c = V[w];
                        indices.Add(a);
                        indices.Add(b);
                        indices.Add(c);
                        ++m;

                        for (s = v, t = v + 1; t < nv; ++s, ++t)
                        {
                            V[s] = V[t];
                        }

                        --nv;
                        count = 2 * nv;
                    }
                }

                return(indices);
            }