Пример #1
0
        private List <float> PrepareWeights(IList <Vector2> p)
        {
            var cnt     = p.Count;
            var weights = GlobalListPool <float> .Get(cnt);

            for (var i = 0; i < cnt; i++)
            {
                var ti = p[i].x;
                var wi = 1f;

                for (var j = 0; j < cnt; j++)
                {
                    if (j == i)
                    {
                        continue;
                    }

                    var tj = p[j].x;
                    wi *= ti - tj;
                }

                weights.Add(wi);
            }

            return(weights);
        }
Пример #2
0
        /// <summary>
        /// Builds a list using the initial element and a builder function.
        /// </summary>
        /// <typeparam name="T">The type of the list items.</typeparam>
        /// <param name="length">The target length of the list.</param>
        /// <param name="first">The first element.</param>
        /// <param name="next">A function generating a followup element.</param>
        /// <returns>Returns the generated list.</returns>
        public static List <T> CreateList <T>(int length, T first, Func <T, T> next)
        {
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(length), "Length must be non-negative.");
            }

            if (length == 0)
            {
                return(new List <T>());
            }

            var result = GlobalListPool <T> .Get(length);

            result.Add(first);
            var prev = first;

            for (var i = 1; i < length; i++)
            {
                var item = next(prev);
                prev = item;
                result.Add(item);
            }

            return(result);
        }
        /// <summary>
        /// Triangulates a list of vertices, interpreted as the vertices of a planar polygon in clockwise order.
        /// </summary>
        /// <param name="vertices">The vertices.</param>
        /// <param name="normal">The normal of the polygon, if not know, use the overload without normal.</param>
        public static int[] Triangulate(this IList <Vector3> vertices, Vector3 normal)
        {
            var output = GlobalListPool <int> .Get(vertices.Count * 3 - 2);

            vertices.Triangulate(normal, output);
            var result = output.ToArray();

            GlobalListPool <int> .Put(output);

            return(result);
        }
        /// <summary>
        /// Triangulates a list of vertices, interpreted as the vertices of a planar polygon in clockwise order.
        /// </summary>
        /// <param name="vertices">The vertices.</param>
        public static int[] TriangulateWithCuttingEars(this IList <Vector3> vertices)
        {
            var output = GlobalListPool <int> .Get(vertices.Count * 3 - 2);

            vertices.TriangulateWithCuttingEars(output);
            var result = output.ToArray();

            GlobalListPool <int> .Put(output);

            return(result);
        }
Пример #5
0
        /// <summary>
        /// Converts any enumerator to an array.
        /// </summary>
        /// <typeparam name="T">The item type.</typeparam>
        /// <param name="enumerator">The enumerator to convert.</param>
        /// <returns>Returns the resulting array.</returns>
        public static T[] ToArray <T>(this IEnumerator <T> enumerator)
        {
            var result = GlobalListPool <T> .Get();

            enumerator.CopyTo(result);
            var output = result.ToArray();

            GlobalListPool <T> .Put(result);

            return(output);
        }
Пример #6
0
        public PolynomialInterpolation2(IList <Vector2> dataPoints)
        {
            if (dataPoints == null)
            {
                throw new ArgumentNullException(nameof(dataPoints));
            }

            if (dataPoints.Count < 1)
            {
                throw new ArgumentException("At least one data point is required for a polynomial interpolation.", nameof(dataPoints));
            }

            this.coeff = GlobalListPool <float> .Get(dataPoints.Count);

            Prepare(dataPoints);
        }
Пример #7
0
        public PolynomialInterpolation(IList <Vector2> dataPoints)
        {
            if (dataPoints == null)
            {
                throw new ArgumentNullException(nameof(dataPoints));
            }

            if (dataPoints.Count < 1)
            {
                throw new ArgumentException("At least one data point is required for a polynomial interpolation.", nameof(dataPoints));
            }

            this.data = GlobalListPool <Vector3> .Get(dataPoints.Count);

            // Point order doesn't matter, so don't sort input
            PrepareData(dataPoints);
        }
Пример #8
0
        public Revelation(Board board, BoardCell cell, float revelationSpeed)
        {
            this.prevCells = GlobalListPool <BoardCell> .Get();

            this.buffer = GlobalListPool <BoardCell> .Get();

            this.followupActions = GlobalListPool <Action> .Get();

            this.RevelationSpeed = revelationSpeed;
            this.board           = board;

            cell.State = CellState.Revealed;
            prevCells.Add(cell);
            lastStep = Time.time;

            CallProvider.AddUpdateListener(DoUpdate);
        }
Пример #9
0
        private void Prepare(IList <Vector2> p)
        {
            var cnt     = p.Count;
            var tValues = GlobalListPool <float> .Get(cnt - 1);

            var w = PrepareWeights(p);

            var cof = 0f;

            for (var i = 0; i < cnt; i++)
            {
                coeff.Add(0f);
            }

            for (var i = 1; i < cnt; i++)
            {
                tValues.Add(p[i].x);
            }

            // First coefficient
            for (var i = 0; i < cnt; i++)
            {
                cof += p[i].y / w[i];
            }

            coeff[0] = cof;

            // Later coefficients
            for (var i = 0; i < cnt; i++)
            {
                var scale = p[i].y / w[i];

                for (var j = 1; j < cnt; j++)
                {
                    var sum = GetNProductSum(tValues, j);

                    coeff[j] += sum * scale;
                }

                if (i < cnt - 1)
                {
                    tValues[i] = p[i].x;
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Applies a filter on a list and returns the matches.
        /// </summary>
        /// <typeparam name="T">The item type.</typeparam>
        /// <param name="items">The list to search.</param>
        /// <param name="filter">The filter function.</param>
        /// <returns></returns>
        public static T[] Filter <T>(this IReadOnlyList <T> items, Func <T, bool> filter)
        {
            var filtered = GlobalListPool <T> .Get(items.Count);

            foreach (var item in items)
            {
                if (filter(item))
                {
                    filtered.Add(item);
                }
            }

            var result = filtered.ToArray();

            GlobalListPool <T> .Put(filtered);

            return(result);
        }
        public LinearInterpolation(IList <Vector2> dataPoints)
        {
            if (dataPoints == null)
            {
                throw new ArgumentNullException(nameof(dataPoints));
            }

            if (dataPoints.Count == 0)
            {
                throw new ArgumentException("At least one data point is required.", nameof(dataPoints));
            }

            this.points = GlobalListPool <Vector2> .Get(dataPoints.Count);

            this.points.AddRange(dataPoints);
            this.points.Sort((a, b) => a.x.CompareTo(b.x));

            this.Range = new Interval <float>(points[0].x, points[points.Count - 1].x);
        }
Пример #12
0
        public Mesh ToMesh()
        {
            var vertexCache = GlobalListPool <Vector3> .Get(this.vertices.Count);

            var indexCache = GlobalListPool <int> .Get(this.vertices.Count);

            var meshVertices = GlobalListPool <Vector3> .Get(this.vertices.Count * 3);

            foreach (var face in faces)
            {
                vertexCache.Clear();
                indexCache.Clear();

                foreach (var vertex in face.Vertices)
                {
                    vertexCache.Add(vertex.Vertex);
                }

                vertexCache.Triangulate(indexCache);

                foreach (var index in indexCache)
                {
                    meshVertices.Add(vertexCache[index]);
                }
            }

            var mesh = new Mesh();

            mesh.vertices  = meshVertices.ToArray();
            mesh.triangles = CollectionUtil.CreateArray(meshVertices.Count, 0, i => i + 1);

            GlobalListPool <Vector3> .Put(vertexCache);

            GlobalListPool <int> .Put(indexCache);

            GlobalListPool <Vector3> .Put(meshVertices);

            return(mesh);
        }
Пример #13
0
        private void CollapseNode(int index)
        {
            Debug.Assert(index >= 0);
            Debug.Assert(index < nodeCount * NodeSize);
            Debug.Assert(index % NodeSize == 0);
            Debug.Assert(nodes[index + 1] < NodeCollapseCount);

            for (var i = ChildIndexOffset; i < NodeSize; i++)
            {
                Debug.Assert(nodes[index + i] <= 0, "If a node has few enough items to be collapsed, it can't be that the node contains child nodes.");
            }

            if (index == 0)
            {
                // Don't collapse root
                return;
            }

            // Node is bellow collapse threshold -> collapse into leaf
            var itemCache = GlobalListPool <ItemEntry> .Get(nodes[index + 1]);

            for (var i = ChildIndexOffset; i < NodeSize; i++)
            {
                var reference = nodes[index + i];
                nodes[index + i] = 0;

                if (reference < 0)
                {
                    var leafIndex = -(reference + 1);
                    var leaf      = leafs[leafIndex];

                    for (var j = 0; j < leaf.Count; j++)
                    {
                        itemCache.Add(leaf.Content[j]);
                    }

                    CacheContentArray(leaf.Content);
                    RemoveLeaf(leafIndex);
                }
            }

            var parent       = nodes[index];
            var newLeafIndex = AddLeaf(parent, itemCache);

            for (var i = ChildIndexOffset; i < NodeSize; i++)
            {
                if (nodes[parent + i] == index)
                {
                    nodes[parent + i] = newLeafIndex;
                }
            }

            RemoveNode(index);
            GlobalListPool <ItemEntry> .Put(itemCache);

            if (parent == nodeCount * NodeSize)
            {
                // In case parent was the last node and was used to replace the current node
            }

            if (nodes[parent + 1] < NodeCollapseCount)
            {
                CollapseNode(parent);
            }
        }
Пример #14
0
        private float GetNProductSum(IList <float> p, int n)
        {
            var result = 0f;

            var last    = p.Count - 1;
            var indices = GlobalListPool <int> .Get(n);

            var values = GlobalListPool <float> .Get(n - 1);

            var steps = 0;      // Used for loop invariant to test implementation

            for (var k = 0; k < n; k++)
            {
                steps += k * (k + 1) / 2;
                indices.Add(k);

                if (k < n - 1)
                {
                    values.Add(p[k]);

                    if (k > 0)
                    {
                        values[k] *= values[k - 1];
                    }
                }
            }

            while (true)
            {
                Debug.Assert(steps > 0, "Loop invariant is broken, to many calculation steps needed for this calculation...");

                steps--;

                // For every index constellation, we need to sum up the products
                result += values[n - 2] * p[indices[n - 1]];

                // Shift last index until we reach the end
                if (indices[n - 1] < last)
                {
                    indices[n - 1]++;
                }
                else
                {
                    // Remember whether we were able to shift and index
                    var couldShift = false;

                    // Find first free index to shift
                    for (var i = n - 2; i >= 0; i--)
                    {
                        // If index can be shifted
                        if (indices[i] < indices[i + 1] - 1)
                        {
                            var prev = indices[i];

                            // Shift index and update precalculated values
                            for (var k = i; k < n; k++)
                            {
                                indices[k] = prev + k - i + 1;

                                if (k < n - 1)
                                {
                                    values[k] = p[indices[k]];

                                    if (k > 0)
                                    {
                                        values[k] *= values[k - 1];
                                    }
                                }
                            }

                            couldShift = true;
                            break;
                        }
                    }

                    if (!couldShift)
                    {
                        // If we reached the end, stop computing
                        break;
                    }
                }
            }

            Debug.Assert(steps == 0, "Loop invariant is broken, not enough calculation steps used for this calculation...");

            return(result);
        }