Esempio n. 1
0
        private List <PointDouble> ClipToBounds(Rectangle bounds)
        {
            var  points = new List <PointDouble>();
            int  n      = _edges.Count;
            int  i      = 0;
            Edge edge;

            while (i < n && (!_edges[i].IsVisible))
            {
                ++i;
            }

            if (i == n)
            {
                // no edges visible
                return(new List <PointDouble>());
            }
            edge = _edges[i];
            LR orientation = _edgeOrientations[i];

            points.Add(edge.ClippedEnds[orientation]);
            points.Add(edge.ClippedEnds[orientation.other()]);

            for (int j = i + 1; j < n; ++j)
            {
                edge = _edges[j];
                if (!edge.IsVisible)
                {
                    continue;
                }
                Connect(points, j, bounds, false);
            }
            // close up the polygon by adding another corner point of the bounds if needed:
            Connect(points, i, bounds, true);

            return(points);
        }
Esempio n. 2
0
        private void Connect(List <PointDouble> points, int j, Rectangle bounds, bool closingUp)
        {
            PointDouble rightPoint     = points[points.Count - 1];
            Edge        newEdge        = _edges[j];
            LR          newOrientation = _edgeOrientations[j];
            // the point that  must be connected to rightPoint:
            PointDouble newPoint = newEdge.ClippedEnds[newOrientation];

            if (!CloseEnough(rightPoint, newPoint))
            {
                // The points do not coincide, so they must have been clipped at the bounds;
                // see if they are on the same border of the bounds:
                if (rightPoint.X != newPoint.X &&
                    rightPoint.Y != newPoint.Y)
                {
                    // They are on different borders of the bounds;
                    // insert one or two corners of bounds as needed to hook them up:
                    // (NOTE this will not be correct if the region should take up more than
                    // half of the bounds rect, for then we will have gone the wrong way
                    // around the bounds and included the smaller part rather than the larger)
                    int    rightCheck = BoundsCheck.Check(rightPoint, bounds);
                    int    newCheck = BoundsCheck.Check(newPoint, bounds);
                    double px, py;
                    if ((rightCheck & BoundsCheck.RIGHT) != 0)
                    {
                        px = bounds.right;
                        if ((newCheck & BoundsCheck.BOTTOM) != 0)
                        {
                            py = bounds.bottom;
                            points.Add(new PointDouble(px, py));
                        }
                        else if ((newCheck & BoundsCheck.TOP) != 0)
                        {
                            py = bounds.top;
                            points.Add(new PointDouble(px, py));
                        }
                        else if ((newCheck & BoundsCheck.LEFT) != 0)
                        {
                            if (rightPoint.Y - bounds.y + newPoint.Y - bounds.y < bounds.height)
                            {
                                py = bounds.top;
                            }
                            else
                            {
                                py = bounds.bottom;
                            }
                            points.Add(new PointDouble(px, py));
                            points.Add(new PointDouble(bounds.left, py));
                        }
                    }
                    else if ((rightCheck & BoundsCheck.LEFT) != 0)
                    {
                        px = bounds.left;
                        if ((newCheck & BoundsCheck.BOTTOM) != 0)
                        {
                            py = bounds.bottom;
                            points.Add(new PointDouble(px, py));
                        }
                        else if ((newCheck & BoundsCheck.TOP) != 0)
                        {
                            py = bounds.top;
                            points.Add(new PointDouble(px, py));
                        }
                        else if ((newCheck & BoundsCheck.RIGHT) != 0)
                        {
                            if (rightPoint.Y - bounds.y + newPoint.Y - bounds.y < bounds.height)
                            {
                                py = bounds.top;
                            }
                            else
                            {
                                py = bounds.bottom;
                            }
                            points.Add(new PointDouble(px, py));
                            points.Add(new PointDouble(bounds.right, py));
                        }
                    }
                    else if ((rightCheck & BoundsCheck.TOP) != 0)
                    {
                        py = bounds.top;
                        if ((newCheck & BoundsCheck.RIGHT) != 0)
                        {
                            px = bounds.right;
                            points.Add(new PointDouble(px, py));
                        }
                        else if ((newCheck & BoundsCheck.LEFT) != 0)
                        {
                            px = bounds.left;
                            points.Add(new PointDouble(px, py));
                        }
                        else if ((newCheck & BoundsCheck.BOTTOM) != 0)
                        {
                            if (rightPoint.X - bounds.x + newPoint.X - bounds.x < bounds.width)
                            {
                                px = bounds.left;
                            }
                            else
                            {
                                px = bounds.right;
                            }
                            points.Add(new PointDouble(px, py));
                            points.Add(new PointDouble(px, bounds.bottom));
                        }
                    }
                    else if ((rightCheck & BoundsCheck.BOTTOM) != 0)
                    {
                        py = bounds.bottom;
                        if ((newCheck & BoundsCheck.RIGHT) != 0)
                        {
                            px = bounds.right;
                            points.Add(new PointDouble(px, py));
                        }
                        else if ((newCheck & BoundsCheck.LEFT) != 0)
                        {
                            px = bounds.left;
                            points.Add(new PointDouble(px, py));
                        }
                        else if ((newCheck & BoundsCheck.TOP) != 0)
                        {
                            if (rightPoint.X - bounds.x + newPoint.X - bounds.x < bounds.width)
                            {
                                px = bounds.left;
                            }
                            else
                            {
                                px = bounds.right;
                            }
                            points.Add(new PointDouble(px, py));
                            points.Add(new PointDouble(px, bounds.top));
                        }
                    }
                }
                if (closingUp)
                {
                    // newEdge's ends have already been added
                    return;
                }
                points.Add(newPoint);
            }
            var newRightPoint = newEdge.ClippedEnds[newOrientation.other()];

            if (!CloseEnough(points[0], newRightPoint))
            {
                points.Add(newRightPoint);
            }
        }