Exemple #1
0
 public void DrawAndAdd(WriteableBitmap wb, Point point, Color color, int width)
 {
     Point = point;
     Color = color;
     Width = width;
     MyBoundary = new MyBoundary(Point.X, Point.Y);
     wb.DrawPoint(point, color, Width);
 }
        public void CohenSutherlandLineClipTest3()
        {
            MyBoundary mb = new MyBoundary(0, 0, 100, 100);
            Point p0 = new Point(150, 150);
            Point p1 = new Point(151, 151);

            var list = PolygonClipping.CohenSutherlandLineClip(mb, p0, p1);

            Assert.IsNull(list);
        }
        public void CohenSutherlandLineClipTest10()
        {
            MyBoundary mb = new MyBoundary(200, 200, 400, 400);
            Point p0 = new Point(200, 100);
            Point p1 = new Point(200, 500);

            var list = PolygonClipping.CohenSutherlandLineClip(mb, p0, p1);
            var correct = new List<Point> { new Point(200, 200), new Point(200, 400) };

            for (int i = 0; i < list.Count(); i++)
            {
                Assert.AreEqual(list[i].X, correct[i].X);
                Assert.AreEqual(list[i].Y, correct[i].Y);
            }
        }
        public void CohenSutherlandLineClipTest2()
        {
            MyBoundary mb = new MyBoundary(0, 0, 100, 100);
            Point p0 = new Point(50, 50);
            Point p1 = new Point(75, 75);

            var list = PolygonClipping.CohenSutherlandLineClip(mb, p0, p1);
            var correct = new List<Point> { new Point(50, 50), new Point(75, 75) };

            if (list.Count() == correct.Count())
            {
                for (int i = 0; i < list.Count(); i++)
                {
                    Assert.AreEqual(list[i].X, correct[i].X);
                    Assert.AreEqual(list[i].Y, correct[i].Y);
                }
            }
        }
        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.
        /// </summary>
        /// <param name="boundary"></param>
        /// <param name="p0"></param>
        /// <param name="p1"></param>
        /// <returns>Returns a list of two points in the resulting clipped line, or zero.</returns>
        public static List<Point> CohenSutherlandLineClip(MyBoundary boundary, Point p0, Point p1)
        {
            var x0 = p0.X;
            var y0 = p0.Y;
            var x1 = p1.X;
            var y1 = p1.Y;

            var outcode0 = ComputeOutCode(boundary, x0, y0);
            var outcode1 = ComputeOutCode(boundary, x1, y1);
            var 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
                {
                    double x, y;

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

                    // Now find the intersection point;

                    if ((outcodeOut & Top) != 0)
                    {
                        x = x0 + (x1 - x0) * (boundary.YMin - y0) / (y1 - y0);
                        y = boundary.YMin;
                    }
                    else if ((outcodeOut & Bottom) != 0)
                    {
                        x = x0 + (x1 - x0) * (boundary.YMax - y0) / (y1 - y0);
                        y = boundary.YMax;
                    }
                    else if ((outcodeOut & Right) != 0)
                    {
                        y = y0 + (y1 - y0) * (boundary.XMax - x0) / (x1 - x0);
                        x = boundary.XMax;
                    }
                    else if ((outcodeOut & Left) != 0)
                    {
                        y = y0 + (y1 - y0) * (boundary.XMin - x0) / (x1 - x0);
                        x = boundary.XMin;
                    }
                    else
                    {
                        x = double.NaN;
                        y = double.NaN;
                    }

                    // Now we move outside point to intersection point to clip and get ready for next pass.

                    if (outcodeOut == outcode0)
                    {
                        x0 = x;
                        y0 = y;
                        outcode0 = ComputeOutCode(boundary, x0, y0);
                    }
                    else
                    {
                        x1 = x;
                        y1 = y;
                        outcode1 = ComputeOutCode(boundary, x1, y1);
                    }
                }
            }

            return (accept) ? new List<Point>()
            {
            new Point(x0, y0),
            new Point(x1, y1),
            } : null;
        }
        /// <summary>
        /// Compute the bit code for a point (x, y) using the clip rectangle bounded diagonally.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns>Returns CompOut Code.</returns>
        private static byte ComputeOutCode(MyBoundary boundary, double x, double y)
        {
            // initialised as being inside of clip window
            byte code = Inside;

            if (y < boundary.YMin)          // above the clip window
                code |= Top;
            else if (y > boundary.YMax)     // below the clip window
                code |= Bottom;
            if (x < boundary.XMin)          // to the left of clip window
                code |= Left;
            else if (x > boundary.XMax)     // to the right of clip window
                code |= Right;

            return code;
        }