/// <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); }
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); }
private void DoUpdate() { if (Time.time <= lastStep + RevelationSpeed) { return; } lastStep += RevelationSpeed; foreach (var cell in prevCells) { if (!cell.IsNude || cell.IsBomb) { continue; } foreach (var neighbor in cell.Neighbors) { if (neighbor.State == CellState.Default) { neighbor.State = CellState.Revealed; if (neighbor.IsNude && !neighbor.IsBomb) { buffer.Add(neighbor); } } } } if (buffer.Count == 0) { IsFinished = true; foreach (var action in followupActions) { action.Invoke(); } OnFinished(); GlobalListPool <BoardCell> .Put(prevCells); GlobalListPool <BoardCell> .Put(buffer); GlobalListPool <Action> .Put(followupActions); CallProvider.RemoveUpdateListener(DoUpdate); return; } var tmp = prevCells; prevCells = buffer; buffer = tmp; buffer.Clear(); }
/// <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); }
public void Dispose() { if (this.coeff == null) { return; } GlobalListPool <float> .Put(this.coeff); this.coeff = null; }
/// <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); }
public void Dispose() { if (this.data == null) { return; } GlobalListPool <Vector3> .Put(this.data); this.data = null; }
public void Dispose() { if (points == null) { return; } // Allow the internal list to be reused GlobalListPool <Vector2> .Put(points); points = null; }
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); }
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); }
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); }
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; } } }
/// <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); }
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); }
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); } }
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); }