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();
    }
    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();
    }