Пример #1
0
        // Cohen-Sutherland algorithm
        public static Line2D ClipToRectangle(Line2D line, RectangleF rect, out bool intersects)
        {
            int flags1 = MapSet.GetCSFieldBits(line.v1, rect);
            int flags2 = MapSet.GetCSFieldBits(line.v2, rect);

            intersects = false;

            Line2D result = line;

            while (true)
            {
                if (flags1 == 0 && flags2 == 0)
                {
                    // Line is fully inside the box
                    intersects = true;
                    return(result);
                }

                if ((flags1 & flags2) != 0)
                {
                    // Both points are in the same outer area
                    intersects = false;
                    return(new Line2D());
                }

                float x, y;
                int   outFlags = flags1 != 0 ? flags1 : flags2;
                if ((outFlags & 0x1) > 0)                 // Top
                {
                    x = result.v1.x + (result.v2.x - result.v1.x) * (rect.Top - result.v1.y) / (result.v2.y - result.v1.y);
                    y = rect.Top;
                }
                else if ((outFlags & 0x2) > 0)                 // Bottom
                {
                    x = result.v1.x + (result.v2.x - result.v1.x) * (rect.Bottom - result.v1.y) / (result.v2.y - result.v1.y);
                    y = rect.Bottom;
                }
                else if ((outFlags & 0x4) > 0)                 // Left
                {
                    y = result.v1.y + (result.v2.y - result.v1.y) * (rect.Left - result.v1.x) / (result.v2.x - result.v1.x);
                    x = rect.Left;
                }
                else if ((outFlags & 0x8) > 0)                 // Right
                {
                    y = result.v1.y + (result.v2.y - result.v1.y) * (rect.Right - result.v1.x) / (result.v2.x - result.v1.x);
                    x = rect.Right;
                }
                else
                {
                    intersects = true;
                    return(result);
                }

                if (outFlags == flags1)
                {
                    result.v1 = new Vector2D(x, y);
                    flags1    = MapSet.GetCSFieldBits(result.v1, rect);
                }
                else
                {
                    result.v2 = new Vector2D(x, y);
                    flags2    = MapSet.GetCSFieldBits(result.v2, rect);
                }
            }
        }