public void BlurArea(int amount)
        {
            if (amount == 0)
            {
                return;
            }
            var map = Map;
            int sizeX = Map.GetLength(0), sizeY = Map.GetLength(1);

            Node[,] newMap = new Node[sizeX, sizeY];
            XRectangle range = activeArea.
                               Inflate(1).
                               RestrictToWithin(new XRectangle(0, 0, sizeX, sizeY));

            for (int x = range.Left; x < range.Right; ++x)
            {
                for (int y = range.Top; y < range.Bottom; ++y)
                {
                    float ave = 0, cnt = 0;
                    for (int dx = -amount; dx <= amount; ++dx)
                    {
                        for (int dy = -amount; dy <= amount; ++dy)
                        {
                            if (dx * dx + dy * dy > amount * amount)
                            {
                                continue;
                            }
                            float weight = 1 - //(float)Math.Sqrt
                                           ((float)(dx * dx + dy * dy) / (amount * amount));
                            int px = x + dx, py = y + dy;
                            if (px >= 0 && py >= 0 && px < sizeX && py < sizeY)
                            {
                                ave += (map[px, py].Weight < 0 ? -1 : 0) * weight;
                                cnt += weight;
                            }
                        }
                    }
                    newMap[x, y].Weight = ave / cnt;
                    if (newMap[x, y].Weight < -0.5f)
                    {
                        Debug.Assert(activeArea.Contains(new XPoint2(x, y)),
                                     "A blurred area should never be larger than the previous area (in terms of bounding box)");
                    }
                }
            }
            activeArea = range;
            Map        = newMap;
        }
Esempio n. 2
0
        void CalculateDistances(int minDistance, int maxDistance)
        {
            var        map     = Map;
            XRectangle range   = activeArea;
            XRectangle mapRect = new XRectangle(0, 0, Map.GetLength(0), Map.GetLength(1));

            range.Inflate(maxDistance);
            range.RestrictToWithin(mapRect);
            List <XPoint2> stack = new List <XPoint2>();

            for (int y = range.Top; y < range.Bottom; ++y)
            {
                for (int x = range.Left; x < range.Right; ++x)
                {
                    int minDist = int.MaxValue;
                    for (int o = 0; o < propogOffs.Length; ++o)
                    {
                        XPoint2 off = propogOffs[o];
                        if (!mapRect.Contains(new XPoint2(x + off.X, y + off.Y)))
                        {
                            continue;
                        }
                        if (map[x + off.X, y + off.Y].IsPositive != map[x, y].IsPositive)
                        {
                            int newCost = propogCost[o];
                            minDist = Math.Min(minDist, newCost);
                        }
                    }
                    if (minDist < int.MaxValue)
                    {
                        stack.Add(new XPoint2(x, y));
                        map[x, y].Weight = (map[x, y].IsPositive ? 70 : 70 - minDist);
                    }
                    else
                    {
                        map[x, y].Weight = (map[x, y].IsPositive ? maxDistance * 70 : minDistance * 70);
                    }
                }
            }
            while (stack.Count > 0)
            {
                int count = stack.Count;
                for (int s = 0; s < count; ++s)
                {
                    var pnt  = stack[s];
                    var node = map[pnt.X, pnt.Y];
                    for (int o = 0; o < propogOffs.Length; ++o)
                    {
                        var newP = pnt + propogOffs[o];
                        if (!mapRect.Contains(newP))
                        {
                            continue;
                        }
                        var tnode = map[newP.X, newP.Y];
                        if (node.IsPositive != tnode.IsPositive)
                        {
                            continue;
                        }
                        int newCost = node.Weight + (node.IsPositive ? propogCost[o] : -propogCost[o]);
                        if (Math.Abs(newCost) < Math.Abs(tnode.Weight))
                        {
                            map[newP.X, newP.Y].Weight = newCost;
                            stack.Add(newP);
                        }
                    }
                }
                stack.RemoveRange(0, count);
            }
        }