4D Arrays?
#1 Members - Reputation: 620
Posted 07 December 2012 - 02:09 AM
For 2d arrays I know it is y(height)*width + x. I also know it for the 3d array but not on the top of my head. But what is it for a 4D array?
hmmm maybe its pointless since you cant even visualize a 4d array... Since what is considered the 4th dimension? I know the 3d has height width and depth but what is in 4d?
#2 Members - Reputation: 1229
Posted 07 December 2012 - 02:12 AM
Or rather, it depends on what you want your fourth dimension to mean.
x + y*width + z*height*width + w*height*width*depth.
you can expand it to as many dimensions as you like.
Why do you need a 4D array anyway? sounds a bit exotic to me.
Edited by Olof Hedman, 07 December 2012 - 02:21 AM.
#3 Members - Reputation: 684
Posted 07 December 2012 - 02:15 AM
Also, when we come to a multiple dimension array, especially so high dimension 4D, we should consider better data structure rather than a plain array.
So if you want to store X, Y, Z, D in a 4D array, how about store them in a 1D array with a structure.
struct Item {
int X;
...
};
Item myArray[100];
Isn't that clearer?
If you are not using C/C++, just make Item a class.
Edited by wqking, 07 December 2012 - 02:16 AM.
http://www.cpgf.org/
cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.
v1.5.5 was released. Now supports tween and timeline for ease animation.
#4 Members - Reputation: 291
Posted 07 December 2012 - 02:42 AM
The fourth dimension can called whatever you like, some people say it's time, some people say it's space and some say it's an object in itself.
Here is a nice link about how you project the 4D in 3D: http://steve.hollasc...s/chapter4.html
Four-dimensional geometry: http://steve.hollasc...s/chapter2.html
#7 Crossbones+ - Reputation: 1177
Posted 07 December 2012 - 03:14 AM
int array[3][4][5][6]; //or std::vector< std::vector< std::vector< std::vector< /*your Type*/ > > > > array;
Using a naked C++ array is usually bad for this and even if you have to if you use only one array you end up with a uniform grid like array only, jagged arrays wouldn't be possible you would need to use a "type****" for that and the just looks ugly.
Edited by NightCreature83, 07 December 2012 - 03:17 AM.
#8 Members - Reputation: 684
Posted 07 December 2012 - 03:18 AM
That makes sense.im making it for learning purposes. The book goes up to making a 3d array class and I thought maybe making a 4d class myself would be good exercise
Hope this Wiki helps you,
http://en.wikipedia.org/wiki/Array_data_structure#Multidimensional_arrays
http://www.cpgf.org/
cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.
v1.5.5 was released. Now supports tween and timeline for ease animation.
#9 Members - Reputation: 1229
Posted 07 December 2012 - 03:33 AM
4D "can" be visualized in 3D: http://en.wikipedia.org/wiki/Tesseract
A "funny" note on those pictures (wich I feel is often forgotten/omitted) is that it isn't just a 3D projection, but a 2D projection of a 3D projection of a 4D object
Might sound irrelevant, but I found that this realisation made me understand the 4D objects better. you have the same kind of information loss from 3D to 2D as you do in 4D to 3D, so in the same way an animation shows 3D objects better in 2D, you "see" the 4D objects better if you rotate it. (as is shown in the animated pictures)
Edited by Olof Hedman, 07 December 2012 - 03:43 AM.
#10 Crossbones+ - Reputation: 1177
Posted 07 December 2012 - 04:38 AM
The real problem with 4D is that you can't imagine it so you have no idea what the real representation looks like, our brains are wired for a 3D world. So to us even a 2D image of a 3D object will actually still look 3D because our brain will try an interpret the depth in the image anyways.
4D "can" be visualized in 3D: http://en.wikipedia.org/wiki/Tesseract
A "funny" note on those pictures (wich I feel is often forgotten/omitted) is that it isn't just a 3D projection, but a 2D projection of a 3D projection of a 4D object
Might sound irrelevant, but I found that this realisation made me understand the 4D objects better. you have the same kind of information loss from 3D to 2D as you do in 4D to 3D, so in the same way an animation shows 3D objects better in 2D, you "see" the 4D objects better if you rotate it. (as is shown in the animated pictures)
#11 Members - Reputation: 1229
Posted 07 December 2012 - 04:47 AM
For a 2D projection of a 3D projection to feel 3D, you either need shading, animation, or an easily recognizable object. All of these are extra hints of the third dimension. Just a straight static 2D projection of a 3D object gives little hints of the objects 3Dness, and makes it seem flat.
In the same way, shading, and animations, can give you more hints of the objects 4Dness in the 3D projection, and give you a better understanding of it, even if you still can't visualize it in your head.
#12 Members - Reputation: 455
Posted 07 December 2012 - 06:47 AM
#13 Members - Reputation: 620
Posted 07 December 2012 - 11:43 PM
[source lang="cpp"]#pragma once#include <iostream>using namespace std;template <class Datatype>class Array4D{public://ConstructorArray4D(int p_time, int p_depth, int p_height, int p_width){ m_array = new Datatype[ p_time * p_depth * p_height * p_width]; m_time = p_time; m_depth = p_depth; m_height = p_height; m_width = p_width;}//Destructor~Array4D(){ if(m_array != 0) { delete[] m_array; } m_array = 0;}//Get: Retrieves the value from passed in locationDatatype& Get(int p_t, int p_z, int p_y, int p_x){ return m_array[ ( (p_t * m_depth * m_height * m_width) + (p_z * m_height * m_width) + (p_y * m_width) + (p_x) ) ];}//Width: Returns the width of the arrayint Width(){ return m_width;}//Height: Returns the height of the arrayint Height(){ return m_height;}//Depth: Returns the depth of the arrayint Depth(){ return m_depth;}//Time: Returns the time of the arrayint Time(){ return m_time;}//Resize: Resizes the arrayvoid Resize(int p_time, int p_depth, int p_height, int p_width){ //Declare a pointer to a new array and allocate enouh memory Datatype *newarray = new [p_time * p_depth * p_height * p_width]; //Determine the minimum of all four dimensions int minx = (p_width < m_width ? p_width : m_width); int miny = (p_height < m_height ? p_height : m_height); int minz = (p_depth < m_depth ? p_depth : m_depth); int mint = (p_time < m_time ? p_time : m_time); //Declare four dimensional coordinates int x; int y; int x; int t; //Declare temporary variables int t1; int t2; int t3; int t4; int t5; int t6; //Now loop through each cell and paste the values from the old array into the new array for(t = 0; t < mint; t++) { t1 = t * p_depth * m_height * m_width t2 = t * m_depth * m_height * m_width for(z = 0; z < minz; z++) { t3 = z * p_width * m_height; t4 = z * m_width * m_height; for(y = 0; y < miny; y++) { t5 = y * p_width; t6 = y * m_width; for(x = 0; x < minx ; x++) { newarray[t1 + t3 + t5 + x] = m_array[t2 + t4 + t6 + x]; } } } } //Deallocate the old array if(m_array != 0) { delete[] m_array; } m_array = newarray; //set the new dimesions m_width = p_width; m_height = p_height; m_depth = p_depth; m_time = p_time;}//Size: Returns the total size of the arrayint Size(){ return m_time * m_depth * m_height * m_width;}private://Private variablesDatatype *m_array;int m_width;int m_height;int m_depth;int m_time;};[/source]
and heres an example implementation file to test it:
[source lang="cpp"]#include <iostream>#include "Array4D.h"using namespace std;int main(){ //Create two different 4-Dimensional arrays Array4D<int> iarray(5, 5, 5, 5); Array4D<float> farray(7, 7, 7, 7); //Create some variables to show output int i; int f; //Insert 10 into an array iarray.Get(2, 1, 3, 0) = 10; i = iarray.Get(2, 1, 3, 0); cout << "The value at time 2, depth 1, height 3, and width 0 is: " << i << endl; farray.Get(2, 1, 3, 0) = 25.0f; f = farray.Get(2, 1, 3, 0); cout << "The value at time 2, depth 1, height 3, and width 0 is: " << f << endl; //Display the size of the arrays cout << "The size of iarray is: " << iarray.Size() << endl; cout << "The size of farray is: " << farray.Size() << endl; cin.get(); return 0;}[/source]
Edited by ISDCaptain01, 07 December 2012 - 11:44 PM.
#14 Marketplace Seller - Reputation: 8957
Posted 08 December 2012 - 01:03 AM
Your first example and second example aren't equivalent.Why aren't you just using
int array[3][4][5][6]; //or std::vector< std::vector< std::vector< std::vector< /*your Type*/ > > > > array;
Using a naked C++ array is usually bad for this and even if you have to if you use only one array you end up with a uniform grid like array only, jagged arrays wouldn't be possible you would need to use a "type****" for that and the just looks ugly.
While I agree with using an std::vector, I disagree with stacking them four deep.
A vector of a vector of a vector of a vector is not the same as a 4D array, in the same way that a vector of a vector is not the same as a 2D array, since each vector within the first vector aren't constrained to the same size (a so called 'jagged array' is an array of an array, not a 2D array).
If you have access to C++11, a std::array would constrain it to the same size.
When I want a multi-dimensional array, I use a single std::vector, and resize it to (width * height) or (width * height * depth), and index into it as Olof Hedman shows.
Edited by Servant of the Lord, 08 December 2012 - 01:04 AM.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal
#15 Marketplace Seller - Reputation: 8957
Posted 08 December 2012 - 01:17 AM
A few notes:
- Typically, people put the dimensions in the order (x,y,z,t) (width, height, depth, time). You seem to have them backward - which is fine, but unusual.
- You also declare alot of your temporary variables before their use in your Resize() function. This, while not quite punishable by death, is often considered bad practice.
Variables shouldn't be declared until the last moment they are needed, unless you have a reason for doing otherwise. And if you do declare them in advance, they should at least be initialized. Where you declare temporary x,y,z,t in your Resize() function you accidentally declare 'x' twice instead of 'z'. - Your 'Get()' function doesn't check to make sure the parameters are within range - that may be intentional though. The standard library typically provides two accessing methods - the subscript operator [], which doesn't check for range (used for extra speed when you are iterating and are confident you don't go over), and a 'at()' function that does check range.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal
#16 Crossbones+ - Reputation: 1064
Posted 08 December 2012 - 06:35 AM
Yep. Also, when you do that, a small indexing function can be very helpful. Easy to get variations of "x + y*width + "z*height*width + w*height*width*depth" wrong in individual accesses, much clearer when you have "array[idx(0, 0, arg, time)]" and so on.When I want a multi-dimensional array, I use a single std::vector, and resize it to (width * height) or (width * height * depth), and index into it as Olof Hedman shows.






