Exemple #1
0
        void ProcessLeftVertex(VertexEvent leftVertexEvent, PolylinePoint nextVertex)
        {
            Debug.Assert(Z == leftVertexEvent.Site * SweepDirection);

            var site = leftVertexEvent.Site;

            ProcessPrevSegmentForLeftVertex(leftVertexEvent, site);

            Point  delta  = nextVertex.Point - leftVertexEvent.Site;
            double deltaX = delta * DirectionPerp;
            double deltaZ = delta * SweepDirection;

            if (deltaZ <= ApproximateComparer.DistanceEpsilon)
            {
                if (deltaX < 0 && deltaZ >= 0)
                {
                    EnqueueEvent(new LeftVertexEvent(nextVertex));
                }
            }
            else
            {
                //deltaZ>epsilon
                InsertLeftSide(new LeftObstacleSide(leftVertexEvent.Vertex));
                EnqueueEvent(new LeftVertexEvent(nextVertex));
            }
            //ShowAtPoint(leftVertexEvent.Site);
            RestrictEdgeFromTheLeftOfEvent(leftVertexEvent.Vertex);
        }
Exemple #2
0
        void ProcessRightVertex(VertexEvent rightVertexEvent, PolylinePoint nextVertex)
        {
            Debug.Assert(Z == rightVertexEvent.Site * SweepDirection);

            var site = rightVertexEvent.Site;

            ProcessPrevSegmentForRightVertex(rightVertexEvent, site);

            var delta  = nextVertex.Point - rightVertexEvent.Site;
            var deltaX = delta * DirectionPerp;
            var deltaZ = delta * SweepDirection;

            if (deltaZ <= ApproximateComparer.DistanceEpsilon)
            {
                if (deltaX > 0 && deltaZ >= 0)
                {
                    EnqueueEvent(new RightVertexEvent(nextVertex));
                }
                else
                {
                    RestrictEdgeContainerToTheRightOfEvent(rightVertexEvent.Vertex);
                }
            }
            else
            {
                //deltaZ>epsilon
                InsertRightSide(new RightObstacleSide(rightVertexEvent.Vertex));
                EnqueueEvent(new RightVertexEvent(nextVertex));
                RestrictEdgeContainerToTheRightOfEvent(rightVertexEvent.Vertex);
            }
        }
Exemple #3
0
 public void VertexChanged(VertexEvent vertexEvent)
 {
     foreach (var i in Parents)
     {
         ManagementControl.Instance.CurrentDocument.ObjectsDictionary[i].OnDataChange(vertexEvent);
     }
 }
    public void CheckCircle(BeachArc mid)
    {
        BeachEdge leftParent  = BeachNode.GetLeftParent(mid);
        BeachEdge rightParent = BeachNode.GetRightParent(mid);

        BeachArc left  = BeachNode.GetLeftChild(leftParent);
        BeachArc right = BeachNode.GetRightChild(rightParent);

        if (left == null || right == null || left.site == right.site)
        {
            return;
        }

        Vector2 s = GetEdgeIntersection(leftParent.edge, rightParent.edge);

        if (float.IsNaN(s.x) || float.IsNaN(s.y))
        {
            return;
        }

        float dx = left.site.pos.x - s.x;
        float dy = left.site.pos.y - s.y;

        float d = Mathf.Sqrt((dx * dx) + (dy * dy));

        if (s.y - d >= sweep)
        {
            return;
        }

        VertexEvent ev = new VertexEvent(left, mid, right);

        mid.ev = ev;
        events.Add(ev);
    }
    private void Generate()
    {
        // We'll use a sweeping algorithm to calculate the vertices and edges
        // Start with a priority queue for our events, initially storing
        // all our site events (each cell) sorted by y-coord
        SortedSet <VoronoiEvent> events = new SortedSet <VoronoiEvent>(new VoronoiEventComparer());

        foreach (Cell cell in diagram.cells)
        {
            events.Add(new SiteEvent
            {
                site = cell
            });
        }

        float     sweep = ConfigurationManager.Instance.height;
        BeachTree beach = new BeachTree(ConfigurationManager.Instance.width, ConfigurationManager.Instance.height, diagram, events);

        while (events.Count > 0)
        {
            VoronoiEvent e = events.Min;
            events.Remove(e);

            sweep       = e.pos.y;
            beach.sweep = e.pos.y;

            if (e.GetType() == typeof(SiteEvent))
            {
                SiteEvent se = (SiteEvent)e;
                beach.Insert(se.site);
            }
            else
            {
                VertexEvent ve = (VertexEvent)e;
                beach.Remove(ve);
            }
        }
        beach.Finish();

        List <Edge> halves = diagram.edges.Where(e => e.section != null).ToList();

        foreach (Edge e in halves)
        {
            e.start.edges.Remove(e);
            e.start = e.section.end;
            e.section.left.edges.Remove(e.section);
            e.section.right.edges.Remove(e.section);
            e.section.end.edges.Remove(e.section);
            e.section.start.edges.Remove(e.section);
            diagram.edges.Remove(e.section);
        }

        FixDiagram();

        Debug.Log("Done");

        ConstructMap();
    }
Exemple #6
0
        private void ProcessPrevSegmentForLeftVertex(VertexEvent leftVertexEvent, Point site)
        {
            var    prevSite = leftVertexEvent.Vertex.PrevOnPolyline.Point;
            var    delta    = site - prevSite;
            double deltaZ   = delta * SweepDirection;

            if (deltaZ > ApproximateComparer.DistanceEpsilon)
            {
                RemoveLeftSide(new LeftObstacleSide(leftVertexEvent.Vertex.PrevOnPolyline));
            }
        }
Exemple #7
0
        void ProcessPrevSegmentForRightVertex(VertexEvent rightVertexEvent, Point site)
        {
            var    prevSite = rightVertexEvent.Vertex.NextOnPolyline.Point;
            var    delta    = site - prevSite;
            double deltaZ   = delta * SweepDirection;

            if (deltaZ > ApproximateComparer.DistanceEpsilon)
            {
                RemoveRightSide(new RightObstacleSide(rightVertexEvent.Vertex.NextOnPolyline));
            }
        }
Exemple #8
0
 public void RemoveIntersectionWith(Edge edge)
 {
     for (int i = 0; i < mIntersections.Count; ++i)
     {
         VertexEvent e = mIntersections[i];
         if (e.IntersectingEdge == edge)
         {
             mIntersections.RemoveAt(i);
             return;
         }
     }
 }
Exemple #9
0
    public int FindIntersectionIndex(Vector3 p)
    {
        VecCompare vcompare = new VecCompare();

        for (int i = 0; i < mIntersections.Count; ++i)
        {
            VertexEvent e = mIntersections[i];
            if (vcompare.Compare(e.Point, p) == 0)
            {
                return(i);
            }
        }
        return(-1);
    }
Exemple #10
0
    public VertexEvent FindPrevIntersection(Vector3 p, ref Vector3 isect)
    {
        VertexEvent prev     = null;
        VecCompare  vcompare = new VecCompare();

        isect = Line.Start;
        foreach (VertexEvent e in mIntersections)
        {
            if (vcompare.Compare(e.Point, p) >= 0)
            {
                break;
            }
            isect = e.Point;
            prev  = e;
        }
        return(prev);
    }
Exemple #11
0
    public bool AddIntersection(VertexEvent ve)
    {
        IComparer <VertexEvent> evcompare = new EventCompare();
        VecCompare veccompare             = new VecCompare();

        for (int i = 0; i < mIntersections.Count; ++i)
        {
            VertexEvent ie = mIntersections[i];
            if (evcompare.Compare(ie, ve) == 0)
            {
                return(false);
            }
            if (veccompare.Compare(ie.Point, ve.Point) > 0)
            {
                mIntersections.Insert(i, ve);
                return(true);
            }
        }
        mIntersections.Add(ve);
        return(true);
    }
Exemple #12
0
        void ProcessVertexEvent(VertexEvent vertexEvent)
        {
            Z = GetZ(vertexEvent);
            var leftVertexEvent = vertexEvent as LeftVertexEvent;

            if (leftVertexEvent != null)
            {
                ProcessLeftVertex(leftVertexEvent, vertexEvent.Vertex.NextOnPolyline);
            }
            else
            {
                var rightVertexEvent = vertexEvent as RightVertexEvent;
                if (rightVertexEvent != null)
                {
                    ProcessRightVertex(rightVertexEvent, vertexEvent.Vertex.PrevOnPolyline);
                }
                else
                {
                    ProcessLeftVertex(vertexEvent, vertexEvent.Vertex.NextOnPolyline);
                    ProcessRightVertex(vertexEvent, vertexEvent.Vertex.PrevOnPolyline);
                }
            }
        }
Exemple #13
0
 public void OnDataChange(VertexEvent vertexEvent)
 {
 }
    public void Remove(VertexEvent e)
    {
        BeachArc mid = e.arcs[1];

        BeachEdge leftEdge  = BeachNode.GetLeftParent(mid);
        BeachEdge rightEdge = BeachNode.GetRightParent(mid);

        BeachArc left  = BeachNode.GetLeftChild(leftEdge);
        BeachArc right = BeachNode.GetRightChild(rightEdge);

        if (left.ev != null)
        {
            events.Remove(left.ev);
            left.ev = null;
        }
        if (right.ev != null)
        {
            events.Remove(right.ev);
            right.ev = null;
        }

        Vertex end = new Vertex(e.center);

        diagram.vertices.Add(end);
        leftEdge.edge.end  = end;
        rightEdge.edge.end = end;

        diagram.edges.Add(leftEdge.edge);
        diagram.edges.Add(rightEdge.edge);

        BeachEdge higher = null;
        BeachNode par    = mid;

        while (par != root)
        {
            par = par.parent;
            if (par == leftEdge)
            {
                higher = leftEdge;
            }
            if (par == rightEdge)
            {
                higher = rightEdge;
            }
        }
        higher.edge = new Edge(end, left.site, right.site);
        diagram.edges.Add(higher.edge);

        BeachEdge gparent = (BeachEdge)mid.parent.parent;

        if (mid.parent.left == mid)
        {
            if (gparent.left == mid.parent)
            {
                gparent.left = mid.parent.right;
            }
            if (gparent.right == mid.parent)
            {
                gparent.right = mid.parent.right;
            }
        }
        else
        {
            if (gparent.left == mid.parent)
            {
                gparent.left = mid.parent.left;
            }
            if (gparent.right == mid.parent)
            {
                gparent.right = mid.parent.left;
            }
        }

        CheckCircle(left);
        CheckCircle(right);
    }
    private IEnumerator GenerateVisualized()
    {
        // We'll use a sweeping algorithm to calculate the vertices and edges
        // Start with a priority queue for our events, initially storing
        // all our site events (each cell) sorted by y-coord
        SortedSet <VoronoiEvent> events = new SortedSet <VoronoiEvent>(new VoronoiEventComparer());

        foreach (Cell cell in diagram.cells)
        {
            events.Add(new SiteEvent
            {
                site = cell
            });
        }

        float     sweep = ConfigurationManager.Instance.height;
        BeachTree beach = new BeachTree(ConfigurationManager.Instance.width, ConfigurationManager.Instance.height, diagram, events);


        GameObject        sweepObj    = Instantiate(sweepPrefab, lineRenderersContainer);
        LineRenderer      sweepRend   = sweepObj.GetComponentInChildren <LineRenderer>();
        GameObject        eventObj    = Instantiate(eventPrefab, verticesContainer);
        List <GameObject> beachObjs   = new List <GameObject>();
        List <GameObject> diagramObjs = new List <GameObject>();

        foreach (Cell cell in diagram.cells)
        {
            GameObject cellGObject = Instantiate(cellPrefab, cellsContainer);
            cellGObject.transform.localPosition = cell.pos;
            cellGObject.transform.GetComponentInChildren <TextMeshPro>().text = cell.name;
            // TODO implement CellController and initialize it
        }

        //MakeBeach(beachObjs, beach.GetPoints(sweep));

        sweepRend.SetPositions(new Vector3[] { new Vector2(0, sweep), new Vector2(ConfigurationManager.Instance.width, sweep) });
        yield return(new WaitForSeconds(0.05f));

        while (events.Count > 0)
        {
            VoronoiEvent e = events.Min;
            events.Remove(e);
            eventObj.transform.localPosition = e.pos;
            while (sweep - 0.1f > e.pos.y)
            {
                sweep       = sweep - 0.1f;
                beach.sweep = sweep;

                sweepRend.SetPositions(new Vector3[] { new Vector2(0, sweep), new Vector2(ConfigurationManager.Instance.width, sweep) });
                MakeVoronoi(diagramObjs);
                MakeBeach(beachObjs, beach.GetBeachPoints());
                yield return(new WaitForSeconds(0.1f));
            }
            sweep       = e.pos.y;
            beach.sweep = e.pos.y;

            sweepRend.SetPositions(new Vector3[] { new Vector2(0, sweep), new Vector2(ConfigurationManager.Instance.width, sweep) });
            MakeVoronoi(diagramObjs);
            MakeBeach(beachObjs, beach.GetBeachPoints());
            yield return(new WaitForSeconds(0.1f));

            if (e.GetType() == typeof(SiteEvent))
            {
                SiteEvent se = (SiteEvent)e;
                beach.Insert(se.site);
            }
            else
            {
                VertexEvent ve = (VertexEvent)e;
                beach.Remove(ve);
            }
            MakeVoronoi(diagramObjs);
            MakeBeach(beachObjs, beach.GetBeachPoints());
            yield return(new WaitForSeconds(0.1f));
        }
        Debug.Log("Finished Events");
        beach.Finish();

        List <Edge> halves = diagram.edges.Where(e => e.section != null).ToList();

        foreach (Edge e in halves)
        {
            e.start.edges.Remove(e);
            e.start = e.section.end;
            e.section.left.edges.Remove(e.section);
            e.section.right.edges.Remove(e.section);
            e.section.end.edges.Remove(e.section);
            e.section.start.edges.Remove(e.section);
            diagram.edges.Remove(e.section);
        }

        FixDiagram();

        while (beachObjs.Count > 0)
        {
            Destroy(beachObjs[0]);
            beachObjs.RemoveAt(0);
        }
        while (diagramObjs.Count > 0)
        {
            Destroy(diagramObjs[0]);
            diagramObjs.RemoveAt(0);
        }
        // Construct current map
        ConstructMap();
    }