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; }