Пример #1
0
        protected PointS adjustPoint2(PointS src, int level, Direction dir, ref int[] right, ref int[] left)
        {
            PointS p = src;

            // overlap to nearest lower level road (if exist)
            if (level < Configure.RoadLevelMax)
            {
                int start;
                if (dir == Direction.SOUTH || dir == Direction.NORTH)
                {
                    start = p.y;
                }
                else
                {
                    start = p.x;
                }
                int l  = min_length[Configure.RoadLevelMax];
                int dR = right[Configure.RoadLevelMax];
                int dL = left[Configure.RoadLevelMax];
                int sR = Math.Abs(dR - start);
                int sL = Math.Abs(dL - start);
                if (dR >= 0)
                {
                    if (dL >= 0)
                    {
                        if (sL < sR)
                        {
                            if (sL < l)
                            {
                                p = PointS.pointFrom(p, DirConvertor.rotL(dir), (short)(l - sL));
                            }
                        }
                        else
                        {
                            if (sR < l)
                            {
                                p = PointS.pointFrom(p, DirConvertor.rotR(dir), (short)(l - sR));
                            }
                        }
                    }
                    else if (sR < l)
                    {
                        p = PointS.pointFrom(p, DirConvertor.rotR(dir), (short)(l - sR));
                    }
                }
                else if (dL >= 0)
                {
                    if (sL < l)
                    {
                        p = PointS.pointFrom(p, DirConvertor.rotL(dir), (short)(l - sL));
                    }
                }
            }
            return(p);
        }
Пример #2
0
        protected int[] getNearestBranches(PointS p, Direction dir, int length)
        {
            int[] ret = new int[Configure.RoadLevelMax + 1];
            for (int i = 0; i < ret.Length; i++)
            {
                ret[i] = -1;
            }

            if (p.x < 0 || p.x >= world.xWidth)
            {
                return(ret);
            }
            if (p.y < 0 || p.y >= world.yWidth)
            {
                return(ret);
            }

            short vx = 0;
            short vy = 0;

            switch (dir)
            {
            case Direction.EAST:
                vx = +1;
                break;

            case Direction.WEST:
                vx = -1;
                break;

            case Direction.NORTH:
                vy = -1;
                break;

            case Direction.SOUTH:
                vy = +1;
                break;

            default:
                Debug.Assert(false);
                break;
            }
            // find flag: if all level branch found, becomes zero.
            int f = (1 << Configure.RoadLevelMax) - 1;
            // scanning range max.
            int       x    = p.x;
            int       y    = p.y;
            Direction dirL = DirConvertor.rotL(dir);
            Direction dirR = DirConvertor.rotR(dir);

            for (int i = 0; i < length; i++)
            {
                Road r = world[x, y].road;
                if (r != null)
                {
                    int lv = Math.Min(r.getLevel(dirR), r.getLevel(dirL));
                    if (lv <= Configure.RoadLevelMax && ret[lv] == -1)
                    {
                        // store x if dir is E or W otherwise store y.
                        ret[lv] = Math.Abs(x * vx + y * vy);
                        // reset flag
                        f ^= (1 << lv);
                        // all nearest branch found
                        if (f == 0)
                        {
                            break;
                        }
                    }
                }
                x += vx;
                y += vy;
                if (!world.isInWorld(x, y))
                {
                    break;
                }
            }
            return(ret);
        }
Пример #3
0
        protected int[] getLastBranches(RoadBud bud, PointS p, Direction dir)
        {
            if (!bud.sprouted || bud.lastBranch == null)
            {
                short     w  = min_length[0];
                int       n  = w * 2;
                Direction r  = DirConvertor.reverse(dir);
                int[]     b0 = getNearestBranches(p, r, n);
                int[]     bR = getNearestBranches(PointS.pointFrom(p, DirConvertor.rotR(dir), w), r, n);
                int[]     bL = getNearestBranches(PointS.pointFrom(p, DirConvertor.rotL(dir), w), r, n);
                if (dir == Direction.WEST || dir == Direction.NORTH)
                {
                    for (int i = 0; i < b0.Length; i++)
                    {
                        if (bR[i] > b0[i])
                        {
                            b0[i] = bR[i];
                        }
                        if (bL[i] > b0[i])
                        {
                            b0[i] = bL[i];
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < b0.Length; i++)
                    {
                        if (bR[i] > 0 && bR[i] < b0[i])
                        {
                            b0[i] = bR[i];
                        }
                        if (bL[i] > 0 && bL[i] < b0[i])
                        {
                            b0[i] = bL[i];
                        }
                    }
                }
                bud.lastBranch = b0;
                bud.sprouted   = true;
            }
            // high level branch is substitutable for lower one
            int v;

            if (dir == Direction.WEST || dir == Direction.NORTH)
            {
                v = -1;
            }
            else
            {
                v = 1;
            }
            for (int i = 1; i <= Configure.RoadLevelMax; i++)
            {
                if (bud.lastBranch[i - 1] != -1)
                {
                    if (bud.lastBranch[i] == -1)
                    {
                        bud.lastBranch[i] = bud.lastBranch[i - 1];
                    }
                    else
                    if ((bud.lastBranch[i - 1] - bud.lastBranch[i]) * v > 0)
                    {
                        bud.lastBranch[i] = bud.lastBranch[i - 1];
                    }
                }
            }
            return(bud.lastBranch);
        }
Пример #4
0
        protected void makeBranch(RoadBud bud, PointS p, int length, Direction dir)
        {
            int[] b     = getLastBranches(bud, p, dir);
            int   d_min = min_length[Configure.RoadLevelMax];

            // prepare arguments
            int start;

            if (dir == Direction.SOUTH || dir == Direction.NORTH)
            {
                start = p.y;
            }
            else
            {
                start = p.x;
            }
            int last = Math.Abs(b[Configure.RoadLevelMax] - start);

            int n = length / d_min + 1;

            // points proposed for branch
            short[] grid = new short[n];
            // set first point
            grid[0] = (short)world.randEx(0, 2);
            if (last < d_min)
            {
                grid[0] += (short)d_min;
            }
            // set followed points
            for (int i = 1; i < n; i++)
            {
                grid[i] = (short)(grid[i - 1] + d_min + world.randEx(0, 2));
            }

            // sleep count of the bud
            int[] counter = new int[n];

            for (int lv = bud.level; lv <= Configure.RoadLevelMax; lv++)
            {
                for (int i = 0; i < n; i++)
                {
                    counter[i] = -1;
                }
                last = Math.Abs(b[lv] - start);
                makeBranch2(lv, length, last, ref grid, ref counter);
                for (int i = 0; i < n; i++)
                {
                    if (counter[i] > -1)
                    {
                        PointS p2 = PointS.pointFrom(p, dir, grid[i]);
                        addBud(p2.x, p2.y, lv, DirConvertor.rotL(dir), counter[i]);
                        addBud(p2.x, p2.y, lv, DirConvertor.rotR(dir), counter[i]);
                        if (dir == Direction.EAST || dir == Direction.WEST)
                        {
                            bud.lastBranch[lv] = p2.x;
                        }
                        else
                        {
                            bud.lastBranch[lv] = p2.y;
                        }
                    }
                }
            }
        }
Пример #5
0
        protected PointS adjustPoint(int level, short x, short y, int length, Direction dir)
        {
            PointS p = new PointS(x, y);
            short  start;

            if (dir == Direction.SOUTH || dir == Direction.NORTH)
            {
                start = y;
            }
            else
            {
                start = x;
            }

            int       l    = min_length[level];
            Direction dirR = DirConvertor.rotR(dir);
            Direction dirL = DirConvertor.rotL(dir);

            int[] bR = getNearestBranches(PointS.pointFrom(p, dirR, 1), dirR, l * 4 / 3);
            int[] bL = getNearestBranches(PointS.pointFrom(p, dirL, 1), dirL, l * 4 / 3);
            int   dR = bR[level];
            int   dL = bL[level];
            int   sR = Math.Abs(dR - start);
            int   sL = Math.Abs(dL - start);
            int   s  = Math.Abs(dR - dL);

            if (dR >= 0)
            {
                // too close branch on ether side
                if (dL >= 0 && s < l)
                {
                    Debug.WriteLine("bud canceled 0");
                    return(null);
                }
                // close branch on right side
                if (sR < l)
                {
                    // can shift left side?
                    if (sL - l > l - sR)
                    {
                        p = PointS.pointFrom(p, DirConvertor.rotL(dir), (short)(l - sR));
                        bR[Configure.RoadLevelMax] = -1;
                        return(adjustPoint2(p, level, dir, ref bR, ref bL));
                    }
                    else
                    {
                        Debug.WriteLine("bud canceled R");
                        return(null);
                    }
                }
            }
            if (dL >= 0)
            {
                // close branch on left side
                if (sL < l)
                {
                    // can shift right side?
                    if (sR - l > l - sL)
                    {
                        p = PointS.pointFrom(p, DirConvertor.rotL(dir), (short)(l - sL));
                        bL[Configure.RoadLevelMax] = -1;
                        return(adjustPoint2(p, level, dir, ref bR, ref bL));
                    }
                    else
                    {
                        Debug.WriteLine("bud canceled L");
                        return(null);
                    }
                }
            }
            return(adjustPoint2(p, level, dir, ref bR, ref bL));
        }