예제 #1
0
        private static bool LineToLine(Vertex2 vertex1, Vertex2 vertex2, Vertex2 vertex3, Vertex2 vertex4, out float r,
                                       out float s)
        {
            r = 0;
            s = 0;
            //Make sure the lines aren't parallel
            Vertex2 line1 = vertex2 - vertex1;
            Vertex2 line2 = vertex4 - vertex3;

            //if (vertex1to2.x * -vertex3to4.y + vertex1to2.y * vertex3to4.x != 0)
            //{
            //if (line1.y/line1.x != line2.y/line2.x)
            //{

            //}

            float d = PGUtils.PerpDot(line1, line2);

            if (d != 0)
            {
                Vertex2 vertex3to1 = vertex1 - vertex3;
                r = (vertex3to1.y * line2.x - vertex3to1.x * line2.y) / d;
                s = (vertex3to1.y * line1.x - vertex3to1.x * line1.y) / d;
                return(true);
            }
            else
            {
                //Parallel
            }

            return(false);
        }
예제 #2
0
        public static void BresenhamLine(int x0, int y0, int x1, int y1, Action <int, int> draw)
        {
            bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);

            if (steep)
            {
                PGUtils.Swap(ref x0, ref y0);
                PGUtils.Swap(ref x1, ref y1);
            }
            if (x0 > x1)
            {
                PGUtils.Swap(ref x0, ref x1);
                PGUtils.Swap(ref y0, ref y1);
            }
            int dx    = x1 - x0;
            int dy    = Math.Abs(y1 - y0);
            int error = dx / 2;
            int ystep = (y0 < y1) ? 1 : -1;
            int y     = y0;

            for (int x = x0; x <= x1; x++)
            {
                draw(steep ? y : x, steep ? x : y);
                error -= dy;
                if (error < 0)
                {
                    y     += ystep;
                    error += dx;
                }
            }
        }
예제 #3
0
 public bool Contains(Vertex2 point, out int wn)
 {
     wn = 0;
     for (int i = 0; i < Count; i++)
     {
         if (this[i].y <= point.y)
         {
             // start y <= P.y
             if (this[i + 1].y > point.y)                                        // an upward crossing
             {
                 if (PGUtils.LocatePointOnLine(this[i], this[i + 1], point) > 0) // P left of edge
                 {
                     ++wn;                                                       // have a valid up intersect
                 }
             }
         }
         else
         {
             // start y > P.y (no test needed)
             if (this[i + 1].y <= point.y)                                       // a downward crossing
             {
                 if (PGUtils.LocatePointOnLine(this[i], this[i + 1], point) < 0) // P right of edge
                 {
                     --wn;                                                       // have a valid down intersect
                 }
             }
         }
     }
     return(wn != 0);
 }
예제 #4
0
 public static void InvertTriangles(this Mesh mesh)
 {
     for (int i = 0; i < mesh.subMeshCount; i++)
     {
         var triangles = mesh.GetTriangles(i);
         for (int j = 0; j < triangles.Length; j += 3)
         {
             PGUtils.Swap(ref triangles[j], ref triangles[j + 1]);
         }
         mesh.SetTriangles(triangles, i);
     }
 }
예제 #5
0
        private static void WuLine(int x0, int y0, int x1, int y1, Action <int, int, float> draw)
        {
            bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);

            if (steep)
            {
                PGUtils.Swap(ref x0, ref y0);
                PGUtils.Swap(ref x1, ref y1);
            }
            if (x0 > x1)
            {
                PGUtils.Swap(ref x0, ref x1);
                PGUtils.Swap(ref y0, ref y1);
            }

            if (steep)
            {
                draw(y0, x0, 1);
                draw(y1, x1, 1);
            }
            else
            {
                draw(x0, y0, 1);
                draw(x1, y1, 1);
            }
            float dx       = x1 - x0;
            float dy       = y1 - y0;
            float gradient = dy / dx;
            float y        = y0 + gradient;

            for (var x = x0 + 1; x <= x1 - 1; x++)
            {
                if (steep)
                {
                    draw((int)y, x, 1 - (y - (int)y));
                    draw((int)y + 1, x, y - (int)y);
                }
                else
                {
                    draw(x, (int)y, 1 - (y - (int)y));
                    draw(x, (int)y + 1, y - (int)y);
                }
                y += gradient;
            }
        }
예제 #6
0
        public static Polygon RemoveCollinearVertices(Polygon polygon)
        {
            if (polygon.Count <= 3)
            {
                return(polygon);
            }

            var newPolygon = new Polygon();

            for (int i = 0; i < polygon.Count; i++)
            {
                if (PGUtils.LocatePointOnLine(polygon[i - 1], polygon[i + 1], polygon[i]) != 0)
                {
                    newPolygon.Add(polygon[i]);
                }
            }
            return(newPolygon);
        }
예제 #7
0
        public void ExtrudeRange(int startIndex, int endIndex, Vertex2 offset)
        {
            if (startIndex > endIndex)
            {
                PGUtils.Swap(ref startIndex, ref endIndex);
            }

            var startV = this[startIndex] + offset;
            var endV   = this[endIndex] + offset;

            if ((endIndex - startIndex) > 1)
            {
                for (int i = startIndex + 1; i < endIndex; i++)
                {
                    this[i] += offset;
                }
            }

            Insert(startIndex + 1, startV);
            Insert(endIndex + 1, endV);
        }
예제 #8
0
 public void Swap()
 {
     PGUtils.Swap(ref x, ref y);
 }
예제 #9
0
        /// <summary>
        /// Based on "Faster Line Segment Intersection" by Franklin Antonio, Graphics Gems III
        /// </summary>
        public static IntersectionType IntSegmentToIntSegmentE(int start0x, int start0y, int end0x, int end0y,
                                                               int start1x, int start1y, int end1x, int end1y, out IntSegment2 intersection, bool testBoundingBox = false)
        {
            intersection = new IntSegment2();
            int ax = end0x - start0x;
            int ay = end0y - start0y;
            int bx = start1x - end1x;
            int by = start1y - end1y;

            if (testBoundingBox)
            {
                // X bound box test
                int x1hi = end0x;
                int x1lo = start0x;
                if (ax < 0)
                {
                    x1lo = end0x;
                    x1hi = start0x;
                }
                if (bx > 0)
                {
                    if (x1hi < end1x || start1x < x1lo)
                    {
                        return(IntersectionType.None);
                    }
                }
                else
                {
                    if (x1hi < start1x || end1x < x1lo)
                    {
                        return(IntersectionType.None);
                    }
                }

                // Y bound box test
                int y1hi = end0y;
                int y1lo = start0y;
                if (ay < 0)
                {
                    y1lo = end0y;
                    y1hi = start0y;
                }
                if (by > 0)
                {
                    if (y1hi < end1y || start1y < y1lo)
                    {
                        return(IntersectionType.None);
                    }
                }
                else
                {
                    if (y1hi < start1y || end1y < y1lo)
                    {
                        return(IntersectionType.None);
                    }
                }
            }

            int cx          = start0x - start1x;
            int cy          = start0y - start1y;
            int denominator = ay * bx - ax * by; // Both denominator

            // Alpha tests
            int alphaNumerator = by * cx - bx * cy;

            if (denominator > 0)
            {
                if (alphaNumerator < 0 || alphaNumerator > denominator)
                {
                    return(IntersectionType.None);
                }
            }
            else
            {
                if (alphaNumerator > 0 || alphaNumerator < denominator)
                {
                    return(IntersectionType.None);
                }
            }
            // Beta tests
            int betaNumerator = ax * cy - ay * cx;

            if (denominator > 0)
            {
                if (betaNumerator < 0 || betaNumerator > denominator)
                {
                    return(IntersectionType.None);
                }
            }
            else
            {
                if (betaNumerator > 0 || betaNumerator < denominator)
                {
                    return(IntersectionType.None);
                }
            }

            // Compute intersection coordinates

            // Segments are parallel
            if (denominator == 0)
            {
                // Segments are noncollinear
                if (alphaNumerator != 0)
                {
                    return(IntersectionType.None);
                }

                // Make sure that start is before end on x axis
                if (start0x > end0x)
                {
                    PGUtils.Swap(ref start0x, ref end0x);
                    PGUtils.Swap(ref start0y, ref end0y);
                }
                if (start1x > end1x)
                {
                    PGUtils.Swap(ref start1x, ref end1x);
                    PGUtils.Swap(ref start1y, ref end1y);
                }

                int biggestStartX = start0x > start1x ? start0x : start1x;
                int smallestEndX  = end0x < end1x ? end0x : end1x;

                // Segments are collinear but not intersecting
                if (biggestStartX > smallestEndX)
                {
                    return(IntersectionType.None);
                }

                // Make sure that start is before end on y axis
                // Remember swap event to prevent mirroring of intersection segment later
                bool swappedY = false;
                if (start0y > end0y)
                {
                    PGUtils.Swap(ref start0x, ref end0x);
                    PGUtils.Swap(ref start0y, ref end0y);
                    swappedY = true;
                }
                if (start1y > end1y)
                {
                    PGUtils.Swap(ref start1x, ref end1x);
                    PGUtils.Swap(ref start1y, ref end1y);
                    swappedY = true;
                }

                int biggestStartY = start0y > start1y ? start0y : start1y;
                int smallestEndY  = end0y < end1y ? end0y : end1y;

                // Segments are collinear but not intersecting
                if (biggestStartY > smallestEndY)
                {
                    return(IntersectionType.None);
                }

                if (swappedY)
                {
                    intersection = new IntSegment2(biggestStartX, smallestEndY, smallestEndX, biggestStartY);
                }
                else
                {
                    intersection = new IntSegment2(biggestStartX, biggestStartY, smallestEndX, smallestEndY);
                }
                return(IntersectionType.Segment);
            }

            int numerator = alphaNumerator * ax;               // Numerator
            int x         = start0x + numerator / denominator; // Intersection x

            numerator = alphaNumerator * ay;
            int y = start0y + numerator / denominator; // Intersection y

            intersection = new IntSegment2(x, y, x, y);
            return(IntersectionType.Point);
        }