Exemplo n.º 1
0
    public void road_generator()
    {
        /* the road generator will generate the roads in the input square area
         * What does it do:
         * find the ideal split orientation for the area(split on the longest edge);
         * get the start point and end point;
         * add some noise(should be in restriction)
         * get_gridpos(startpos,endpos)
         * return the new generated square areas
         */
        gridmap.quand_area a = new gridmap.quand_area();
        a.corner00 = new Vector2(0, 0);
        a.corner01 = new Vector2(width, 0);
        a.corner10 = new Vector2(0, height);
        a.corner11 = new Vector2(width, height);

        Queue <quand_area> areas = new Queue <quand_area>();

        areas.Enqueue(a);
        int depth_thread = 20;

        while (areas.Count != 0)
        {
            quand_area current   = areas.Dequeue();
            Vector2[]  start_end = split_picker(ref current);
            if (start_end != null)
            {
                Vector2 startpos = start_end[0];
                Vector2 endpos   = start_end[1];
                float   road_width;
                if (depth_thread > 14)
                {
                    road_width = 3f;
                }
                else if (depth_thread > 0)
                {
                    road_width = 2f;
                }
                else
                {
                    road_width = 1f;
                }

                quand_area[] new_a = new_areas(current, startpos, endpos, road_width);
                depth_thread -= 1;
                areas.Enqueue(new_a[0]);
                areas.Enqueue(new_a[1]);
            }
        }
    }
Exemplo n.º 2
0
    private quand_area[] new_areas(quand_area a, Vector2 start_pos, Vector2 end_pos, float width)
    {
        quand_area[] new_a = new quand_area[2];
        switch (a.o)
        {
        case orientation.v:
            quand_area a1v = new quand_area();
            a1v.corner00 = a.corner00;
            a1v.corner10 = a.corner10;
            Vector2 dir_v1 = (a.corner01 - a.corner00).normalized;
            Vector2 dir_v2 = (a.corner11 - a.corner10).normalized;

            a1v.corner01 = start_pos - 0.5f * width * dir_v1;
            a1v.corner11 = end_pos - 0.5f * width * dir_v2;
            new_a[0]     = a1v;
            quand_area a2v = new quand_area();
            a2v.corner00 = start_pos + 0.5f * width * dir_v1;
            a2v.corner10 = end_pos + 0.5f * width * dir_v2;
            a2v.corner01 = a.corner01;
            a2v.corner11 = a.corner11;
            new_a[1]     = a2v;
            return(new_a);

        case orientation.h:
            quand_area a1h    = new quand_area();
            Vector2    dir_h1 = (a.corner10 - a.corner00).normalized;
            Vector2    dir_h2 = (a.corner11 - a.corner01).normalized;
            a1h.corner00 = a.corner00;
            a1h.corner10 = start_pos - 0.5f * width * dir_h1;
            a1h.corner01 = a.corner01;
            a1h.corner11 = end_pos - 0.5f * width * dir_h2;
            new_a[0]     = a1h;
            quand_area a2h = new quand_area();
            a2h.corner00 = start_pos + 0.5f * width * dir_h1;
            a2h.corner10 = a.corner10;
            a2h.corner01 = end_pos + 0.5f * width * dir_h2;
            a2h.corner11 = a.corner11;
            new_a[1]     = a2h;
            return(new_a);

        default:
            Debug.LogWarning("no new area added, the previoud area is not updated or not qualified for splitting.");
            return(null);
        }
    }
Exemplo n.º 3
0
    private Vector2[] split_picker(ref quand_area a)
    {
        float len_h0 = Vector2.Distance(a.corner00, a.corner01);
        float len_h1 = Vector2.Distance(a.corner10, a.corner11);
        float len_v0 = Vector2.Distance(a.corner00, a.corner10);
        float len_v1 = Vector2.Distance(a.corner01, a.corner11);

        //judge whether we could split(estimated area bigger than 7*7)
        float est_area = (len_h0 + len_h1) * (len_v0 * len_v1) / 4;

        if (est_area < Thread)
        {
            Debug.LogWarning("Area is too small for spliting");
            areas.Add(a);
            Debug.Log(areas.Count); return(null);
        }
        else
        {
            Vector2[] start_end = new Vector2[2];
            if ((len_h0 + len_h1) > (len_v0 + len_v1))
            {
                //split vertically
                a.o = orientation.v;
                float   noise = 0.1f - 0.2f * Random.value;
                Vector2 mid0  = (a.corner00 + a.corner01) / 2 + noise * (a.corner01 - a.corner00);
                noise = 0.1f - 0.2f * Random.value;
                Vector2 mid1 = (a.corner10 + a.corner11) / 2 + noise * (a.corner11 - a.corner10);
                start_end[0] = mid0;
                start_end[1] = mid1;
                return(start_end);
            }
            else
            {
                //split horizontally
                a.o = orientation.h;
                float   noise = 0.15f - 0.3f * Random.value;
                Vector2 mid0  = (a.corner00 + a.corner10) / 2 + noise * (a.corner10 - a.corner00);
                noise = 0.15f - 0.3f * Random.value;
                Vector2 mid1 = (a.corner01 + a.corner11) / 2 + noise * (a.corner11 - a.corner01);
                start_end[0] = mid0;
                start_end[1] = mid1;
                return(start_end);
            }
        }
    }