Author |
Message |
pizza
Joined: Jun 30, 2012 Posts: 2 Location: moon
|
Posted: Sat Jun 30, 2012 5:43 pm Post subject:
dynamic multidimensional array help |
|
|
my first post, but i've had a ton of questions answered by this forum's archives. thanks everyone.
i'd like to make a dynamic, 3d array for an animation application. something like
which would be initialized as
i want to expand the first dimension -- add more frames -- as we need them. but i can't figure out how to do this, or if it's even possible.
the /examples and versions file only treat 1 dimensional arrays, and i can't quite figure out these threads from a few years back:
playing with dynamic array
3d dynamic array
can anyone give a more clear picture of how to work with dynamic multidimensional arrays in chuck?
or if what i'm aiming for is impossible, any ideas on how to work around it?
thanks a lot! |
|
Back to top
|
|
|
Antimon
Joined: Jan 18, 2005 Posts: 4145 Location: Sweden
Audio files: 371
G2 patch files: 100
|
Posted: Sun Jul 01, 2012 5:03 am Post subject:
|
|
|
I'll start from the bottom, skip ahead until you reach the part that's causing you problems. :)
Coming from a more low-level programming background, I find it sometimes helps to think of these things as arrays containing arrays containing arrays, rather than something that has multiple dimensions.
So, a two dimensional array of integers can be thought of as an array where each element of the array is an array containing integers. So this:
int a[2][3];
is one array (a) containing two arrays (a[0] and a[1]) who, in turn, contain three integers each. All integers in a[0] and a[1] are initialized to zero by ChucK.
If we want to add another integer array so that the size becomes a[3][3], we can do that like this, using ChucK's push operator for adding elements at the end of an array:
a << [4,5,6];
Now there's a third array a[2], which contains the numbers 4, 5 and 6. a[0] and a[1] still both contain 0, 0, 0.
If we now want to add a third dimension, we'll be dealing with an array that contains arrays that in turn contain arrays of integers:
int q[0][3][3];
This new array is as of yet empty, since it was initialized with zero in the first size placeholder. We can make that size 1 by running this (using our previous array a):
q << a;
The size of q is now as if we had initialized it like this:
int q[1][3][3];
...though if we had initialized it like that it would be all zeroes, now it contains one "frame" (from your example) with the numbers that we put in a before.
I made some code to test that what I said above checked out, including it below. Hope this helps!
Code: | int line1[0];
line1 << 1;
line1 << 2;
// line1 now contains 1, 2, i.e. [1, 2]
int line2[0];
line2 << 3;
line2 << 4;
// line2: [3,4]
int line3[0];
line3 << 5;
line3 << 6;
// line3: [5,6]
int plane1[0][0];
plane1 << line1;
plane1 << line2;
// plane1 now is this:
// [ [1, 2],
// [3, 4] ]
int plane2[0][0];
plane2 << line2;
plane2 << line3;
// plane2 now is this:
// [ [3, 4],
// [5, 6] ]
int cube[0][0][0];
cube << plane1;
cube << plane2;
// cube now is this:
// [ [ [1, 2],
// [3, 4] ]
// [ [3, 4],
// [5, 6] ] ]
printCube(cube);
fun void printCube(int cube[][][]) {
for (0 => int i; i < cube.size(); i++) {
<<< "[" + i + "]:">>>;
printPlane(cube[i]);
}
}
fun void printPlane(int plane[][]) {
for (0 => int i; i < plane.size(); i++) {
<<< " [" + i + "]:">>>;
printLine(plane[i]);
}
}
fun void printLine(int line[]) {
" " => string printout;
for (0 => int i; i < line.size(); i++) {
if (i > 0) {
printout + ", " => printout;
}
printout + line[i] => printout;
}
<<< printout >>>;
}
|
_________________ Antimon's Window
@soundcloud @Flattr home - you can't explain music |
|
Back to top
|
|
|
Antimon
Joined: Jan 18, 2005 Posts: 4145 Location: Sweden
Audio files: 371
G2 patch files: 100
|
|
Back to top
|
|
|
pizza
Joined: Jun 30, 2012 Posts: 2 Location: moon
|
Posted: Mon Jul 02, 2012 3:31 am Post subject:
|
|
|
i got it!
and i get it!
antimon, thank you so much for your help. i learned a lot.
for posterity, this is how i expanded the array in my app (only two lines!):
Code: | int cel[1][16][8]; // a one frame stack of 16 by 8 frames
if (x == xmax - 1) // when the "add frame" button is pressed...
{
int newframe[16][8]; //create a 2D array, a blank frame
cel << newframe; //add it to our set of frames
}
// now, the size of "cel" is [2][16][8]
// if the button is pressed again, it becomes [3][16][8] |
interestingly, if i declare newframe at the start of the program, (after int cel, before if), cel will still expand, but not with unique data. in other words, you can add 9 frames, but frames 2-10 will all be identical. edits to frame 3 also change 2, 4, 5, etc. instantiating newframe every time the button is pressed seemed to fix that.
thanks again antimon! |
|
Back to top
|
|
|
Antimon
Joined: Jan 18, 2005 Posts: 4145 Location: Sweden
Audio files: 371
G2 patch files: 100
|
Posted: Mon Jul 02, 2012 9:56 am Post subject:
|
|
|
Glad that I could help.
Btw, judging from what you say happens, writing this:
int cel[1][16][8];
inside a block (i.e. some code that is enclosed within curly brackets, like the contents of your if statement or a function) will cause a new array to be created each time you enter that block, which is also inaccessible outside the block. If you write the same thing at root level - i.e. not enclosed by any curly brackets at all - it becomes a global variable that is initialized when the program starts, and stays the same throughout the program's life length.
This is different from, say, javascript (if you've hacked some of that), where a variable declared anywhere (with "var" in front of it) is available to either the whole function it was declared in, or if was declared outside a function, the whole program. _________________ Antimon's Window
@soundcloud @Flattr home - you can't explain music |
|
Back to top
|
|
|
|