public string this[string columnName] { get { string result = null; if (columnName == "OutType") { if (String.IsNullOrEmpty(OutType)) { result = String.Format("{0} required.\r\n", columnName); } //if (OutType == null) //{ // result = "OutType not supplied."; //} } if (columnName == "OutCode") { if (OutCode != null && OutCode.ToString().Length > 8) { result = "OutCode exceeds maximum length (8 digits)."; //OutCode = (int?)int.Parse(OutCode.ToString().Substring(0, 8)); } } return(result); } }
private static PointF CalculateIntersection(RectangleF r, PointF p1, PointF p2, OutCode clipTo) { var dx = (p2.X - p1.X); var dy = (p2.Y - p1.Y); var slopeY = dx / dy; // slope to use for possibly-vertical lines var slopeX = dy / dx; // slope to use for possibly-horizontal lines if (clipTo.HasFlag(OutCode.Top)) { return new PointF( p1.X + slopeY * (r.Top - p1.Y), r.Top ); } if (clipTo.HasFlag(OutCode.Bottom)) { return new PointF( p1.X + slopeY * (r.Bottom - p1.Y), r.Bottom ); } if (clipTo.HasFlag(OutCode.Right)) { return new PointF( r.Right, p1.Y + slopeX * (r.Right - p1.X) ); } if (clipTo.HasFlag(OutCode.Left)) { return new PointF( r.Left, p1.Y + slopeX * (r.Left - p1.X) ); } throw new ArgumentOutOfRangeException("clipTo = " + clipTo); }
private static Vector3 ClipEulerAgainstMaxPitchYaw(Vector3 val, Vector3 min, Vector3 max) { OutCode outCode = ComputeOutCode(val, min, max); if ((OutCode.INSIDE | outCode) != 0) { OutCode outCode2 = outCode; if ((outCode2 & OutCode.TOP) != 0) { val.x = val.x * max.y / val.y; val.y = max.y; } else if ((outCode2 & OutCode.BOTTOM) != 0) { val.x = val.x * min.y / val.y; val.y = min.y; } else if ((outCode2 & OutCode.RIGHT) != 0) { val.y = val.y * max.x / val.x; val.x = max.x; } else if ((outCode2 & OutCode.LEFT) != 0) { val.y = val.y * min.x / val.x; val.x = min.x; } } val.z = Mathf.Clamp(val.z, min.z, max.z); return(val); }
public static (bool shouldDraw, Point p0, Point p1) ClipToScreen( IScreenBuffer buffer, Point p0, Point p1) { OutCode outCode0 = ComputeOutCode(p0, buffer.Dimensions); OutCode outCode1 = ComputeOutCode(p1, buffer.Dimensions); bool accept = false; while (true) { if ((outCode0 | outCode1) == OutCode.Inside) { accept = true; break; } if ((outCode0 & outCode1) != OutCode.Inside) { break; } int x = 0; int y = 0; OutCode outCodeOut = (outCode0 != OutCode.Inside) ? outCode0 : outCode1; if ((outCodeOut & OutCode.Top) == OutCode.Top) { x = (int)(p0.X + (p1.X - p0.X) * (buffer.Dimensions.Y - p0.Y) / ((double)p1.Y - p0.Y)); y = buffer.Dimensions.Y; } else if ((outCodeOut & OutCode.Bottom) == OutCode.Bottom) { x = (int)(p0.X + (p1.X - p0.X) * -p0.Y / ((double)p1.Y - p0.Y)); y = 0; } else if ((outCodeOut & OutCode.Right) == OutCode.Right) { y = (int)(p0.Y + (p1.Y - p0.Y) * (buffer.Dimensions.X - p0.X) / ((double)p1.X - p0.X)); x = buffer.Dimensions.X; } else if ((outCodeOut & OutCode.Left) == OutCode.Left) { y = (int)(p0.Y + (p1.Y - p0.Y) * -p0.X / ((double)p1.X - p0.X)); x = 0; } if (outCodeOut == outCode0) { p0 = new Point(x, y); outCode0 = ComputeOutCode(p0, buffer.Dimensions); } else { p1 = new Point(x, y); outCode1 = ComputeOutCode(p1, buffer.Dimensions); } } return(accept, p0, p1); }
private static PointF CountIntersec(RectangleF r, PointF poi1, PointF poi2, OutCode clipTo) { var dx = poi2.X - poi1.X; var dy = poi2.Y - poi1.Y; var slopeY = dx / dy; // slope to use for possibly-vertical lines var slopeX = dy / dx; // slope to use for possibly-horizontal lines if (clipTo.HasFlag(OutCode.Top)) { return(new PointF(poi1.X + slopeY * (r.Top - poi1.Y), r.Top)); } if (clipTo.HasFlag(OutCode.Bottom)) { return(new PointF(poi1.X + slopeY * (r.Bottom - poi1.Y), r.Bottom)); } if (clipTo.HasFlag(OutCode.Right)) { return(new PointF(r.Right, poi1.Y + slopeX * (r.Right - poi1.X))); } if (clipTo.HasFlag(OutCode.Left)) { return(new PointF(r.Left, poi1.Y + slopeX * (r.Left - poi1.X))); } throw new ArgumentOutOfRangeException("clipTo = " + clipTo); }
private bool line_clip(ref Vector2 startPoint, ref Vector2 endPoint) { OutCode startOutcode = new OutCode(startPoint); OutCode endOutcode = new OutCode(endPoint); if (triviallyAccept(startOutcode, endOutcode)) { return(true); } if (triviallyReject(startOutcode, endOutcode)) { return(false); } for (int udlr = 0; udlr < 4; udlr++) { if (startOutcode.udlr[udlr]) { startPoint = lineIntercept(startPoint, endPoint, udlr); if (new OutCode(startPoint) == new OutCode())// new point in viewport { return(line_clip(ref endPoint, ref startPoint)); } } } return(true); }
private static OutCode addTwoOutCode(OutCode firstP, OutCode secondP) { bool u = firstP.u && secondP.u; bool d = firstP.d && secondP.d; bool l = firstP.l && secondP.l; bool r = firstP.r && secondP.r; return(new OutCode(u, d, l, r)); }
private static OutCode ComputeOutCode(Vector3 euler, Vector3 min, Vector3 max) { OutCode outCode = OutCode.INSIDE; if (euler.x < min.x) { outCode |= OutCode.LEFT; } else if (euler.x > max.x) { outCode |= OutCode.RIGHT; } if (euler.y < min.y) { outCode |= OutCode.BOTTOM; } else if (euler.y > max.y) { outCode |= OutCode.TOP; } if (!IsPowerOfTwoOrZero(outCode)) { float num = euler.y / euler.x; switch (outCode) { case OutCode.LEFT | OutCode.TOP: { float num4 = (0f - max.y) / max.x; outCode = ((num > num4) ? OutCode.LEFT : OutCode.TOP); break; } case OutCode.RIGHT | OutCode.TOP: { float num3 = max.y / max.x; outCode = ((!(num > num3)) ? OutCode.RIGHT : OutCode.TOP); break; } case OutCode.LEFT | OutCode.BOTTOM: { float num5 = max.y / max.x; outCode = ((!(num > num5)) ? OutCode.LEFT : OutCode.BOTTOM); break; } case OutCode.RIGHT | OutCode.BOTTOM: { float num2 = (0f - max.y) / max.x; outCode = ((!(num > num2)) ? OutCode.BOTTOM : OutCode.RIGHT); break; } } } return(outCode); }
public static bool isTriviallyReject(OutCode firstP, OutCode secondP) { /* * bool res = false; * * if (sum.u | sum.d | sum.l | sum.r) * res = true; */ return(addTwoOutCode(firstP, secondP) != new OutCode(false)); }
//Trivially Accept/Reject public static bool isTriviallyAccept(OutCode firstP, OutCode secondP) { /* * bool res = false; * * if (!(firstP.u | firstP.d | firstP.l | firstP.r | secondP.u | secondP.d | secondP.l | secondP.r)) * res = true; */ return(firstP == new OutCode(false) && secondP == new OutCode(false)); }
/// <summary> /// Clips a line. /// </summary> /// <param name="first">The first coordinate of the line.</param> /// <param name="second">The second coordinate of the line.</param> /// <param name="window">The clipping window.</param> /// <returns>The clipped line.</returns> private static Coordinate[] Clip(Coordinate first, Coordinate second, Envelope window) { if (first == null || second == null) { return(null); } Boolean accept = false; OutCode outCodeFirst = ComputeOutCode(first, window); OutCode outCodeSecond = ComputeOutCode(second, window); while (!accept) { if ((outCodeFirst | outCodeSecond) == OutCode.Inside) { accept = true; break; } if ((outCodeFirst & outCodeSecond) != 0) { break; } OutCode outCode = outCodeFirst != OutCode.Inside ? outCodeFirst : outCodeSecond; Coordinate intersectionCoordinate = ComputeIntersection(first, second, window, outCode); if (outCode == outCodeFirst) { first = intersectionCoordinate; outCodeFirst = ComputeOutCode(first, window); } if (outCode == outCodeSecond) { second = intersectionCoordinate; outCodeSecond = ComputeOutCode(second, window); } } if (accept) { return new Coordinate[] { first, second } } ; return(null); }
public void ClipSegment(RectangleF r, Point p1, Point p2) { new Bresenham().Algorithm(p1, p2, "LightGray"); OutCode outCodeP1 = ComputeOutCode(p1, r); OutCode outCodeP2 = ComputeOutCode(p2, r); bool accept = false; while (true) { if ((outCodeP1 | outCodeP2) == OutCode.Inside) { accept = true; break; } else if ((outCodeP1 & outCodeP2) != 0) { break; } else { OutCode outcodeOut = outCodeP1 != OutCode.Inside ? outCodeP1 : outCodeP2; Point p = ComputeIntersection(r, p1, p2, outcodeOut); if (outcodeOut == outCodeP1) { p1 = p; outCodeP1 = ComputeOutCode(p1, r); } else { p2 = p; outCodeP2 = ComputeOutCode(p2, r); } } } if (accept) { new Bresenham().Algorithm(p1, p2, "Green"); } else { return; } }
/// <summary> /// Returns the orientation with which the given point lies outside of the given /// rectangle. /// </summary> /// <param name="p">The point to compare against the rectangle.</param> /// <param name="r">The rectangle to compare against the point.</param> /// <returns></returns> public static OutCode RectangleOutCode(PointF p, RectangleF r) { OutCode outCode = OutCode.None; if (p.X < r.Left) { outCode |= OutCode.Left; } if (p.X > r.Right) { outCode |= OutCode.Right; } if (p.Y < r.Top) { outCode |= OutCode.Top; } if (p.Y > r.Bottom) { outCode |= OutCode.Bottom; } return(outCode); }
private static Point ComputeIntersection(RectangleF r, Point p1, Point p2, OutCode clipTo) { var dx = (p2.X - p1.X); var dy = (p2.Y - p1.Y); var slopeY = dx / (dy + 0.000001); // slope to use for possibly-vertical lines var slopeX = dy / (dx + 0.000001); // slope to use for possibly-horizontal lines if (clipTo.HasFlag(OutCode.Top)) { return(new Point( Convert.ToInt32(p1.X + slopeY * (r.Top - p1.Y)), Convert.ToInt32((r.Top)) )); } if (clipTo.HasFlag(OutCode.Bottom)) { return(new Point( Convert.ToInt32(p1.X + slopeY * (r.Bottom - p1.Y)), Convert.ToInt32(r.Bottom) )); } if (clipTo.HasFlag(OutCode.Right)) { return(new Point( Convert.ToInt32(r.Right), Convert.ToInt32(p1.Y + slopeX * (r.Right - p1.X)) )); } if (clipTo.HasFlag(OutCode.Left)) { return(new Point( Convert.ToInt32(r.Left), Convert.ToInt32(p1.Y + slopeX * (r.Left - p1.X)) )); } throw new ArgumentOutOfRangeException("clipTo = " + clipTo); }
private Vector2 CalculateIntersection(Vector2 p1, Vector2 p2, OutCode clipTo) { var dx = p2.X - p1.X; var dy = p2.Y - p1.Y; var slopeY = dx / dy; // slope to use for possibly-vertical lines var slopeX = dy / dx; // slope to use for possibly-horizontal lines if (clipTo.HasFlag(OutCode.Top)) { return(new Vector2( p1.X + slopeY * (this.Top - p1.Y), this.Top)); } if (clipTo.HasFlag(OutCode.Bottom)) { return(new Vector2( p1.X + slopeY * (this.Bottom - p1.Y), this.Bottom)); } if (clipTo.HasFlag(OutCode.Right)) { return(new Vector2( this.Right, p1.Y + slopeX * (this.Right - p1.X))); } if (clipTo.HasFlag(OutCode.Left)) { return(new Vector2( this.Left, p1.Y + slopeX * (this.Left - p1.X))); } throw new ArgumentOutOfRangeException("clipTo = " + clipTo); }
private static Point CalculateIntersection(Rect r, Point p1, Point p2, OutCode clipTo) { var dx = (p2.X - p1.X); var dy = (p2.Y - p1.Y); var slopeY = dx / dy; // slope to use for possibly-vertical lines var slopeX = dy / dx; // slope to use for possibly-horizontal lines if (clipTo.HasFlag(OutCode.Top)) { return(new Point( p1.X + slopeY * (r.Top - p1.Y), r.Top )); } if (clipTo.HasFlag(OutCode.Bottom)) { return(new Point( p1.X + slopeY * (r.Bottom - p1.Y), r.Bottom )); } if (clipTo.HasFlag(OutCode.Right)) { return(new Point( r.Right, p1.Y + slopeX * (r.Right - p1.X) )); } if (clipTo.HasFlag(OutCode.Left)) { return(new Point( r.Left, p1.Y + slopeX * (r.Left - p1.X) )); } throw new ArgumentOutOfRangeException("clipTo = " + clipTo); }
static OutCode ComputeOutCode(Point p, Point bounds) { OutCode code = OutCode.Inside; if (p.X < 0) { code |= OutCode.Left; } else if (p.X > bounds.X) { code |= OutCode.Right; } if (p.Y < 0) { code |= OutCode.Bottom; } else if (p.Y > bounds.Y) { code |= OutCode.Top; } return(code); }
/// <summary> /// Compute the bit code of a coordinate. /// </summary> /// <param name="x">The X coordinate.</param> /// <param name="y">The Y coordinate.</param> /// <param name="window">The clipping window.</param> /// <returns>The computed bitcode.</returns> private static OutCode ComputeOutCode(Double x, Double y, Envelope window) { OutCode code = OutCode.Inside; if (x < window.MinX) { code |= OutCode.Left; } if (x > window.MaxX) { code |= OutCode.Right; } if (y < window.MinY) { code |= OutCode.Top; } if (y > window.MaxY) { code |= OutCode.Bottom; } return(code); }
public string this[string columnName] { get { string result = null; if (columnName == "OutType") { if (OutType == null) { result = "OutType not supplied."; } } if (columnName == "OutCode") { if (OutCode != null && OutCode.ToString().Length > 8) { result = "OutCode exceeds maximum length (8 digits)."; //OutCode = (int?)int.Parse(OutCode.ToString().Substring(0, 8)); } } return(result); } }
// 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. private static OutCode ComputeOutCode(double x, double y, ref RectangleInt tileScreenBoundingBox) { OutCode code = OutCode.Inside; if (x < tileScreenBoundingBox.XMin) // to the left of clip window { code |= OutCode.Left; } else if (x > tileScreenBoundingBox.XMax) // to the right of clip window { code |= OutCode.Right; } if (y < tileScreenBoundingBox.YMin) // below the clip window { code |= OutCode.Bottom; } else if (y > tileScreenBoundingBox.YMax) // above the clip window { code |= OutCode.Top; } return(code); }
// Compute the bit code for a point (x, y) using the clip rectangle // bounded diagonally by (xmin, ymin), and (xmax, ymax) static OutCode ComputeOutCode(Rect rect, float x, float y) { OutCode code = OutCode.Inside; // initialised as being inside of [[clip window]] if (x < rect.xMin) // to the left of clip window { code |= OutCode.Left; } else if (x > rect.xMax) // to the right of clip window { code |= OutCode.Right; } if (y < rect.yMin) // below the clip window { code |= OutCode.Bottom; } else if (y > rect.yMax) // above the clip window { code |= OutCode.Top; } return(code); }
public string this[string columnName] { get { string result = null; if (columnName == "OutType") { if (OutType == null) { result = "OutType not supplied."; } } if (columnName == "ULN") { if (OutCode != null && OutCode.ToString().Length > 9) { result = "OutCode Number exceeds maximum length (9 digits)."; } } return(result); } }
// 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). internal static bool RectContainsLineSegment(Rect rect, float x0, float y0, float x1, float y1) { // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle OutCode outcode0 = ComputeOutCode(rect, x0, y0); OutCode outcode1 = ComputeOutCode(rect, x1, y1); bool accept = false; while (true) { if ((outcode0 | outcode1) == OutCode.Inside) { // bitwise OR is 0: both points inside window; trivially accept and exit loop accept = true; break; } else if ((outcode0 & outcode1) != OutCode.Inside) { // bitwise AND is not 0: both points share an outside zone (LEFT, RIGHT, TOP, // or BOTTOM), so both must be outside window; exit loop (accept is false) break; } else { // failed both tests, so calculate the line segment to clip // from an outside point to an intersection with clip edge float x = 0f, y = 0f; // At least one endpoint is outside the clip rectangle; pick it. OutCode outcodeOut = outcode0 != OutCode.Inside ? outcode0 : outcode1; // Now find the intersection point; // use formulas: // slope = (y1 - y0) / (x1 - x0) // x = x0 + (1 / slope) * (ym - y0), where ym is ymin or ymax // y = y0 + slope * (xm - x0), where xm is xmin or xmax // No need to worry about divide-by-zero because, in each case, the // outcode bit being tested guarantees the denominator is non-zero if ((outcodeOut & OutCode.Top) == OutCode.Top) { // point is above the clip window x = x0 + (x1 - x0) * (rect.yMax - y0) / (y1 - y0); y = rect.yMax; } else if ((outcodeOut & OutCode.Bottom) == OutCode.Bottom) { // point is below the clip window x = x0 + (x1 - x0) * (rect.yMin - y0) / (y1 - y0); y = rect.yMin; } else if ((outcodeOut & OutCode.Right) == OutCode.Right) { // point is to the right of clip window y = y0 + (y1 - y0) * (rect.xMax - x0) / (x1 - x0); x = rect.xMax; } else if ((outcodeOut & OutCode.Left) == OutCode.Left) { // point is to the left of clip window y = y0 + (y1 - y0) * (rect.xMin - x0) / (x1 - x0); x = rect.xMin; } // 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(rect, x0, y0); } else { x1 = x; y1 = y; outcode1 = ComputeOutCode(rect, x1, y1); } } } return(accept); }
/// <summary> /// Computes the intersection of a line. /// </summary> /// <param name="first">The first coordinate of the line.</param> /// <param name="second">The second coordinate of the line.</param> /// <param name="window">The clipping window.</param> /// <param name="clipTo">Location of first coordinate in relation to the region of interest.</param> /// <returns>The intersection coordinate.</returns> /// <exception cref="System.ArgumentException">The code is invalid.</exception> private static Coordinate ComputeIntersection(Coordinate first, Coordinate second, Envelope window, OutCode clipTo) { Double dx = second.X - first.X; Double dy = second.Y - first.Y; Double slopeY = dx / dy; Double slopeX = dy / dx; if (clipTo.HasFlag(OutCode.Top)) { return(new Coordinate(first.X + slopeY * (window.MaxY - first.Y), window.MaxY)); } if (clipTo.HasFlag(OutCode.Bottom)) { return(new Coordinate(first.X + slopeY * (window.MinY - first.Y), window.MinY)); } if (clipTo.HasFlag(OutCode.Right)) { return(new Coordinate(window.MaxX, first.Y + slopeX * (window.MaxX - first.X))); } if (clipTo.HasFlag(OutCode.Left)) { return(new Coordinate(window.MinX, first.Y + slopeX * (window.MinX - first.X))); } return(Coordinate.Undefined); }
/// <summary> /// Computes the intersection of a line. /// </summary> /// <param name="first">The first coordinate of the line.</param> /// <param name="second">The second coordinate of the line.</param> /// <param name="window">The clipping window.</param> /// <param name="clipTo">Location of first coordinate in relation to the region of interest.</param> /// <returns>The intersection coordinate.</returns> /// <exception cref="System.ArgumentException">The code is invalid.</exception> private static Coordinate ComputeIntersection(Coordinate first, Coordinate second, Envelope window, OutCode clipTo) { Double dx = (second.X - first.X); Double dy = (second.Y - first.Y); Double slopeY = dx / dy; Double slopeX = dy / dx; if (clipTo.HasFlag(OutCode.Top)) { return(new Coordinate( first.X + slopeY * (window.MaxY - first.Y), window.MaxY )); } if (clipTo.HasFlag(OutCode.Bottom)) { return(new Coordinate( first.X + slopeY * (window.MinY - first.Y), window.MinY )); } if (clipTo.HasFlag(OutCode.Right)) { return(new Coordinate( window.MaxX, first.Y + slopeX * (window.MaxX - first.X) )); } if (clipTo.HasFlag(OutCode.Left)) { return(new Coordinate( window.MinX, first.Y + slopeX * (window.MinX - first.X) )); } throw new ArgumentException("The code is invalid.", "clipTo"); }
private static bool IsPowerOfTwoOrZero(OutCode x) { return((x & (x - 1)) == 0); }
public static bool triviallyAccept(OutCode a, OutCode b) { return(a == new OutCode() && b == new OutCode()); }
public static Vector2 LineIntersect(this Rect rect, Vector2 outSidePoint, Vector2 insidePoint) { OutCode outcode0 = ComputeOutCode(outSidePoint.x, outSidePoint.y, rect); OutCode outcode1 = ComputeOutCode(insidePoint.x, insidePoint.y, rect); while (true) { if ((outcode0 | outcode1) == OutCode.INSIDE) { // Bitwise OR is 0. Trivially accept and get out of loop break; } else if ((outcode0 & outcode1) != 0) { // Bitwise AND is not 0. Trivially reject and get out of loop break; } else { // failed both tests, so calculate the line segment to clip // from an outside point to an intersection with clip edge float x = 0, y = 0; // At least one endpoint is outside the clip rectangle; pick it. OutCode 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 & OutCode.TOP) == OutCode.TOP) { // point is above the clip rectangle x = outSidePoint.x + (insidePoint.x - outSidePoint.x) * (rect.yMax - outSidePoint.y) / (insidePoint.y - outSidePoint.y); y = rect.yMax; } else if ((outcodeOut & OutCode.BOTTOM) == OutCode.BOTTOM) { // point is below the clip rectangle x = outSidePoint.x + (insidePoint.x - outSidePoint.x) * (rect.yMin - outSidePoint.y) / (insidePoint.y - outSidePoint.y); y = rect.yMin; } else if ((outcodeOut & OutCode.RIGHT) == OutCode.RIGHT) { // point is to the right of clip rectangle y = outSidePoint.y + (insidePoint.y - outSidePoint.y) * (rect.xMax - outSidePoint.x) / (insidePoint.x - outSidePoint.x); x = rect.xMax; } else if ((outcodeOut & OutCode.LEFT) == OutCode.LEFT) { // point is to the left of clip rectangle y = outSidePoint.y + (insidePoint.y - outSidePoint.y) * (rect.xMin - outSidePoint.x) / (insidePoint.x - outSidePoint.x); x = rect.xMin; } // Now we move outside point to intersection point to clip // and get ready for next pass. if (outcodeOut == outcode0) { outSidePoint.x = x; outSidePoint.y = y; outcode0 = ComputeOutCode(outSidePoint.x, outSidePoint.y, rect); } else { insidePoint.x = x; insidePoint.y = y; outcode1 = ComputeOutCode(insidePoint.x, insidePoint.y, rect); } } } return(outSidePoint); }
// Use this for initialization void Start() { //TEST for OutCode class //Trivially Accept print("================================"); print("NEW POINT :"); Vector2 temp1 = new Vector2(0.5f, 0.3f); Vector2 temp2 = new Vector2(0.5f, -0.9f); Vector2[] temp_res = new Vector2[2]; temp_res = OutCode.LineClipping(temp1, temp2); print("Point 1 : x = " + temp_res[0].x + " , y = " + temp_res[0].y); print("Point 1 : x = " + temp_res[1].x + " , y = " + temp_res[1].y); //Trivially Reject print("================================"); print("NEW POINT :"); temp1.x = 1.5f; temp1.y = 0.1f; temp2.x = 1.5f; temp2.y = 2f; temp_res = OutCode.LineClipping(temp1, temp2); print("Point 1 : x = " + temp_res[0].x + " , y = " + temp_res[0].y); print("Point 1 : x = " + temp_res[1].x + " , y = " + temp_res[1].y); //Not accept, reject and outside the screen print("================================"); print("NEW POINT :"); temp1.x = 15f; temp1.y = 0f; temp2.x = 0f; temp2.y = 15f; temp_res = OutCode.LineClipping(temp1, temp2); print("Point 1 : x = " + temp_res[0].x + " , y = " + temp_res[0].y); print("Point 1 : x = " + temp_res[1].x + " , y = " + temp_res[1].y); //Not accept, reject and inside the screen print("================================"); print("NEW POINT :"); temp1.x = 0f; temp1.y = 1.2f; temp2.x = -1.3f; temp2.y = -1.4f; temp_res = OutCode.LineClipping(temp1, temp2); print("Point 1 : x = " + temp_res[0].x + " , y = " + temp_res[0].y); print("Point 1 : x = " + temp_res[1].x + " , y = " + temp_res[1].y); //============================== //Test For the Rasterisation Rasterisation screen = new Rasterisation(64, 36); List <Vector2> result = new List <Vector2>(); //Test for normal case print("================================"); print("NEW RASTERISATION :"); temp1 = new Vector2(-1f, 1f); temp2 = new Vector2(1f, -1f); temp1 = Rasterisation.ViewPortToPixelSpacePointCoord(temp1, screen); temp2 = Rasterisation.ViewPortToPixelSpacePointCoord(temp2, screen); print("x0 : " + temp1.x + " , y0 : " + temp1.y); print("x1 : " + temp2.x + " , y1 : " + temp2.y); result = Rasterisation.Breshenhams(temp1, temp2); for (int i = 0; i < result.Count; i++) { print("x : " + result[i].x + " , y : " + result[i].y); } //Test for negate case print("================================"); print("NEW RASTERISATION :"); temp1 = new Vector2(-1f, -1f); temp2 = new Vector2(1f, 1f); temp1 = Rasterisation.ViewPortToPixelSpacePointCoord(temp1, screen); temp2 = Rasterisation.ViewPortToPixelSpacePointCoord(temp2, screen); print("x0 : " + temp1.x + " , y0 : " + temp1.y); print("x1 : " + temp2.x + " , y1 : " + temp2.y); result = Rasterisation.Breshenhams(temp1, temp2); for (int i = 0; i < result.Count; i++) { print("x : " + result[i].x + " , y : " + result[i].y); } //Test for swap case print("================================"); print("NEW RASTERISATION :"); temp1 = new Vector2(0f, 1f); temp2 = new Vector2(1f, -1f); temp1 = Rasterisation.ViewPortToPixelSpacePointCoord(temp1, screen); temp2 = Rasterisation.ViewPortToPixelSpacePointCoord(temp2, screen); print("x0 : " + temp1.x + " , y0 : " + temp1.y); print("x1 : " + temp2.x + " , y1 : " + temp2.y); result = Rasterisation.Breshenhams(temp1, temp2); for (int i = 0; i < result.Count; i++) { print("x : " + result[i].x + " , y : " + result[i].y); } //Test for negate swap case print("================================"); print("NEW RASTERISATION :"); temp1 = new Vector2(0f, -1f); temp2 = new Vector2(1f, 1f); temp1 = Rasterisation.ViewPortToPixelSpacePointCoord(temp1, screen); temp2 = Rasterisation.ViewPortToPixelSpacePointCoord(temp2, screen); print("x0 : " + temp1.x + " , y0 : " + temp1.y); print("x1 : " + temp2.x + " , y1 : " + temp2.y); result = Rasterisation.Breshenhams(temp1, temp2); for (int i = 0; i < result.Count; i++) { print("x : " + result[i].x + " , y : " + result[i].y); } }
/// <summary> /// Cohen–Sutherland clipping algorithm clips a line from P0 = (x0, y0) to P1 = (x1, y1) against a clipBounds rectangle /// </summary> /// <param name="x0"></param> /// <param name="y0"></param> /// <param name="x1"></param> /// <param name="y1"></param> /// <param name="tileScreenBoundingBox"></param> /// <param name="clipState"> state of clipped line. ClipState.None if line is not clipped. If either end of the line /// is clipped then the clipState flag are set (ClipState.Start or ClipState.End) </param> /// <returns>true if clipped line is inside given clip bounds</returns> private static bool CohenSutherlandLineClip(ref double x0, ref double y0, ref double x1, ref double y1, ref RectangleInt tileScreenBoundingBox, out ClipState clipState) { // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle OutCode outcode0 = ComputeOutCode(x0, y0, ref tileScreenBoundingBox); OutCode outcode1 = ComputeOutCode(x1, y1, ref tileScreenBoundingBox); bool accept = false; clipState = ClipState.None; while (true) { if ((outcode0 | outcode1) == OutCode.Inside) { // bitwise OR is 0: both points inside window; trivially accept and exit loop accept = true; break; } else if ((outcode0 & outcode1) != OutCode.Inside) { // bitwise AND is not 0: both points share an outside zone (LEFT, RIGHT, TOP, // or BOTTOM), so both must be outside window; exit loop (accept is false) break; } else { // failed both tests, so calculate the line segment to clip // from an outside point to an intersection with clip edge double x = 0, y = 0; // At least one endpoint is outside the clip rectangle; pick it. OutCode outcodeOut = outcode0 != OutCode.Inside ? outcode0 : outcode1; // Now find the intersection point; // use formulas: // slope = (y1 - y0) / (x1 - x0) // x = x0 + (1 / slope) * (ym - y0), where ym is ymin or ymax // y = y0 + slope * (xm - x0), where xm is xmin or xmax // No need to worry about divide-by-zero because, in each case, the // outcode bit being tested guarantees the denominator is non-zero if ((outcodeOut & OutCode.Top) == OutCode.Top) { // point is above the clip window x = x0 + (x1 - x0) * (tileScreenBoundingBox.YMax - y0) / (y1 - y0); y = tileScreenBoundingBox.YMax; } else if ((outcodeOut & OutCode.Bottom) == OutCode.Bottom) { // point is below the clip window x = x0 + (x1 - x0) * (tileScreenBoundingBox.YMin - y0) / (y1 - y0); y = tileScreenBoundingBox.YMin; // ymin; } else if ((outcodeOut & OutCode.Right) == OutCode.Right) { // point is to the right of clip window y = y0 + (y1 - y0) * (tileScreenBoundingBox.XMax - x0) / (x1 - x0); x = tileScreenBoundingBox.XMax; // xmax; } else if ((outcodeOut & OutCode.Left) == OutCode.Left) { // point is to the left of clip window y = y0 + (y1 - y0) * (tileScreenBoundingBox.XMin - x0) / (x1 - x0); x = tileScreenBoundingBox.XMin; // xmin; } // Now we move outside point to intersection point to clip // and get ready for next pass. if (outcodeOut == outcode0) { clipState |= ClipState.Start; x0 = x; y0 = y; outcode0 = ComputeOutCode(x0, y0, ref tileScreenBoundingBox); } else { clipState |= ClipState.End; x1 = x; y1 = y; outcode1 = ComputeOutCode(x1, y1, ref tileScreenBoundingBox); } } } return(accept); }
public static bool triviallyReject(OutCode a, OutCode b) { return((a & b) != new OutCode()); }