/// <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.Height, this.Diameter, cellLength);
            int sizeBase   = array.GetLength(0);
            int sizeHeight = array.GetLength(1);

            // mask tracks what slots are inside and outside of the circle base in order to fill in the columns
            bool[,] mask = MaskArrayFactory.CreateCircleMask(sizeBase);

            // for each slot in the circular base
            for (int iX = 0; iX < sizeBase; iX++)
            {
                for (int iZ = 0; iZ < sizeBase; iZ++)
                {
                    // choose fill function depending on if it's inside or outside the circle base
                    Func <Index3D, T> value = mask[iX, iZ] ? internalValueFactory : externalValueFactory;

                    // fill in the column with the chosen function
                    for (int iY = 0; iY < sizeHeight; iY++)
                    {
                        array[iX, iY, iZ] = value(new Index3D(iX, iY, iZ));
                    }
                }
            }

            return(new Array3D <T>(array));
        }
        /// <inheritdoc />
        public IBoundedIndexable <Index2D, T> Rasterize(
            float cellLength, Func <Index2D, T> internalValueFactory, Func <Index2D, T> externalValueFactory)
        {
            IRasterizableMaskContracts.Rasterize(cellLength, internalValueFactory, externalValueFactory);

            T[,] array = MaskArrayFactory.Create <T>(this.Diameter, this.Diameter, cellLength);
            int size = array.GetLength(0);

            // mask tracks what slots are inside and outside of the circle
            bool[,] mask = MaskArrayFactory.CreateCircleMask(size);

            // for each cell in the array, fill in according to the mask
            for (int iX = 0; iX < size; iX++)
            {
                for (int iY = 0; iY < size; iY++)
                {
                    if (mask[iX, iY])
                    {
                        // inside the circle
                        array[iX, iY] = internalValueFactory(new Index2D(iX, iY));
                    }
                    else
                    {
                        // outside the circle
                        array[iX, iY] = externalValueFactory(new Index2D(iX, iY));
                    }
                }
            }

            return(new Array2D <T>(array));
        }