Say you have a 3-dimensional array in c#
int space[width, height, depth];
And you would like to implement the method
public int[,] GetCrossSection(int position, int dimension)
Where 'position' is the point along the 'dimension' specified where you would like to extract your slice. It is important to not use the fact that we are only dealing with 3 dimensions, in the examples below you could fix them by adding if statements and assume the matrix will not grow beyond 3 dimensions.
My first attempt (commented problem areas):
public int[,] GetCrossSection(int position, int dimension)
{
int[] dimensionIterationInterval = new int[] { width, height, depth };
var dims = new List<int>(dimensionIterationInterval);
dims.RemoveAt(dimension);
dimensionIterationInterval = dims.ToArray();
int[,] crossSection = new int[dimensionIterationInterval[0], dimensionIterationInterval[1]];
int[] itr = new int[2];
for (itr[0] = 0; itr[0] < dimensionIterationInterval[0]; itr[0]++)
{
for (itr[1] = 0; itr[1] < dimensionIterationInterval[1]; itr[1]++)
{
crossSection[itr[0], itr[1]] = space[?,?,?]; //Problem
}
}
}
And my second attempt, equally futile:
public int[,] GetCrossSection(int position, int dimension)
{
int[,] dimensionIterationInterval = new int[,] { { 0, width }, { 0, height }, { 0, depth } };
dimensionIterationInterval[dimension, 0] = position;
dimensionIterationInterval[dimension, 1] = position + 1;
int[,] crossSection = new int[?,?]; //Problem
for (int x = dimensionIterationInterval[0, 0]; x < dimensionIterationInterval[0, 1]; x++)
{
for (int y = dimensionIterationInterval[1, 0]; y< dimensionIterationInterval[1, 1]; y++)
{
for (int z = dimensionIterationInterval[2, 0]; z < dimensionIterationInterval[2, 1]; z++)
{
crossSection[?, ?] = space[x, y, z]; // Problem
}
}
}
}
Both those attemps run into dead ends. How would you solve it? It's ok to have the fixed iteration loops for the number of dimensions of space[,,]. If the number of dimensions grow that is somewhat managable. Clever/limited if statments could work, but not excessive ifs for each dimension.
Quick draft:
static int[,] GetSlice(int[,,] source, int dimension, int position)
{
int l1 = 0, l2 = 0;
if (dimension == 0)
{
l1 = source.GetLength(1);
l2 = source.GetLength(2);
}
else if (dimension == 1)
{
l1 = source.GetLength(0);
l2 = source.GetLength(2);
}
else if (dimension == 2)
{
l1 = source.GetLength(0);
l2 = source.GetLength(1);
}
var result = new int[l1, l2];
var s0 = dimension == 0 ? position : 0;
var s1 = dimension == 1 ? position : 0;
var s2 = dimension == 2 ? position : 0;
var m0 = dimension == 0 ? position + 1 : source.GetLength(0);
var m1 = dimension == 1 ? position + 1 : source.GetLength(1);
var m2 = dimension == 2 ? position + 1 : source.GetLength(2);
for (var i0 = s0; i0 < m0; i0++)
for (var i1 = s1; i1 < m1; i1++)
for (var i2 = s2; i2 < m2; i2++)
{
int x = 0, y = 0;
if (dimension == 0)
{
x = i1;
y = i2;
}
else if (dimension == 1)
{
x = i0;
y = i2;
}
else if (dimension == 2)
{
x = i0;
y = i1;
}
result[x, y] = source[i0, i1, i2];
}
return result;
}
It can be generalised to any number of dimensions (and it even will make code smaller and simpler).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With