Beispiel #1
0
        public static bool Create(IList <Vector2> vertices, float epsilon, out int dimension, out int[] indices)
        {
            Vector2ex.Information information = Vector2ex.GetInformation(vertices, epsilon);
            if (information == null)
            {
                dimension = -1;
                indices   = null;
                return(false);
            }
            int count = vertices.Count;

            if (information.Dimension == 0)
            {
                dimension = 0;
                int[] array = new int[1];
                indices = array;
                return(true);
            }
            if (information.Dimension == 1)
            {
                float[] array2 = new float[count];
                Vector2 origin = information.Origin;
                Vector2 vector = information.Direction[0];
                for (int i = 0; i < count; i++)
                {
                    Vector2 value = vertices[i] - origin;
                    array2[i] = vector.Dot(value);
                }
                ConvexHull1.Create(array2, epsilon, out dimension, out indices);
                return(true);
            }
            dimension = 2;
            Vector2[] array3 = new Vector2[count];
            Vector2   min    = information.Min;
            float     d      = 1f / information.MaxRange;

            for (int j = 0; j < count; j++)
            {
                array3[j] = (vertices[j] - min) * d;
            }
            Query2 query = new Query2(array3);
            int    num   = information.Extreme[0];
            int    num2  = information.Extreme[1];
            int    num3  = information.Extreme[2];

            ConvexHull2.Edge edge;
            ConvexHull2.Edge edge2;
            ConvexHull2.Edge edge3;
            if (information.ExtremeCCW)
            {
                edge  = new ConvexHull2.Edge(num, num2);
                edge2 = new ConvexHull2.Edge(num2, num3);
                edge3 = new ConvexHull2.Edge(num3, num);
            }
            else
            {
                edge  = new ConvexHull2.Edge(num, num3);
                edge2 = new ConvexHull2.Edge(num3, num2);
                edge3 = new ConvexHull2.Edge(num2, num);
            }
            edge.Insert(edge3, edge2);
            edge2.Insert(edge, edge3);
            edge3.Insert(edge2, edge);
            ConvexHull2.Edge edge4 = edge;
            for (int k = 0; k < count; k++)
            {
                if (!ConvexHull2.Update(ref edge4, k, query))
                {
                    dimension = -1;
                    indices   = null;
                    return(false);
                }
            }
            edge4.GetIndices(out indices);
            return(true);
        }
        internal static Vector2ex.Information GetInformation(IList <Vector2> points, float epsilon)
        {
            if (points == null)
            {
                return(null);
            }
            int count = points.Count;

            if (count == 0 || epsilon < 0f)
            {
                return(null);
            }
            Vector2ex.Information information = new Vector2ex.Information();
            information.ExtremeCCW = false;
            float num2;
            float num  = num2 = points[0].x;
            int   num3 = 0;
            int   num4 = 0;
            float num6;
            float num5 = num6 = points[0].y;
            int   num7 = 0;
            int   num8 = 0;

            for (int i = 1; i < count; i++)
            {
                float num9 = points[i].x;
                if (num9 < num2)
                {
                    num2 = num9;
                    num3 = i;
                }
                else if (num9 > num)
                {
                    num  = num9;
                    num4 = i;
                }
                num9 = points[i].y;
                if (num9 < num6)
                {
                    num6 = num9;
                    num7 = i;
                }
                else if (num9 > num5)
                {
                    num5 = num9;
                    num8 = i;
                }
            }
            information.Min.x      = num2;
            information.Min.y      = num6;
            information.Max.x      = num;
            information.Max.y      = num5;
            information.MaxRange   = num - num2;
            information.Extreme[0] = num3;
            information.Extreme[1] = num4;
            float num10 = num5 - num6;

            if (num10 > information.MaxRange)
            {
                information.MaxRange   = num10;
                information.Extreme[0] = num7;
                information.Extreme[1] = num8;
            }
            information.Origin = points[information.Extreme[0]];
            if (information.MaxRange < epsilon)
            {
                information.Dimension    = 0;
                information.Extreme[1]   = information.Extreme[0];
                information.Extreme[2]   = information.Extreme[0];
                information.Direction[0] = Vector2ex.Zero;
                information.Direction[1] = Vector2ex.Zero;
                return(information);
            }
            information.Direction[0] = points[information.Extreme[1]] - information.Origin;
            information.Direction[0].Normalize();
            information.Direction[1] = -information.Direction[0].Perp();
            float num11 = 0f;
            float num12 = 0f;

            information.Extreme[2] = information.Extreme[0];
            for (int j = 0; j < count; j++)
            {
                Vector2 value = points[j] - information.Origin;
                float   num13 = information.Direction[1].Dot(value);
                float   num14 = Mathf.Sign(num13);
                num13 = Mathf.Abs(num13);
                if (num13 > num11)
                {
                    num11 = num13;
                    num12 = num14;
                    information.Extreme[2] = j;
                }
            }
            if (num11 < epsilon * information.MaxRange)
            {
                information.Dimension  = 1;
                information.Extreme[2] = information.Extreme[1];
                return(information);
            }
            information.Dimension  = 2;
            information.ExtremeCCW = (num12 > 0f);
            return(information);
        }