Пример #1
0
        // Returns true if point lies in the viewing plane, false otherwise
        protected bool ClipSegment(IAxis x_axis, IAxis y_axis,
                                   ref Point a, ref Point b)
        {
            long x_min, x_max;

            x_axis.GetGridClipRegion(out x_min, out x_max);

            long y_min, y_max;

            y_axis.GetGridClipRegion(out y_min, out y_max);

            // Use the Cohen-Sutherland algorithm to clip points
            // described http://www.cim.mcgill.ca/~langer/557B/Jan16.html
            int outcode_a, outcode_b;

            while (true)
            {
                outcode_a  = Convert.ToInt32(a.Y > y_max) << 3;
                outcode_a |= Convert.ToInt32(a.Y < y_min) << 2;
                outcode_a |= Convert.ToInt32(a.X > x_max) << 1;
                outcode_a |= Convert.ToInt32(a.X < x_min);

                outcode_b  = Convert.ToInt32(b.Y > y_max) << 3;
                outcode_b |= Convert.ToInt32(b.Y < y_min) << 2;
                outcode_b |= Convert.ToInt32(b.X > x_max) << 1;
                outcode_b |= Convert.ToInt32(b.X < x_min);

                // Trivially accept edge if bitwise OR of outcodes is 0000
                if ((outcode_a | outcode_b) == 0)
                {
                    return(true);
                }

                // Trivially reject edge if the bitwise AND of the two outcomes is other than 0000
                if ((outcode_a & outcode_b) != 0)
                {
                    return(false);
                }

                // Now, we know that at least one of the points needs to be clipped.
                Point p = a, o = b;
                int   current_outcode = outcode_a;

                if (outcode_a == 0)
                {
                    p = b;
                    o = a;
                    current_outcode = outcode_b;
                }

                double m = (b.Y - a.Y) / ((double)b.X - a.X);

                p.IsClipped = true;

                // handle vertical lines specially, since
                // Cohen-Sutherland doesn't specifically
                // discuss them

                bool is_vertical = (m == Double.PositiveInfinity);
                if ((current_outcode & 8) == 8)                                         // Above
                {
                    p.Y = y_max;
                    p.X = (is_vertical) ? p.X : Convert.ToInt64(((p.Y - o.Y) / m) + o.X);
                }
                else if ((current_outcode & 4) == 4)                                    // Below
                {
                    p.Y = y_min;
                    p.X = (is_vertical) ? p.X : Convert.ToInt64(((p.Y - o.Y) / m) + o.X);
                }
                else if ((current_outcode & 2) == 2)                                    // Right
                {
                    p.X = x_max;
                    p.Y = (is_vertical) ? p.Y : Convert.ToInt64(((p.X - o.X) * m) + o.Y);
                }
                else if ((current_outcode & 1) == 1)                                    // Left
                {
                    p.X = x_min;
                    p.Y = (is_vertical) ? p.Y : Convert.ToInt64(((p.X - o.X) * m) + o.Y);
                }

                if (outcode_a != 0)
                {
                    a = p;
                }
                else
                {
                    b = p;
                }
            }
        }