/// <summary>
        /// Инициализировать буферы и списки
        /// </summary>
        void InitializeData(ConvexHullComputationConfig config)
        {
            UnprocessedFaces = new FaceList();
            ConvexFaces      = new IndexBuffer();

            FacePool          = new ConvexFaceInternal[(Dimension + 1) * 10]; // Должен быть инициализирован перед менеджером объектов
            AffectedFaceFlags = new bool[(Dimension + 1) * 10];
            ObjectManager     = new ObjectManager(this);

            Center             = new double[Dimension];
            TraverseStack      = new IndexBuffer();
            UpdateBuffer       = new int[Dimension];
            UpdateIndices      = new int[Dimension];
            EmptyBuffer        = new IndexBuffer();
            AffectedFaceBuffer = new IndexBuffer();
            ConeFaceBuffer     = new SimpleList <DeferredFace>();
            SingularVertices   = new HashSet <int>();
            BeyondBuffer       = new IndexBuffer();

            ConnectorTable = new ConnectorList[ConnectorTableSize];
            for (int i = 0; i < ConnectorTableSize; i++)
            {
                ConnectorTable[i] = new ConnectorList();
            }

            VertexMarks = new bool[Vertices.Length];
            InitializePositions(config);

            MathHelper = new MathHelper(Dimension, Positions);
        }
        /// <summary>
        /// Обертка вершины и определения размера, если он неизвесен
        /// </summary>
        private ConvexHullInternal(IVertex[] vertices, bool lift, ConvexHullComputationConfig config)
        {
            if (config.PointTranslationType != PointTranslationType.None && config.PointTranslationGenerator == null)
            {
                throw new InvalidOperationException("PointTranslationGenerator cannot be null if PointTranslationType is enabled.");
            }

            this.IsLifted = lift;
            this.Vertices = vertices;
            this.PlaneDistanceTolerance = config.PlaneDistanceTolerance;

            Dimension = DetermineDimension();
            if (Dimension < 2)
            {
                throw new InvalidOperationException("Dimension of the input must be 2 or greater.");
            }

            if (lift)
            {
                Dimension++;
            }
            InitializeData(config);
        }
        /// <summary>
        /// Проинициализируем позиции вершин на основе типа перевода от конфигурации
        /// </summary>
        void InitializePositions(ConvexHullComputationConfig config)
        {
            Positions = new double[Vertices.Length * Dimension];
            int index = 0;

            if (IsLifted)
            {
                var origDim = Dimension - 1;
                var tf      = config.PointTranslationGenerator;
                switch (config.PointTranslationType)
                {
                case PointTranslationType.None:
                    foreach (var v in Vertices)
                    {
                        double lifted = 0.0;
                        for (int i = 0; i < origDim; i++)
                        {
                            var t = v.Position[i];
                            Positions[index++] = t;
                            lifted            += t * t;
                        }
                        Positions[index++] = lifted;
                    }
                    break;

                case PointTranslationType.TranslateInternal:
                    foreach (var v in Vertices)
                    {
                        double lifted = 0.0;
                        for (int i = 0; i < origDim; i++)
                        {
                            var t = v.Position[i] + tf();
                            Positions[index++] = t;
                            lifted            += t * t;
                        }
                        Positions[index++] = lifted;
                    }
                    break;
                }
            }
            else
            {
                var tf = config.PointTranslationGenerator;
                switch (config.PointTranslationType)
                {
                case PointTranslationType.None:
                    foreach (var v in Vertices)
                    {
                        for (int i = 0; i < Dimension; i++)
                        {
                            Positions[index++] = v.Position[i];
                        }
                    }
                    break;

                case PointTranslationType.TranslateInternal:
                    foreach (var v in Vertices)
                    {
                        for (int i = 0; i < Dimension; i++)
                        {
                            Positions[index++] = v.Position[i] + tf();
                        }
                    }
                    break;
                }
            }
        }
Exemple #4
0
 /// <summary>
 /// Создает выпуклую оболочку из входных данных
 /// </summary>
 public static ConvexHull <TVertex, TFace> Create <TVertex, TFace>(IList <TVertex> data, ConvexHullComputationConfig config = null)
     where TVertex : IVertex
     where TFace : ConvexFace <TVertex, TFace>, new()
 {
     return(ConvexHull <TVertex, TFace> .Create(data, config));
 }
        /// <summary>
        /// Класс выпуклой оболочки
        /// </summary>
        internal static ConvexHull <TVertex, TFace> GetConvexHull <TVertex, TFace>(IList <TVertex> data, ConvexHullComputationConfig config)
            where TFace : ConvexFace <TVertex, TFace>, new()
            where TVertex : IVertex
        {
            config = config ?? new ConvexHullComputationConfig();

            var vertices = new IVertex[data.Count];

            for (int i = 0; i < data.Count; i++)
            {
                vertices[i] = data[i];
            }
            ConvexHullInternal ch = new ConvexHullInternal(vertices, false, config);

            ch.FindConvexHull();

            var hull = ch.GetHullVertices(data);

            return(new ConvexHull <TVertex, TFace> {
                Points = hull, Faces = ch.GetConvexFaces <TVertex, TFace>()
            });
        }