Puisque la taille est connue à l'avance et que vous aurez besoin de convertir tout le tableau en tableau 1D (pour OpenGL), pourquoi ne pas en créer une classe? J'ai créé une implémentation basée sur un modèle d'un tableau 3D qui, je l'espère, vous sera utile.
Utilisation:
typedef Array3D<double, 3, 3, 3> DoubleArray333;
DoubleArray333 array;
Double val = 0.0;
for (size_t i = 0; i < DoubleArray333::SizeX; ++i)
{
for (size_t j = 0; j < DoubleArray333::SizeY; ++j)
{
for (size_t k = 0; k < DoubleArray333::SizeZ; ++k)
{
array(i, j, k) = val++;
}
}
}
for (size_t i = 0; i < DoubleArray333::ArraySize; ++i)
{
std::cout<<array[i]<<" ";
}
Le fichier d'en-tête Array3D:
#pragma once
#include <exception>
#include <sstream>
#include <utility>
#include <memory>
/**
* \brief A 3D array of variable type and size.
* \author Vite Falcon
* \date 08/06/2010
**/
template <typename T, int x, int y, int z>
class Array3D
{
private:
T* m_array;
/**
* \brief Validate the index range of different dimensions.
* \remarks Vite Falcon, 08/06/2010.
* \author Vite Falcon
* \date 08/06/2010
* \exception std::out_of_range Thrown when one of the indices is out-of-range.
* \param x The width index.
* \param y The height index.
* \param z The depth index.
**/
inline void validateRange(size_t x, size_t y, size_t z)
{
if (x >= SizeX || y >= SizeY || z >= SizeZ)
{
std::stringstream ss;
ss<<"Index out of range when accessing ("<<x<<", "<<y<<", "<<z<<
") when total size is ("<<SizeX<<", "<<SizeY<<", "<<SizeZ<<").";
throw std::out_of_range(ss.str());
}
}
/**
* \brief Validates the given array index.
* \remarks Vite Falcon, 08/06/2010.
* \author Vite Falcon
* \date 08/06/2010
* \exception std::out_of_range Thrown when the index is out-of-range.
* \param index Zero-based index of the array.
**/
inline void validateIndex(size_t index)
{
if (index >= ArraySize)
{
std::stringstream ss;
ss<<"Index out of range when accessing array by index "<<index<<
" when total array size is "<<ArraySize<<".";
throw std::out_of_range(ss.str());
}
}
public:
static const size_t SizeX;
static const size_t SizeY;
static const size_t SizeZ;
static const size_t ArraySize;
typedef Array3D<T,x,y,z> MyType;
/**
* \brief Default constructor.
* \author Vite Falcon
* \date 08/06/2010
**/
Array3D(void)
:m_array(new T[ArraySize])
{
}
/**
* \brief Copy constructor.
* \author Vite Falcon
* \date 08/06/2010
* \param other The other.
**/
Array3D(const MyType& other)
:m_array(new T[ArraySize])
{
memcpy_s(m_array, sizeof(T)*ArraySize, other.m_array, sizeof(T)*ArraySize);
}
/**
* \brief Destructor.
* \author Vite Falcon
* \date 08/06/2010
**/
~Array3D(void)
{
delete[] m_array;
m_array = 0;
}
/**
* \brief Gets the value at a particular array index.
* \author Vite Falcon
* \date 08/06/2010
* \param array_index Zero-based index of the array.
* \return The value at the given index.
**/
inline T& at(size_t array_index)
{
return (*this)[array_index];
}
/**
* \brief Gets the value at a particular array index (const version)
* \author Vite Falcon
* \date 08/06/2010
* \param array_index Zero-based index of the array.
* \return The value at the given index.
**/
inline const T& at(size_t array_index) const
{
return (*this)[array_index];
}
/**
* \brief Gets the value in the array from the given 3D indices.
* \author Vite Falcon
* \date 08/06/2010
* \param x The width index.
* \param y The height index.
* \param z The depth index.
* \return The value at the given indices.
**/
inline T& at(size_t x, size_t y, size_t z)
{
return (*this)(x, y, z);
}
/**
* \brief Gets the value in the array from the given 3D indices (const version).
* \author Vite Falcon
* \date 08/06/2010
* \param x The width index.
* \param y The height index.
* \param z The depth index.
* \return The value at the given indices.
**/
inline const T& at(size_t x, size_t y, size_t z) const
{
return (*this)(x, y, z);
}
/**
* \brief The '()' operator to access the values as a 3D array.
* \author Vite Falcon
* \date 08/06/2010
* \return The value at the given indices.
*
* \param x The width index.
* \param y The height index.
* \param z The depth index.
**/
inline T& operator()(size_t x, size_t y, size_t z)
{
validateRange(x, y, z);
return m_array[x*SizeY*SizeZ + y*SizeZ + z];
}
/**
* \brief The '()' operator to access the values as a 3D array (const version).
* \author Vite Falcon
* \date 08/06/2010
* \return The value at the given indices.
*
* \param x The width index.
* \param y The height index.
* \param z The depth index.
**/
inline const T& operator()(size_t x, size_t y, size_t z) const
{
validateRange(x, y, z);
return m_array[x*SizeY*SizeZ + y*SizeZ + z];
}
/**
* \brief The '[]' operator to access the values as a 1D array.
* \author Vite Falcon
* \date 08/06/2010
* \param array_index Zero-based index of the array.
* \return Value at the given index.
**/
inline T& operator[](size_t array_index)
{
validateIndex(array_index);
return m_array[array_index];
}
/**
* \brief The '[]' operator to access the values as a 1D array.
* \author Vite Falcon
* \date 08/06/2010
* \param array_index Zero-based index of the array.
* \return Value at the given index.
**/
inline const T& operator[](size_t array_index) const
{
validateIndex(array_index);
return m_array[array_index];
}
/**
* \brief Fills the array with the given value.
* \author Vite Falcon
* \date 08/06/2010
* \param val The value to fill the array.
**/
void fill(const T& val)
{
for (size_t i = 0; i < ArraySize; ++i)
{
m_array[i] = val;
}
}
/**
* \brief Gets the raw array.
* \author Vite Falcon
* \date 08/06/2010
* \return The 1D array.
**/
T* getArray()
{
return m_array;
}
/**
* \brief Swaps the current array with the given one.
* \author Vite Falcon
* \date 08/06/2010
* \param [in,out] other The other.
**/
void swap(MyType& other)
{
std::swap(m_array, other.m_array);
}
/**
* \brief Copy operator.
* \author Vite Falcon
* \date 08/06/2010
* \param other The other.
* \return A shallow copy of this object.
**/
MyType& operator = (const MyType& other)
{
MyType temp(other);
swap(temp);
return *this;
}
};
template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::SizeX = x;
template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::SizeY = y;
template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::SizeZ = z;
template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::ArraySize = x*y*z;
Vous pouvez également obtenir le pointeur sur le tableau en tant que 1D en utilisant la fonction:
double* double_array = array.getArray();
EDIT: Modification de l'utilisation pour l'afficher en double plutôt qu'en int.
Donc, vous avez déjà les doubles disponibles, non? Vous voulez 'double foo [32] [32] [16] = {{{1.0, 2.0, 3.0, ...}, {...}}}', mais pour les vecteurs? –
Oui, fondamentalement ça devrait être un vecor de vecteur de double vecteur donc je devrais pouvoir faire vec [31] [31] [15] sans problèmes – jmasterx
Si les cotes sont fixes, pourquoi ne pas utiliser un 'boost :: array' (ou 'std :: tr1 :: array', si votre compilateur a TR1 ou' std :: array' en C++ 1x)? – sbi