private const byte TOP = 8; // 1000

        #endregion Fields

        #region Methods

        /// <summary>
        /// Cohen–Sutherland clipping algorithm clips a line from
        /// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
        /// diagonal from (xmin, ymin) to (xmax, ymax).
        /// </summary>
        /// <param name="x0"></param>
        /// <param name="y0""</param>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <returns>a list of two points in the resulting clipped line, or zero</returns>
        public static List<Point> CohenSutherlandLineClip(Rect extents, int x1, int y1, int x2, int y2)
        {
            float xf1 = x1;
            float yf1 = y1;
            float xf2 = x2;
            float yf2 = y2;

            // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
            byte outcode0 = CohenSutherland.ComputeOutCode(extents, xf1, yf1);
            byte outcode1 = CohenSutherland.ComputeOutCode(extents, xf2, yf2);
            bool accept = false;

            while (true)
            {
                // Bitwise OR is 0. Trivially accept and get out of loop
                if ((outcode0 | outcode1) == 0)
                {
                    accept = true;
                    break;
                }
                // Bitwise AND is not 0. Trivially reject and get out of loop
                else if ((outcode0 & outcode1) != 0)
                {
                    break;
                }
                else
                {
                    // failed both tests, so calculate the line segment to clip
                    // from an outside point to an intersection with clip edge
                    float x, y;

                    // At least one endpoint is outside the clip rectangle; pick it.
                    byte outcodeOut = (outcode0 != 0) ? outcode0 : outcode1;

                    // Now find the intersection point;
                    // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
                    if ((outcodeOut & TOP) != 0)
                    {   // point is above the clip rectangle
                        x = xf1 + (xf2 - xf1) * (extents.Top - yf1) / (yf2 - yf1);
                        y = extents.Top;
                    }
                    else if ((outcodeOut & BOTTOM) != 0)
                    { // point is below the clip rectangle
                        x = xf1 + (xf2 - xf1) * (extents.Bottom - yf1) / (yf2 - yf1);
                        y = extents.Bottom;
                    }
                    else if ((outcodeOut & RIGHT) != 0)
                    {  // point is to the right of clip rectangle
                        y = yf1 + (yf2 - yf1) * (extents.Right - xf1) / (xf2 - xf1);
                        x = extents.Right;
                    }
                    else if ((outcodeOut & LEFT) != 0)
                    {   // point is to the left of clip rectangle
                        y = yf1 + (yf2 - yf1) * (extents.Left - xf1) / (xf2 - xf1);
                        x = extents.Left;
                    }
                    else
                    {
                        x = float.NaN;
                        y = float.NaN;
                    }

                    // Now we move outside point to intersection point to clip
                    // and get ready for next pass.
                    if (outcodeOut == outcode0)
                    {
                        xf1 = x;
                        yf1 = y;
                        outcode0 = CohenSutherland.ComputeOutCode(extents, xf1, yf1);
                    }
                    else
                    {
                        xf2 = x;
                        yf2 = y;
                        outcode1 = CohenSutherland.ComputeOutCode(extents, xf2, yf2);
                    }
                }
            }

            // return the clipped line
            return (accept) ? new List<Point>() { new Point((int)xf1, (int)yf1), new Point((int)xf2, (int)yf2),} : null;
        }
예제 #2
0
        /// <summary>
        /// Initialise the class
        /// </summary>
        public Canvas()
        {
            _buffers = new UInt32[] { FrameBufferBase, FrameBufferBase + (ScreenWidth * ScreenHeight * 4) };

            _activeBuffer = 0;
            _backBuffer = 1;

            DisplayInterop.LCD_Init((UInt32*)_buffers[_activeBuffer], (UInt32*)_buffers[_backBuffer]);

            // initial clip
            _screenClip = new Rect(0, 0, ScreenWidth, ScreenHeight);
            _clip = _screenClip;

            _timer = new Timer();
            _timer.start();
        }
        /// <summary>
        /// Compute the bit code for a point (x, y) using the clip rectangle
        /// bounded diagonally by (xmin, ymin), and (xmax, ymax)
        /// ASSUME THAT xmax , xmin , ymax and ymin are global constants.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private static byte ComputeOutCode(Rect extents, float x, float y)
        {
            // initialised as being inside of clip window
            byte code = INSIDE;

            if (x < extents.Left)           // to the left of clip window
                code |= LEFT;
            else if (x > extents.Right)     // to the right of clip window
                code |= RIGHT;
            if (y > extents.Bottom)         // below the clip window
                code |= BOTTOM;
            else if (y < extents.Top)       // above the clip window
                code |= TOP;

            return code;
        }