FAQ
Cover
This is the archive Discourse for the Processing (ALPHA) software.
Please visit the new Processing forum for current information.

   Processing 1.0 _ALPHA_
   Programming Questions & Help
   Syntax
(Moderators: fry, REAS)
   Duplicating an array
« Previous topic | Next topic »

Pages: 1 
   Author  Topic: Duplicating an array  (Read 383 times)
inadaze


Duplicating an array
« on: Nov 17th, 2004, 1:31am »

Hi,
I have an array called pointArray[] that has 3 sets of 3 points for a total of 9 points one after another in the array.  I would like to duplicate this array so that i can manipulate the data without changing where the points are on the screen.  So I thought I would create another array called resultPointArray[] that would have all the same data but if I changed the Xpos and Ypos it would not affect the first pointArray[] and therefore the points would not move on the screen.  But for some reason the first point in each set of three does move.  Does my second array control my first if my code is like this?
(maxNumberPoints is 9)
 
 
  int firstPoint = 0;
 
  void createDuplicateArray(){
  for(int i=0; i < currentGame.maxNumberPoints;i++)  {
    resultPointArray[i] = currentGame.pointArray[i];
    }
  for(int i=0; i < currentGame.maxNumberPoints;i++)  {
  if(i<3){
  this.firstPoint = 0;
  }else if(i>=3 && i < 6){
  this.firstPoint = 3;
  }else if(i>=6 && i < 9){
  this.firstPoint = 6;
  }
    resultPointArray[i].Xpos = currentGame.pointArray[i].Xpos - currentGame.pointArray[this.firstPoint].Xpos;
    resultPointArray[i].Ypos = currentGame.pointArray[i].Ypos - currentGame.pointArray[this.firstPoint].Ypos;  
     
  }
  }
 
i know it's kind of messy but that's because i keep trying to fix it and i end up making it worse.
 
Thanks
Jay
 
_C


Re: Duplicating an array
« Reply #1 on: Nov 17th, 2004, 2:04am »

maybe clone does it:  
 
int source[] = new int[6];
int target[] = (int [])target.clone();
 
( this is a flat copyin of the source array )
 
greets
c
 
TomC

WWW
Re: Duplicating an array
« Reply #2 on: Nov 17th, 2004, 11:47am »

Firstly, I think you meant source.clone().
 
Secondly, it's probably better to use System.arraycopy().
 
Simple reason:  It's to do with the difference between a deep copy and a shallow copy.  A deep copy (what we want here) will have independent storage, and modifications to the copy will not affect the original.  A shallow copy will use the same data, and modifications to the copy will affect the original.
 
To make a deep copy of a whole array:
 
Code:

 
// the array to be copied:
int[] source = new int[10];
// make a new array of the same type, of the same length or longer
int[] target = new int[source.length];
// starting at source[0] and target[0] copy source.length elements from source to target:
System.arraycopy( source, 0, target, 0, source.length );
 

 
Complicated reason: (Deep breath) clone() on arrays is only a deep copy for one-dimensional arrays of primitive types (int, float, boolean, etc).  For two dimensional arrays, you'll get a mixed up kind of shallow copy (modifications to the clone's data will affect the original).  For one-dimensional arrays of Objects, the clone will also be shallow.  Also, last time I checked, clone was slower than System.arraycopy(), which is why it's the preferred way to get a deep copy of an array.  (It could just be the cast which was slow, so for large arrays like pixels, it might be worth benchmarking clone against arraycopy).  But arraycopy is safer and more flexible (it can also copy ranges).
 
Hope that's clear.
« Last Edit: Nov 17th, 2004, 11:58am by TomC »  
TomC

WWW
Re: Duplicating an array
« Reply #3 on: Nov 17th, 2004, 12:05pm »

To answer the original poster, this code is where it's going a bit wrong:
 
Code:

for(int i=0; i < currentGame.maxNumberPoints; i++) {  
  resultPointArray[i] = currentGame.pointArray[i];  
}  

 
When you put an Object in an array, the array doesn't actually contain the data, it just contains a reference which says where the data is.  When you copy an element of an array using =, you just copy the reference.  So the two arrays will both be referring to the same data (a shallow copy).  You should be using System.arraycopy here to get a deep copy.
 
_C's use of clone would also have given you a shallow copy, because you're dealing with an array of Objects.
 
Hope that's clear
« Last Edit: Nov 17th, 2004, 12:05pm by TomC »  
fjen

WWW
Re: Duplicating an array
« Reply #4 on: Nov 17th, 2004, 4:46pm »

i totally second tom's post(s), but i remember this article that states that arraycopy is not in all cases the fastest. in the end we just have to test every time i guess ...
 
/F
 
TomC

WWW
Re: Duplicating an array
« Reply #5 on: Nov 17th, 2004, 5:07pm »

Yeah, I think those benchmarks are interesting, but dubious.  e.g. they create new objects with every loop, so I would be cautious about doing them in the same order every time.  They are also only copying a short int array, and not Objects.  They are also not dated, and don't say what Java version they're using.
 
Any volunteers to port to processing, and try with some longer arrays (pixels length, at least)?
 
 
fjen

WWW
Re: Duplicating an array
« Reply #6 on: Nov 17th, 2004, 5:42pm »

sure. one for all ..
 
i'll port/check once i have my alice 2.0 importer finished (today).
 
/F
 
TomC

WWW
Re: Duplicating an array
« Reply #7 on: Nov 17th, 2004, 5:52pm »

Cool.  Does this work with all my Processing wishes?
 
Any volunteers to write a full-spec X3D/VRML browser, complete with scripting?  And hardware acceleration?
 
fjen

WWW
Re: Duplicating an array
« Reply #8 on: Nov 17th, 2004, 6:25pm »

sure, the cutomer is king ... at least that's what the sign i'm looking at says. .. hihi.
 
/F
 
michael05

WWW
Re: Duplicating an array
« Reply #9 on: Nov 17th, 2004, 8:03pm »

we are working on a java3d api for processing and will release a preview soon.
 

°°°°°°°°°°°°°°°°°°°°
http://www.m05.de
inadaze


Re: Duplicating an array
« Reply #10 on: Nov 18th, 2004, 8:54pm »

Thanks, that worked just fine...so far.
But I was wondering why I must write this:
 
System.arraycopy(source, 0, target, 0, source.length);
 
instead of this:
 
System.arraycopy(source[], 0, target[], 0, source[].length);
 
I thought that you needed "[]" to get something out of the array.  Or is that only when you need a specific element from it?
 
Thanks
Jay
 
inadaze


Re: Duplicating an array
« Reply #11 on: Nov 18th, 2004, 9:18pm »

....And it still does not work properly.
 
When I modify the target it modifies the source.  
I am trying to change the x and y positions of the target without changing the positions of the source.  Because I am drawing the source on the stage and i don't want them to change.   But maybe I did something wrong:
 
  void createDuplicateArray(){
  // starting at source[0] and target[0] copy source.length elements from source to target:
 System.arraycopy(currentGame.pointArray, 0, resultPointArray, 0, currentGame.pointArray.length);  
 
  for(int i=2; i >= 0;i--)  {
    resultPointArray[i].Xpos = resultPointArray[i].Xpos - resultPointArray[this.firstPoint].Xpos;
    resultPointArray[i].Ypos = resultPointArray[i].Ypos - resultPointArray[this.firstPoint].Ypos;
  }
  }
 
For some reason it still changes the currentGame.pointArray[] x and y positions?
 
Jay
 
TomC

WWW
Re: Duplicating an array
« Reply #12 on: Nov 18th, 2004, 10:59pm »

Yes, you only need the square brackets when declaring an array or accessing an element in the array.
 
Can you show us how you are declaring and initialising the arrays?
 
If at any point you say:
 
Code:

resultPointArray = currentGame.pointArray;

 
Then this would cause the behaviour you describe.  (so don't do it )
 
At some point before you use arraycopy, reresultPointArray should be initialised as a new array, independently of currentGame.pointArray.
« Last Edit: Nov 18th, 2004, 10:59pm by TomC »  
inadaze


Re: Duplicating an array
« Reply #13 on: Nov 19th, 2004, 1:45am »

I don't see anything like that in the code.  
here is the only time i use the new array:
 
class RunComparison  {
 
  //Properties
  LinePoint[] resultPointArray = new LinePoint[currentGame.maxNumberPoints];
 
  //Constructor
  RunComparison()  {
 
  }
 
  //Methods
  //split the original array into three arrays
  void createDuplicateArray(){
    // starting at source[0] and target[0] copy source.length elements from source to target:
    System.arraycopy(currentGame.pointArray, 0, resultPointArray, 0, currentGame.pointArray.length);
 
    //Move all the lines to the origin to run a comparrison to stored data
    //Heat Line
    for(int i=2; i >= 0;i--)  {
 resultPointArray[i].Xpos = resultPointArray[i].Xpos - resultPointArray[0].Xpos;
 resultPointArray[i].Ypos = resultPointArray[i].Ypos - resultPointArray[0].Ypos;
 println(i);
 println("newX = " + resultPointArray[i].Xpos);
 println("newY = " + resultPointArray[i].Ypos);
 println("oldX = " + currentGame.pointArray[i].Xpos);
 println("oldY = " + currentGame.pointArray[i].Ypos);
    }
    /*
    //Head Line
    for(int i=5; i >= 3;i--)  {
 resultPointArray[i].Xpos = resultPointArray[i].Xpos - resultPointArray[3].Xpos;
 resultPointArray[i].Ypos = resultPointArray[i].Ypos - resultPointArray[3].Ypos;
    }
    //Life Line
    for(int i=8; i >= 6;i--)  {
 resultPointArray[i].Xpos = resultPointArray[i].Xpos - resultPointArray[6].Xpos;
 resultPointArray[i].Ypos = resultPointArray[i].Ypos - resultPointArray[6].Ypos;
    }*/
  }
   
  void testLinePlacement()  {
  // check if the heal of the hand angles out at the top
    if(currentGame.handArray[currentGame.maxNumberHandPoints-2].Xpos > currentGame.handArray[currentGame.maxNumberHandPoints-1].Xpos)  {
 //check and see how close the end of the heart and head line are to the end of the hand
 if(resultPointArray[2].Xpos - resultPointArray[2].size/2  < currentGame.handArray[currentGame.maxNumberHandPoints-2].Xpos &&  
 resultPointArray[2].Xpos - resultPointArray[2].size/2  > currentGame.handArray[currentGame.maxNumberHandPoints-2].Xpos - 20)  {
     println("You have a LONG heart line");
 }else{
   println("You have a SHORT heart line");
 }
 }else{
 println("The left side of your hand is on too much of an angle.  Please make sure that your hand print is straight");  
 }
  }
  /*
  void testCurves()  {
    //TEST to make sure the points are properly placed
    //produce ERROR if the points are either too high or too much to the left of
    //the first in the line.
    if(this.heartLine2X < this.heartLine1X || this.heartLine3X < this.heartLine1X ||
    this.headLine2X < this.headLine1X || this.headLine3X < this.headLine1X ||
    this.lifeLine2X < this.lifeLine1X || this.lifeLine3X < this.lifeLine1X ||
    this.heartLine2Y < this.heartLine1Y || this.heartLine3Y < this.heartLine1Y ||
    this.headLine2Y < this.headLine1Y || this.headLine3Y < this.headLine1Y ||
    this.lifeLine2Y < this.lifeLine1Y || this.lifeLine3Y < this.lifeLine1Y)  {
 println("Jay's ERROR: Please check the placement of your points on their lines.");
 println("The second and third points cannot be higher or to the left of the first point.");
    }else{
 changePointPos();
    }
  }*/
 
}
 
And in the end i call the function on a key press
 
if(key==' ')  {
 RunComparison myTest = new RunComparison();
 myTest.createDuplicateArray();
}
 
That's it.  I'd give you all my code to look at but the form here says that it's too long to post.
 
Thanks
Jay
 
Pages: 1 

« Previous topic | Next topic »