Ejemplo n.º 1
0
        /// <summary>
        /// Creates a graphics path from the given stencil buffer. It should be filled with 'true' values
        /// to indicate the areas that should be outlined.
        /// </summary>
        /// <param name="stencil">The stencil buffer to read from. NOTE: The contents of this will be destroyed when this method returns.</param>
        /// <param name="bounds">The bounding box within the stencil buffer to limit discovery to.</param>
        /// <returns>A PdnGraphicsPath with traces that outline the various areas from the given stencil buffer.</returns>
        public unsafe static PdnGraphicsPath PathFromStencil(IBitVector2D stencil, Rectangle bounds)
        {
            if (stencil.IsEmpty)
            {
                return(new PdnGraphicsPath());
            }

            PdnGraphicsPath ret   = new PdnGraphicsPath();
            Point           start = bounds.Location;
            Vector <Point>  pts   = new Vector <Point>();
            int             count = 0;

            // find all islands
            while (true)
            {
                bool startFound = false;

                while (true)
                {
                    if (stencil[start])
                    {
                        startFound = true;
                        break;
                    }

                    ++start.X;

                    if (start.X >= bounds.Right)
                    {
                        ++start.Y;
                        start.X = bounds.Left;

                        if (start.Y >= bounds.Bottom)
                        {
                            break;
                        }
                    }
                }

                if (!startFound)
                {
                    break;
                }

                pts.Clear();
                Point last  = new Point(start.X, start.Y + 1);
                Point curr  = new Point(start.X, start.Y);
                Point next  = curr;
                Point left  = Point.Empty;
                Point right = Point.Empty;

                // trace island outline
                while (true)
                {
                    left.X = ((curr.X - last.X) + (curr.Y - last.Y) + 2) / 2 + curr.X - 1;
                    left.Y = ((curr.Y - last.Y) - (curr.X - last.X) + 2) / 2 + curr.Y - 1;

                    right.X = ((curr.X - last.X) - (curr.Y - last.Y) + 2) / 2 + curr.X - 1;
                    right.Y = ((curr.Y - last.Y) + (curr.X - last.X) + 2) / 2 + curr.Y - 1;

                    if (bounds.Contains(left) && stencil[left])
                    {
                        // go left
                        next.X += curr.Y - last.Y;
                        next.Y -= curr.X - last.X;
                    }
                    else if (bounds.Contains(right) && stencil[right])
                    {
                        // go straight
                        next.X += curr.X - last.X;
                        next.Y += curr.Y - last.Y;
                    }
                    else
                    {
                        // turn right
                        next.X -= curr.Y - last.Y;
                        next.Y += curr.X - last.X;
                    }

                    if (Math.Sign(next.X - curr.X) != Math.Sign(curr.X - last.X) ||
                        Math.Sign(next.Y - curr.Y) != Math.Sign(curr.Y - last.Y))
                    {
                        pts.Add(curr);
                        ++count;
                    }

                    last = curr;
                    curr = next;

                    if (next.X == start.X && next.Y == start.Y)
                    {
                        break;
                    }
                }

                Point[]    points = pts.ToArray();
                Scanline[] scans  = Utility.GetScans(points);

                foreach (Scanline scan in scans)
                {
                    stencil.Invert(scan);
                }

                ret.AddLines(points);
                ret.CloseFigure();
            }

            return(ret);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a graphics path from the given stencil buffer. It should be filled with 'true' values
        /// to indicate the areas that should be outlined.
        /// </summary>
        /// <param name="stencil">The stencil buffer to read from. NOTE: The contents of this will be destroyed when this method returns.</param>
        /// <param name="bounds">The bounding box within the stencil buffer to limit discovery to.</param>
        /// <returns>A PdnGraphicsPath with traces that outline the various areas from the given stencil buffer.</returns>
        public unsafe static PdnGraphicsPath PathFromStencil(IBitVector2D stencil, Rectangle bounds)
        {
            if (stencil.IsEmpty)
            {
                return new PdnGraphicsPath();
            }

            PdnGraphicsPath ret = new PdnGraphicsPath();
            Point start = bounds.Location;
            Vector<Point> pts = new Vector<Point>();
            int count = 0;

            // find all islands
            while (true) 
            {
                bool startFound = false;

                while (true)
                {
                    if (stencil[start])
                    {
                        startFound = true;
                        break;
                    }

                    ++start.X;

                    if (start.X >= bounds.Right)
                    {
                        ++start.Y;
                        start.X = bounds.Left;

                        if (start.Y >= bounds.Bottom)
                        {
                            break;
                        }
                    }
                }
            
                if (!startFound)
                {
                    break;
                }

                pts.Clear();
                Point last = new Point(start.X, start.Y + 1);
                Point curr = new Point(start.X, start.Y);
                Point next = curr;
                Point left = Point.Empty;
                Point right = Point.Empty;
            
                // trace island outline
                while (true)
                {
                    left.X = ((curr.X - last.X) + (curr.Y - last.Y) + 2) / 2 + curr.X - 1;
                    left.Y = ((curr.Y - last.Y) - (curr.X - last.X) + 2) / 2 + curr.Y - 1;

                    right.X = ((curr.X - last.X) - (curr.Y - last.Y) + 2) / 2 + curr.X - 1;
                    right.Y = ((curr.Y - last.Y) + (curr.X - last.X) + 2) / 2 + curr.Y - 1;

                    if (bounds.Contains(left) && stencil[left])
                    {
                        // go left
                        next.X += curr.Y - last.Y;
                        next.Y -= curr.X - last.X;
                    }
                    else if (bounds.Contains(right) && stencil[right])
                    {
                        // go straight
                        next.X += curr.X - last.X;
                        next.Y += curr.Y - last.Y;
                    }
                    else
                    {
                        // turn right
                        next.X -= curr.Y - last.Y;
                        next.Y += curr.X - last.X;
                    }

                    if (Math.Sign(next.X - curr.X) != Math.Sign(curr.X - last.X) ||
                        Math.Sign(next.Y - curr.Y) != Math.Sign(curr.Y - last.Y))
                    {
                        pts.Add(curr);
                        ++count;
                    }

                    last = curr;
                    curr = next;

                    if (next.X == start.X && next.Y == start.Y)
                    {
                        break;
                    }
                }

                Point[] points = pts.ToArray();
                Scanline[] scans = Utility.GetScans(points);

                foreach (Scanline scan in scans)
                {
                    stencil.Invert(scan);
                }

                ret.AddLines(points);
                ret.CloseFigure();
            }

            return ret;
        }
Ejemplo n.º 3
0
        public unsafe static Point[][] PolygonSetFromStencil(IBitVector2D stencil, Rectangle bounds, int translateX, int translateY)
        {
            List <Point[]> polygons = new List <Point[]>();

            if (!stencil.IsEmpty)
            {
                Point        start = bounds.Location;
                List <Point> pts   = new List <Point>();
                int          count = 0;

                // find all islands
                while (true)
                {
                    bool startFound = false;

                    while (true)
                    {
                        if (stencil[start])
                        {
                            startFound = true;
                            break;
                        }

                        ++start.X;

                        if (start.X >= bounds.Right)
                        {
                            ++start.Y;
                            start.X = bounds.Left;

                            if (start.Y >= bounds.Bottom)
                            {
                                break;
                            }
                        }
                    }

                    if (!startFound)
                    {
                        break;
                    }

                    pts.Clear();
                    Point last  = new Point(start.X, start.Y + 1);
                    Point curr  = new Point(start.X, start.Y);
                    Point next  = curr;
                    Point left  = Point.Empty;
                    Point right = Point.Empty;

                    // trace island outline
                    while (true)
                    {
                        left.X = ((curr.X - last.X) + (curr.Y - last.Y) + 2) / 2 + curr.X - 1;
                        left.Y = ((curr.Y - last.Y) - (curr.X - last.X) + 2) / 2 + curr.Y - 1;

                        right.X = ((curr.X - last.X) - (curr.Y - last.Y) + 2) / 2 + curr.X - 1;
                        right.Y = ((curr.Y - last.Y) + (curr.X - last.X) + 2) / 2 + curr.Y - 1;

                        if (bounds.Contains(left) && stencil[left])
                        {
                            // go left
                            next.X += curr.Y - last.Y;
                            next.Y -= curr.X - last.X;
                        }
                        else if (bounds.Contains(right) && stencil[right])
                        {
                            // go straight
                            next.X += curr.X - last.X;
                            next.Y += curr.Y - last.Y;
                        }
                        else
                        {
                            // turn right
                            next.X -= curr.Y - last.Y;
                            next.Y += curr.X - last.X;
                        }

                        if (Math.Sign(next.X - curr.X) != Math.Sign(curr.X - last.X) ||
                            Math.Sign(next.Y - curr.Y) != Math.Sign(curr.Y - last.Y))
                        {
                            pts.Add(curr);
                            ++count;
                        }

                        last = curr;
                        curr = next;

                        if (next.X == start.X && next.Y == start.Y)
                        {
                            break;
                        }
                    }

                    Point[]    points = pts.ToArray();
                    Scanline[] scans  = Utility.GetScans(points);

                    foreach (Scanline scan in scans)
                    {
                        stencil.Invert(scan);
                    }

                    Utility.TranslatePointsInPlace(points, translateX, translateY);
                    polygons.Add(points);
                }
            }

            Point[][] returnVal = polygons.ToArray();
            return(returnVal);
        }
Ejemplo n.º 4
0
        public unsafe static Point[][] PolygonSetFromStencil(IBitVector2D stencil, Rectangle bounds, int translateX, int translateY)
        {
            List<Point[]> polygons = new List<Point[]>();

            if (!stencil.IsEmpty)
            {
                Point start = bounds.Location;
                List<Point> pts = new List<Point>();
                int count = 0;

                // find all islands
                while (true) 
                {
                    bool startFound = false;

                    while (true)
                    {
                        if (stencil[start])
                        {
                            startFound = true;
                            break;
                        }

                        ++start.X;

                        if (start.X >= bounds.Right)
                        {
                            ++start.Y;
                            start.X = bounds.Left;

                            if (start.Y >= bounds.Bottom)
                            {
                                break;
                            }
                        }
                    }
            
                    if (!startFound)
                    {
                        break;
                    }

                    pts.Clear();
                    Point last = new Point(start.X, start.Y + 1);
                    Point curr = new Point(start.X, start.Y);
                    Point next = curr;
                    Point left = Point.Empty;
                    Point right = Point.Empty;
            
                    // trace island outline
                    while (true)
                    {
                        left.X = ((curr.X - last.X) + (curr.Y - last.Y) + 2) / 2 + curr.X - 1;
                        left.Y = ((curr.Y - last.Y) - (curr.X - last.X) + 2) / 2 + curr.Y - 1;

                        right.X = ((curr.X - last.X) - (curr.Y - last.Y) + 2) / 2 + curr.X - 1;
                        right.Y = ((curr.Y - last.Y) + (curr.X - last.X) + 2) / 2 + curr.Y - 1;

                        if (bounds.Contains(left) && stencil[left])
                        {
                            // go left
                            next.X += curr.Y - last.Y;
                            next.Y -= curr.X - last.X;
                        }
                        else if (bounds.Contains(right) && stencil[right])
                        {
                            // go straight
                            next.X += curr.X - last.X;
                            next.Y += curr.Y - last.Y;
                        }
                        else
                        {
                            // turn right
                            next.X -= curr.Y - last.Y;
                            next.Y += curr.X - last.X;
                        }

                        if (Math.Sign(next.X - curr.X) != Math.Sign(curr.X - last.X) ||
                            Math.Sign(next.Y - curr.Y) != Math.Sign(curr.Y - last.Y))
                        {
                            pts.Add(curr);
                            ++count;
                        }

                        last = curr;
                        curr = next;

                        if (next.X == start.X && next.Y == start.Y)
                        {
                            break;
                        }
                    }

                    Point[] points = pts.ToArray();
                    Scanline[] scans = Utility.GetScans(points);

                    foreach (Scanline scan in scans)
                    {
                        stencil.Invert(scan);
                    }

                    Utility.TranslatePointsInPlace(points, translateX, translateY);
                    polygons.Add(points);
                }
            }

            Point[][] returnVal = polygons.ToArray();
            return returnVal;
        }