|
Author |
Topic: Expand! Expand! (aren't dynamic arrays troubling?) (Read 1419 times) |
|
st33d
|
Expand! Expand! (aren't dynamic arrays troubling?)
« on: Aug 6th, 2004, 9:21pm » |
|
In a previous post I asked a question about this piece of code which expands the length of an array named x[]: Code: int []x=new int [1]; void setup(){ x[0]=1; //x[x.length]=1; } void draw(){ newLength(x[x.length-1]); println(x[0]); println(x[1]); println(x.length); } void newLength(int newx) { int[] tempx = new int[x.length + 1]; System.arraycopy(x, 0, tempx, 0, x.length); tempx[x.length] = newx; x = tempx; } |
| Could I expand an array with two dimensions? x[][] for example. How would I increment either dimension? Narrain helpfully replied with what made this code: Code: int [][] x=new int [1][1]; void setup(){ x[0][0]=1; } void draw(){ println(x[0][0]); println(x[0][0]); extend1(x[x.length-1]); println(x[1][0]); extend2(); println(x[1][1]); println(x.length); } void extend1 (int[] newx) { int[][] tempx = new int[x.length+1][]; System.arraycopy(x, 0, tempx, 0, x.length); tempx[x.length] = newx; x = tempx; } void extend2 () { for (int i = 0; i < x.length; i++) { int[] xi = x[i]; int[] tempxi = new int[xi.length + 1]; System.arraycopy(xi, 0, tempxi, 0, xi.length); x[i] = tempxi; } } |
| Great stuff. And put to use in my pattern generator to help me track bugs and my dyslexic code. It's much easier to spot mistakes when you can watch the computer work. I used the two dimensional array to create a log of lines. The first dimension stored the iteration count and the second dimension held eight numbers (a bezier curve). I think I can expand this program to work with paths as opposed to lines. Which means a chain of beziers. Array [iteration][iteration within path][bezier information] was my solution to approaching this. However, things aren't so straight forward. The rules have changed again. The following code doesn't work. And I don't know why. Is it possible to make x[][][] dynamic or not? I only need to work with the first two dimensions, but how far does this problem extend? Code: int [][][] x=new int [1][1][1]; void setup(){ x[0][0][0]=1; } void draw(){ println(x[0][0][0]); println(x[0][0][0]); extend1(x[x.length-1]); println(x[1][0][0]); extend2(); println(x[1][1][0]); println(x.length); } void extend1 (int[] newx) { // newx is what to put in the new locations int[][] tempx = new int[x.length+1][]; System.arraycopy(x, 0, tempx, 0, x.length); tempx[x.length] = newx; x = tempx; } void extend2 () { for (int i = 0; i < x.length; i++) { int[] xi = x[i]; int[] tempxi = new int[xi.length + 1]; System.arraycopy(xi, 0, tempxi, 0, xi.length); x[i] = tempxi; } } |
|
|
I could murder a pint.
|
|
|
narain
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #1 on: Aug 7th, 2004, 6:55am » |
|
I'm afraid expanding arrays just doesn't scale to higher dimensions very well... Maybe you'll be better off using objects, like I suggested before, instead of just packing all your parameters into a single array. arielm has made a great tutorial on object-oriented programming at http://p5.chronotext.org/tutorials/motion_oop/ I highly recommend using objects for the kind of thing you're doing. Once you get up to speed with it (which won't take much time at all thanks to ariel's tutorial), it'll make your coding a lot easier. Check out http://processing.org/discourse/yabb/board_Syntax_action_displa_y_num_1091723111.html for an example of before-and-after code following ariel's tutorial.
|
« Last Edit: Aug 7th, 2004, 6:57am by narain » |
|
|
|
|
st33d
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #2 on: Aug 7th, 2004, 4:19pm » |
|
My pattern generator takes a line from the log, alters it and then passes it back into the log as a new entry. I would need object/s which would expand. The tutorial doesn't cover this and I haven't found a post which covers this yet. The basic version which deals only with lines is here: http://www.st33d.net/processing/pattern5/pattern5.pde I post a link instead of code because it's quite large for a forum post and it's easier to watch what is does first before reading it. It creates lines when the "play" button is held. It is prevented from clustering lines by an array which records population of grid areas (the gray lines). You can see the occupation of the array by pressing pause. It crashes if the screen is too populated. I couldn't be bothered to write a fail safe because I already know when it crashes. The save button exports an illustrator file of the lines drawn on screen. I know there's some for loops in there I could implement but the debug session turned into a magical mystery tour. The latest version of this code which tries to deal with paths is here. With the higher dimension array installed and not working beautifully. http://www.st33d.net/processing/pattern53/pattern53.pde I'm not suggesting anyone post a rewrite (unless you have your own space as well and too much spare time). But I would ask how I create objects dynamically. My big problem is the lack of a fixed quantity. Unsightly the look of a memory gobbler may be, it allows me to find out what sort of quantities I'm going to expect when I develop the work further. I need an open ended system to continue the research.
|
I could murder a pint.
|
|
|
narain
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #3 on: Aug 8th, 2004, 6:17am » |
|
Um... I just meant, put the bezier information in objects, and make a 2D array of these objects. So you don't need higher-dimension expansion. I looked at the code in your first post again, though, and I think it probably can be made to work. There were a lot of type errors (int[] where int[][] should be, and other such things) and probably an uninitialised array somewhere. But considering it's terribly confusing, wouldn't it be easier just to switch to a 2D array of objects? If I were you, actually, I'd make a simple array of Path objects, and each Path object would contain an array of Bezier or Point objects or something like that. To add another path, you just extend the Path array. To add lines to one path, you call a method of the Path object that extends its internal array. Makes for better code organization, IMO. But, well, it's your code after all. Do what works for you. (BTW, your pattern53 applet isn't running. The Java console says File Not Found: pattern4.jar. And my name is Narain, not Narrain. )
|
|
|
|
st33d
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #4 on: Aug 8th, 2004, 3:13pm » |
|
Um.. and I said how do I create objects dynamically. I tried applying an array extension to an object and it didn't like it. (Getting names wrong and bracket madness are just what happens when I'm stuck in front of a keyboard. Typing of the Dead doesn't work on my computer recently so I haven't finished my touch type training. Pattern53 doesn't work anyway and if I'm changing the log into objects it's an irrelevant bit of code now.) Here's my attempt at what you said, making another object on the fly by extending its array length. I'm guessing internal extension shouldn't be problematic but the code for expanding an array doesn't work with object arrays because objects aren't variables. So how do I call them for expansion? Code: test[] x; void setup(){ x=new test[1]; x[0].thing1=1; } void draw(){ newLength(x[x.length-1]); x[0].plus(); println(x[0].thing1); println(x[1].thing1); println(x.length); } class test{ int thing1; test (int thing2){ thing2=thing1; } void plus(){ thing1++; } } void newLength(int newx) { int[] tempx = new int[x.length + 1]; System.arraycopy(x, 0, tempx, 0, x.length); tempx[x.length] = newx; x = tempx; } |
|
|
I could murder a pint.
|
|
|
TomC
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #5 on: Aug 8th, 2004, 7:36pm » |
|
OK, some syntax things to get you on your way. newLength is a function which takes an integer, and adds that integer to the end of a new array of integers called tempx. It then assigns tempx to x, but x is an array of 'test' objects. So you need to make newLength work on some test objects. The constructor for your test class takes an integer, and then assigns a new value to it. You probably meant to assign the value of thing2 to the test instance's member variable, thing1? When you make an array of objects, e.g. x = new test[1];, all that does is create some 'empty boxes' in memory. It doesn't initialise the objects themselves. So you need to do x[0] = new test(1); instead of x[0].thing1 = 1; because the latter will give a null pointer exception until you have assigned something to x[0]. The main mistake you're making though is mixing up an array of test objects with an array of ints. That won't work.
|
|
|
|
st33d
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #6 on: Aug 8th, 2004, 11:29pm » |
|
Yup, okay. I'm new to object arrays I'll admit I got the initialisation of the object wrong. However: Quote: me: but the code for expanding an array doesn't work with object arrays because objects aren't variables. So how do I call them for expansion? |
| I'm sorry about all the fuss but I need to make new objects on the fly. How do you do it?
|
I could murder a pint.
|
|
|
TomC
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #7 on: Aug 9th, 2004, 10:19am » |
|
In this case, tempx should be an array of test objects - or whatever class you're using - not ints.
|
|
|
|
st33d
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #8 on: Aug 11th, 2004, 7:14pm » |
|
Nope, sorry. I still don't get it. Now it doesn't want me to set up the object anywhere. Code: test[] x; test[] tempx; x[0] = new test(1); void setup(){ } void draw(){ newLength(x[x.length-1]); x[0].plus(); println(x[0].thing1); println(x[1].thing1); println(x.length); } class test{ int thing1; test (int thing2){ thing2=thing1; } void plus(){ thing1++; } } void newLength(test newx) { tempx = new test[x.length + 1]; System.arraycopy(x, 0, tempx, 0, x.length); tempx[x.length] = newx; x = tempx; } |
|
|
I could murder a pint.
|
|
|
fjen
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #9 on: Aug 11th, 2004, 10:35pm » |
|
Code: class test{ int thing1; test (int thing2){ thing2=thing1; } } |
| this seems to be wrong ... if you set thing2 = thing1 it will end somewhere in nirvana. thing2 is the value incoming, i guess you wanted to set thing1 = thing2, right?
|
|
|
|
fjen
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #10 on: Aug 11th, 2004, 10:42pm » |
|
is this what you wanted? Code: test[] x = new test[1]; test[] tempx; void setup() { size(100,100); x[0] = new test(1); } void draw(){ newLength(x[x.length-1]); x[0].plus(); println(x[0].thing1); println(x[1].thing1); println(x.length); } class test{ int thing1; test (int thing2){ thing1=thing2; } void plus(){ thing1++; } } void newLength(test newx) { tempx = new test[x.length + 1]; System.arraycopy(x, 0, tempx, 0, x.length); tempx[x.length] = newx; x = tempx; } |
|
|
|
|
|
st33d
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #11 on: Aug 12th, 2004, 9:18pm » |
|
Actually no. What I was hoping for is something like this: Code: table[] x = new table[1]; table[] tempx; void setup() { size(100,100); x[0] = new table(1); } void draw(){ newLength(x[x.length-1]); println(x.length); println(x[0].ax[0][0]); x[0].extend1(x[0].ax[x[0].ax.length-1]); println(x[0].ax[1][0]); newLength(x[x.length-1]); println(x.length); x[0].extend2(); println(x[0].ax[1][1]); } class table{ int [][] ax=new int [1][1]; table (int bx){ ax[0][0]=bx; } void extend1 (int[] newax) { int[][] tempax = new int[ax.length+1][]; System.arraycopy(ax, 0, tempax, 0, ax.length); tempax[ax.length] = newax; ax = tempax; } void extend2 () { for (int i = 0; i < ax.length; i++) { int[] axi = ax[i]; int[] tempaxi = new int[axi.length + 1]; System.arraycopy(axi, 0, tempaxi, 0, axi.length); ax[i] = tempaxi; } } } //end of class void newLength(table newx) { tempx = new table[x.length + 1]; System.arraycopy(x, 0, tempx, 0, x.length); tempx[x.length] = newx; x = tempx; } |
| Thanks very much all. It's almost a dynamic three dimensional array. That pretty much answers the question and allows me to work on dynamic little robots now. A final thought would be how processing would integrate with some kind of database which would probably be a lot less tricky than all this array juggling. But it's cool that dynamic three dimensional arrays are on the scene.
|
I could murder a pint.
|
|
|
TomC
|
Re: Expand! Expand! (aren't dynamic arrays troubli
« Reply #12 on: Aug 12th, 2004, 10:18pm » |
|
Glad you've got your head around it For the record, I seriously recommend you take a look at the extensible array classes in Java, such as Vector, and try and use objects (classes) to encapsulate data, rather than tables. At the very least, programming in a typically Java-ish way will mean there are more people who will get what you're trying to do and be able to help In this case, you have a variable-length collection of variable length collections of 2 integers? (List of lists of points). Here's objecty/vectory code which does something similar, for comparison. It lets you draw lines with the mouse, recording the position in each frame into a Point2f class, and adding each point to a Vector of points contained in a Line class contained in a Vector of lines. Note that the melt function in the Line class demonstrates removing elements from a Vector. Hit space to melt the lines. Code: Vector lines = new Vector(); // for recording the mouse Line newLine; void setup() { size(640,480); } void loop() { background(0); if (mousePressed) { if (newLine == null) { // start a new line newLine = new Line(); lines.addElement(newLine); } // record the current mouse position newLine.points.addElement(new Point2f(mouseX,mouseY)); } else if (newLine != null) { // set finished newLine.finished = true; // clear the line newLine = null; } for (int i = 0; i < lines.size(); i++) { Line line = (Line)lines.elementAt(i); line.draw(); if (keyPressed) { line.melt(); } } } class Point2f { float x,y; Point2f() { x = y = 0; } Point2f(int x, int y) { this.x = x; this.y = y; } } class Line { Vector points = new Vector(); boolean finished = false; void draw() { if (points.size() >= 2) { for (int j = 0; j < points.size()-1; j++) { float proportion = float(j) / points.size(); stroke(255.0*proportion); Point2f a = (Point2f)points.elementAt(j); Point2f b = (Point2f)points.elementAt(j+1); line(a.x,a.y,b.x,b.y); } } } // moves the points towards their average location, purges points above 250, clears points on !mousePressed void melt() { if (points.size() >= 2) { float averageX = 0; float averageY = 0; for (int j = 0; j < points.size(); j++) { Point2f a = (Point2f)points.elementAt(j); averageX += a.x; averageY += a.y; } averageX /= points.size(); averageY /= points.size(); for (int j = 0; j < points.size(); j++) { Point2f a = (Point2f)points.elementAt(j); if (points.size() > 250) { points.removeElement(a); } else { a.x += (averageX - a.x) / 100.0; a.y += (averageY - a.y) / 100.0; } } if (finished) { Point2f a = (Point2f)points.elementAt(0); points.removeElement(a); } } else if (points.size() == 0) { lines.removeElement(this); } } } |
|
|
« Last Edit: Aug 12th, 2004, 10:25pm by TomC » |
|
|
|
|
|