/// <inheritdoc /> public IBoundedIndexable <Index3D, T> Rasterize( float cellLength, Func <Index3D, T> internalValueFactory, Func <Index3D, T> externalValueFactory) { IRasterizableMaskContracts.Rasterize(cellLength, internalValueFactory, externalValueFactory); T[,,] array = MaskArrayFactory.Create <T>(this.Diameter, this.Diameter, this.Diameter, cellLength); if (array.Length == 0) { return(new Array3D <T>(array)); } int max = array.GetLength(0) - 1; int mid = max / 2; float radius = array.GetLength(0) / 2f; float distance = radius * radius; for (int iX = 0; iX <= mid; iX++) { for (int iY = 0; iY <= mid; iY++) { for (int iZ = 0; iZ <= mid; iZ++) { int mX = max - iX; int mY = max - iY; int mZ = max - iZ; if (DistanceCheck(iX - mid, iY - mid, iZ - mid, distance)) { array[iX, iY, iZ] = internalValueFactory(new Index3D(iX, iY, iZ)); array[mX, iY, iZ] = internalValueFactory(new Index3D(mX, iY, iZ)); array[iX, mY, iZ] = internalValueFactory(new Index3D(iX, mY, iZ)); array[iX, iY, mZ] = internalValueFactory(new Index3D(iX, iY, mZ)); array[mX, mY, iZ] = internalValueFactory(new Index3D(mX, mY, iZ)); array[iX, mY, mZ] = internalValueFactory(new Index3D(iX, mY, mZ)); array[mX, iY, mZ] = internalValueFactory(new Index3D(mX, iY, mZ)); array[mX, mY, mZ] = internalValueFactory(new Index3D(mX, mY, mZ)); } else { array[iX, iY, iZ] = externalValueFactory(new Index3D(iX, iY, iZ)); array[mX, iY, iZ] = externalValueFactory(new Index3D(mX, iY, iZ)); array[iX, mY, iZ] = externalValueFactory(new Index3D(iX, mY, iZ)); array[iX, iY, mZ] = externalValueFactory(new Index3D(iX, iY, mZ)); array[mX, mY, iZ] = externalValueFactory(new Index3D(mX, mY, iZ)); array[iX, mY, mZ] = externalValueFactory(new Index3D(iX, mY, mZ)); array[mX, iY, mZ] = externalValueFactory(new Index3D(mX, iY, mZ)); array[mX, mY, mZ] = externalValueFactory(new Index3D(mX, mY, mZ)); } } } } return(new Array3D <T>(array)); }
public static T[,,] Stitch <T>(T[,,] x, T[,,] y) { var output = new T[x.GetLength(0) + y.GetLength(0), x.GetLength(1), x.GetLength(2)]; for (int i = 0; i < x.GetLength(0); i++) { for (int j = 0; j < x.GetLength(1); j++) { for (int k = 0; k < x.GetLength(2); k++) { output[i, j, k] = x[i, j, k]; } } } for (int i = 0; i < y.GetLength(0); i++) { for (int j = 0; j < x.GetLength(1); j++) { for (int k = 0; k < x.GetLength(2); k++) { output[i + x.GetLength(0), j, k] = y[i, j, k]; } } } return(output); }
/// <summary> /// Concatenate 3D array following second order. /// Result shape become [ src.GetLength(0), (src.GetLength(1) - clipping) + (targetRight.GetLength(1) - clipping) , src.GetLength(2) ] /// </summary> /// <typeparam name="T"></typeparam> /// <param name="src"></param> /// <param name="targetRight"></param> /// <param name="clipping"></param> /// <returns></returns> public static T[ , , ] Concate_H <T>( this T [ , , ] src , T [ , , ] targetRight , int clipping) where T : new() { if (src.GetLength(0) == targetRight.GetLength(0) && src.GetLength(2) == targetRight.GetLength(2)) { int order0Len = src.GetLength(0); int order1Len = src.GetLength(1) + targetRight.GetLength(1) - 2 * clipping; int order2Len = src.GetLength(2); T[,,] output = new T[order0Len, order1Len, order2Len]; Action <int> act = new Action <int>(j => { for (int i = 0; i < src.GetLength(1) - clipping; i++) { for (int k = 0; k < order2Len; k++) { output[j, i, k] = src[j, i, k]; } } for (int i = src.GetLength(1) - clipping; i < order1Len; i++) { for (int k = 0; k < order2Len; k++) { output[j, i, k] = targetRight[j, i - src.GetLength(1) + clipping, k]; } } }); if (order0Len * order1Len * order2Len > double.MaxValue) { Parallel.For(0, order0Len, new Action <int>(j => { act(j); })); } else { for (int j = 0; j < order0Len; j++) { act(j); } } return(output); } else { throw new IndexOutOfRangeException("Source and Target Length are not same"); } }
/// <summary> /// 拼接三维数组 /// </summary> public static T[,,] Concat2 <T>(this T[,,] array_0, T[,,] array_1) { if (array_0.GetLength(0) != array_1.GetLength(0) || array_0.GetLength(1) != array_1.GetLength(1)) { throw new System.Exception("两个数组一二维的长度要相等"); } T[,,] ret = new T[array_0.GetLength(0), array_0.GetLength(1), array_1.GetLength(1) + array_1.GetLength(2)]; for (int i = 0; i < array_0.GetLength(0); i++) { for (int j = 0; j < array_0.GetLength(1); j++) { for (int k = 0; k < array_0.GetLength(2); k++) { ret[i, j, k] = array_0[i, j, k]; } } } for (int i = 0; i < array_1.GetLength(0); i++) { for (int j = 0; j < array_1.GetLength(1); j++) { for (int k = 0; k < array_0.GetLength(2); k++) { ret[i, j, k + array_0.GetLength(2)] = array_1[i, j, k]; } } } return(ret); }
/// <summary> /// Concatenate 3D array following first order. /// Result shape become [ src.GetLength(0) targetBottom.GetLength(0) , src.GetLength(1) , src.GetLength(2) ] /// </summary> /// <typeparam name="T"></typeparam> /// <param name="src"></param> /// <param name="targetBottom"></param> /// <returns></returns> public static T[ , , ] Concate_V <T>( this T [ , , ] src, T [ , , ] targetBottom) where T : new() { if (src.GetLength(1) == targetBottom.GetLength(1) && src.GetLength(2) == targetBottom.GetLength(2)) { int order0Len = src.GetLength(0) + targetBottom.GetLength(0); int order1Len = src.GetLength(1); int order2Len = src.GetLength(2); T[,,] output = new T[order0Len, order1Len, order2Len]; Action <int> act = new Action <int>(i => { for (int j = 0; j < src.GetLength(0); j++) { for (int k = 0; k < order2Len; k++) { output[j, i, k] = src[j, i, k]; } } for (int j = src.GetLength(0); j < order0Len; j++) { for (int k = 0; k < order2Len; k++) { output[j, i, k] = targetBottom[j - src.GetLength(0), i, k]; } } }); if (order0Len * order1Len * order2Len > double.MaxValue) { Parallel.For(0, order1Len, new Action <int>(i => { act(i); })); } else { for (int i = 0; i < order1Len; i++) { act(i); } } return(output); } else { throw new ArgumentOutOfRangeException("Source and Target Length are not same"); } }
/// <summary> /// Reads the contents of the current <see cref="Texture3D{T}"/> instance and writes them into a target array. /// </summary> /// <typeparam name="T">The type of items stored on the texture.</typeparam> /// <param name="source">The input <see cref="Texture3D{T}"/> instance to read data from.</param> /// <param name="destination">The input array to write data to.</param> /// <remarks> /// The input 3D array needs to have each 2D plane stacked on the depth axis. That is, the expected /// layout of the input array has to be of shape [depth, height, width]. /// </remarks> public static void CopyTo <T>(this Texture3D <T> source, T[,,] destination) where T : unmanaged { Guard.IsNotNull(source); Guard.IsNotNull(destination); Guard.IsEqualTo(destination.GetLength(0), source.Depth, nameof(destination)); Guard.IsEqualTo(destination.GetLength(1), source.Height, nameof(destination)); Guard.IsEqualTo(destination.GetLength(2), source.Width, nameof(destination)); source.CopyTo(ref destination[0, 0, 0], destination.Length, 0, 0, 0, source.Width, source.Height, source.Depth); }
/// <summary> /// Writes the contents of a given <typeparamref name="T"/> array to the current <see cref="Texture3D{T}"/> instance. /// </summary> /// <typeparam name="T">The type of items stored on the texture.</typeparam> /// <param name="destination">The target <see cref="Texture3D{T}"/> instance to write data to.</param> /// <param name="source">The input <typeparamref name="T"/> array to read data from.</param> /// <remarks> /// The source 3D array needs to have each 2D plane stacked on the depth axis. That is, the expected /// layout of the input array has to be of shape [depth, height, width]. /// </remarks> public static void CopyFrom <T>(this Texture3D <T> destination, T[,,] source) where T : unmanaged { Guard.IsNotNull(destination); Guard.IsNotNull(source); Guard.IsEqualTo(source.GetLength(0), destination.Depth, nameof(source)); Guard.IsEqualTo(source.GetLength(1), destination.Height, nameof(source)); Guard.IsEqualTo(source.GetLength(2), destination.Width, nameof(source)); destination.CopyFrom(ref source[0, 0, 0], source.Length, 0, 0, 0, destination.Width, destination.Height, destination.Depth); }
public Cube(T[,,] cube) { if (cube.GetLength(0) != 3 || cube.GetLength(1) != 3 || cube.GetLength(2) != 6) { throw new Exception("Cube must have dimensions 3x3x6"); } _cube = cube; }
/// <summary> /// Creates a khiva array object. /// </summary> /// <typeparam name="T">Type of the elements of the array.</typeparam> /// <param name="values">3 dimensional array with the data.</param> /// <param name="doublePrecision">If Complex array has double precision. Default to false.</param> /// <returns>KhivaArray created</returns> public static unsafe KhivaArray Create <T>(T[,,] values, bool doublePrecision = false) where T : unmanaged { if (values == null) { throw new Exception("Null elems object provided"); } fixed(T *data = &values[0, 0, 0]) return(Create <T>(3, new long[] { values.GetLength(2), values.GetLength(1), values.GetLength(0), 1 }, data, doublePrecision)); }
/// <summary> /// Concatenates the elements of a second array in the X dimension. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="second">The second array to concatenate.</param> /// <returns></returns> public static T[,,] ConcatX <T>(this T[,,] source, T[,,] second) { if (source == null) { throw new ArgumentNullException("source"); } if (second == null) { throw new ArgumentNullException("second"); } int width = source.GetLength(0), height = source.GetLength(1), depth = source.GetLength(2); if (height != second.GetLength(1)) { throw new ArgumentOutOfRangeException("second", "The height of the second array must match the height of the source array."); } if (depth != second.GetLength(2)) { throw new ArgumentOutOfRangeException("second", "The depth of the second array must match the depth of the source array."); } int secondWidth = second.GetLength(0); T[,,] result = new T[width + secondWidth, height, depth]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < depth; z++) { result[x, y, z] = source[x, y, z]; } } } for (int x = 0; x < secondWidth; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < depth; z++) { result[secondWidth + x, y, z] = second[x, y, z]; } } } return(result); }
public static T GetSafely <T>(this T[,,] array, int index0, int index1, int index2, T defaultValue = default) { if (index0 < 0 || index0 >= array.GetLength(0) || index1 < 0 || index1 >= array.GetLength(1) || index2 < 0 || index2 >= array.GetLength(2)) { return(defaultValue); } return(array[index0, index1, index2]); }
public static bool CheckPosition <T>(Vector3D position, T[, ,] array) { int i = array.GetLength(0); int j = array.GetLength(1); int k = array.GetLength(2); if (position.X >= 0 && position.X < i && position.Y >= 0 && position.Y < j && position.Z >= 0 && position.Z < k) { return(true); } return(false); }
public static bool SetSafely <T>(this T[,,] array, int index0, int index1, int index2, T value) { if (index0 < 0 || index0 >= array.GetLength(0) || index1 < 0 || index1 >= array.GetLength(1) || index2 < 0 || index2 >= array.GetLength(2)) { return(false); } array[index0, index1, index2] = value; return(true); }
public static bool CheckPosition<T>(Vector3 position, T[,,] array) { int i = array.GetLength(0); int j = array.GetLength(1); int k = array.GetLength(2); if (position.X >= 0 && position.X < i && position.Y >= 0 && position.Y < j && position.Z >= 0 && position.Z < k) return true; else return false; }
/// <summary> /// Determines whether two arrays are equal by comparing their elements using an equality comparer. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="second">The array to compare.</param> /// <param name="comparer">An equality comparer to use to compare elements.</param> /// <returns></returns> public static bool ArrayEqual <T>(this T[,,] source, T[,,] second, IEqualityComparer <T> comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (second == null) { throw new ArgumentNullException("second"); } if (comparer == null) { throw new ArgumentNullException("comparer"); } int width = source.GetLength(0), height = source.GetLength(1), depth = source.GetLength(2); if (width != second.GetLength(0)) { throw new ArgumentException("second", "The width of the second array must match the width of the source array."); } if (height != second.GetLength(1)) { throw new ArgumentException("second", "The height of the second array must match the height of the source array."); } if (depth != second.GetLength(2)) { throw new ArgumentException("second", "The depth of the second array must match the depth of the source array."); } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < depth; z++) { if (!comparer.Equals(source[x, y, z], second[x, y, z])) { return(false); } } } } return(true); }
public static T[,] Get2DFrom3D <T>(T[,,] array, int index) { T[,] result = new T[array.GetLength(1), array.GetLength(2)]; for (int x = 0; x < array.GetLength(1); x++) { for (int y = 0; y < array.GetLength(2); y++) { result[x, y] = array[index, x, y]; } } return(result); }
static public T[,,] AddLayer <T> (T[,,] array, T[,,] otherArray, int channel) { int lengthX = array.GetLength(0); int lengthZ = array.GetLength(1); int numChannels = array.GetLength(2); T[,,] newArray = new T[lengthX, lengthZ, numChannels + 1]; Array.Copy(array, newArray, lengthX * lengthZ * numChannels); CopyLayer(otherArray, newArray, channel, numChannels); return(newArray); }
public MemoryBuffer3D <T> SetBuffer <T>(T[,,] obj) where T : struct { var w = obj.GetLength(0); var h = obj.GetLength(1); var z = obj.GetLength(2); var buffer = _accelerator.Allocate <T>(w, h, z); buffer.CopyFrom(obj, new Index3(0, 0, 0), new Index3(0, 0, 0), new Index3(w, h, z)); return(buffer); }
/// <summary> /// Set every element in an array to the return value of a delegation /// </summary> /// <typeparam name="T">Type of the Array</typeparam> /// <param name="arr">The array</param> /// <param name="DO">The delegate to set the values taking input (X,Y,Z,Value)</param> public static void SetForEach <T>(T[,,] arr, Func <int, int, int, T, T> DO) { for (int x = 0; x < arr.GetLength(0); x++) { for (int y = 0; y < arr.GetLength(1); y++) { for (int z = 0; z < arr.GetLength(2); z++) { arr[x, y, z] = DO(x, y, z, arr[x, y, z]); } } } }
public static void FillArray <T>(T[,,] array, T value) { int max0 = array.GetLength(0); int max1 = array.GetLength(1); int max2 = array.GetLength(2); for (int i = 0; i < max0; i++) { for (int j = 0; j < max1; j++) { for (int k = 0; k < max2; k++) { array[i, j, k] = value; } } } }
public static void InitDP3 <T>(T[,,] dp, T value) { for (int i = 0; i < dp.GetLength(0); i++) { for (int j = 0; j < dp.GetLength(1); j++) { for (int k = 0; k < dp.GetLength(2); k++) { dp[i, j, k] = value; } } } }
static public void CopyLayer <T> (T[,,] src, T[,,] dst, int srcNum, int dstNum) { int sizeX = src.GetLength(0); int sizeZ = src.GetLength(1); for (int x = 0; x < sizeX; x++) { for (int z = 0; z < sizeZ; z++) { dst[x, z, dstNum] = src[x, z, srcNum]; } } }
public static void FillArray <T>(T[,,] a, T b) { int c = a.GetLength(0); int d = a.GetLength(1); int e = a.GetLength(2); for (int f = 0; f < c; f++) { for (int g = 0; g < d; g++) { for (int h = 0; h < e; h++) { a[f, g, h] = b; } } } }
public static void Clear <T>(this T[,,] a, T value) { for (int x = 0; x < a.GetLength(0); x++) { for (int y = 0; y < a.GetLength(1); y++) { for (int w = 0; w < a.GetLength(2); w++) { a[x, y, w] = value; } } } }
/// <summary> /// Fill a three dimension array with a default value. /// </summary> /// <param name="array">The array to fill.</param> /// <param name="defaultValue">The default value to fill the array with.</param> public static void FillArray <T>(T[,,] array, T defaultValue) { for (int x = 0; x < array.GetLength(0); x++) { for (int y = 0; y < array.GetLength(1); y++) { for (int z = 0; z < array.GetLength(2); z++) { array[x, y, z] = defaultValue; } } } }
static public void ForEach <T>(this T[, , ] array, Action <T, int, int, int> action) { for (int i = 0; i < array.GetLength(0); i++) { for (int j = 0; j < array.GetLength(1); j++) { for (int k = 0; k < array.GetLength(2); k++) { action(array[i, j, k], i, j, k); } } } }
/// <summary> /// Perform a delegation with each element in the array /// </summary> /// <typeparam name="T">Type of the Array</typeparam> /// <param name="arr">The array</param> /// <param name="DO">The delegate to run taking input (X,Y,Z,Value)</param> public static void DoForEach <T>(T[,,] arr, Action <int, int, int, T> DO) { for (int x = 0; x < arr.GetLength(0); x++) { for (int y = 0; y < arr.GetLength(1); y++) { for (int z = 0; z < arr.GetLength(2); z++) { DO(x, y, z, arr[x, y, z]); } } } }
public void Fill(Vector3Int pos, Vector3Int size, T value) { for (int z = 0; z < data.GetLength(0); z++) { for (int y = 0; y < data.GetLength(1); y++) { for (int x = 0; x < data.GetLength(2); x++) { data[pos.z + z, pos.y + y, pos.x + x] = value; } } } }
public bool TryGetPointAt(int x, int y, int z, out T point) { if (x >= matrix.GetLength(0) || y >= matrix.GetLength(1) || z >= matrix.GetLength(2)) { point = null; return(false); } else { point = matrix[x, y, z]; return(true); } }
/// <summary> /// Initializes a new instance of the <see cref="ReadOnlyMemory2D{T}"/> struct wrapping a layer in a 3D array. /// </summary> /// <param name="array">The given 3D array to wrap.</param> /// <param name="depth">The target layer to map within <paramref name="array"/>.</param> /// <exception cref="ArgumentOutOfRangeException">Thrown when a parameter is invalid.</exception> public ReadOnlyMemory2D(T[,,] array, int depth) { if ((uint)depth >= (uint)array.GetLength(0)) { ThrowHelper.ThrowArgumentOutOfRangeExceptionForDepth(); } this.instance = array; this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(depth, 0, 0)); this.height = array.GetLength(1); this.width = array.GetLength(2); this.pitch = 0; }