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);
            }
        }
コード例 #2
0
ファイル: CohenSutherland.cs プロジェクト: amitprakash07/dx11
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
    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);
    }
コード例 #7
0
    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));
    }
コード例 #8
0
        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);
        }
コード例 #9
0
    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));
    }
コード例 #10
0
    //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));
    }
コード例 #11
0
        /// <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);
        }
コード例 #12
0
        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;
            }
        }
コード例 #13
0
        /// <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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        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);
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        /// <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);
        }
コード例 #19
0
 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);
     }
 }
コード例 #20
0
        // 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);
        }
コード例 #21
0
        // 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);
        }
コード例 #22
0
        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);
            }
        }
コード例 #23
0
        // 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);
        }
コード例 #24
0
        /// <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);
        }
コード例 #25
0
        /// <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");
        }
コード例 #26
0
 private static bool IsPowerOfTwoOrZero(OutCode x)
 {
     return((x & (x - 1)) == 0);
 }
コード例 #27
0
 public static bool triviallyAccept(OutCode a, OutCode b)
 {
     return(a == new OutCode() && b == new OutCode());
 }
コード例 #28
0
ファイル: ExtensionsRect.cs プロジェクト: settamaF/PixelGame
    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);
    }
コード例 #29
0
    // 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);
        }
    }
コード例 #30
0
        /// <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);
        }
コード例 #31
0
 public static bool triviallyReject(OutCode a, OutCode b)
 {
     return((a & b) != new OutCode());
 }