I'm working on some simulation of gas particles.
My problem is that I made 3 two-dimensional integer tables. One for pressure value of particle, and another two to describe x and y movement of particle.
Although I make arraycopy and clone it still somehow manage to change values in global table
private void translate() {
int [][] VectorXBuff = new int[500][500];
System.arraycopy(VectorX.clone(), 0, VectorXBuff, 0, VectorX.length);
int [][] VectorYBuff = new int[500][500];
System.arraycopy(VectorY.clone(), 0, VectorYBuff, 0, VectorX.length);
int [][] FieldBuff = new int[500][500];
System.arraycopy(FieldMatrix.clone(), 0, FieldBuff, 0, VectorX.length);
for (int y = 0; y < FieldMatrix.length; y++){
for (int x = 0; x < FieldMatrix.length; x++){
if(FieldBuff[x][y]!= 0 && FieldBuff[x][y]!= 9 ){
FieldBuff[x + VectorXBuff[x][y]][y + VectorYBuff[x][y]] = Integer.valueOf(FieldBuff[x][y]);
FieldBuff[x][y] = 0;
VectorXBuff[x + VectorXBuff[x][y]][y + VectorYBuff[x][y]] = Integer.valueOf(VectorXBuff[x][y]);
VectorYBuff[x + VectorXBuff[x][y]][y + VectorYBuff[x][y]] = Integer.valueOf(VectorYBuff[x][y]);
VectorXBuff[x][y] = 0;
VectorYBuff[x][y] = 0;
}
}
}
}
This is because you only copy one dimension of your two dimension array. So you are still referencing the same arrays and therefore modifying it in the original one.
Basically, you have a source object [[1,2],[3,4]] and when you do a copy you are copying the pointer to [1,2] and [3,4] into a new array.
As the clone does a shallow copy (check Does calling clone() on an array also clone its contents?) this in the end resumt to just creating another array of the exactly same instances of arrays in memory.
Related
I am trying to make a game where the player can only see in a small radius around them. i'm attempting to do this by covering a 500X500 display with 1X1 black pixels that i can set active or inactive. The problem is that using a standered for loop to add them takes a large amount of time when the program launches and it slows the entire thing down. Any Solutions?
the pix object takes two paramaters(int x, int y)
code
public ArrayList<Pix> pixs= new ArrayList<>();
for(int i = 0; i<=500; i++)
{
for(int ii = 0; ii<=500; ii++)
{
pixs.add(new Pix(ii,i));
}
}
You are constructing 250000 instances of your Pix class. That will take some time.
Consider having a 2 dimensional array of booleans instead. Where false means the pixel is black.
You don't need to initialize the values yourself as they will default to false.
boolean[][] pixs = new boolean[500][500];
You can iterate over the structure with this:
for (int x = 0; x < 500; x++) {
for (int y = 0; y < 500; y++) {
System.out.println(pixs[x][y]);
}
}
And you can set a particular pix with
int x = 232;
int y = 455;
pixs[x][y] = true;
I'm working with a 2D array and what I'm trying to do in the below method is swap two values. The 'currentBoard' variable is a 2D array that needs should not be edited. The 'cpy' variable a duplicate of the 'currentBoard' and needs its variables to be changed. 'nbt' and 'bt' are 1D arrays that used to point to an index in the 2D array. The code for the function 'copyBoard' is always below if it helps
The issue I'm having is that at on the line marked with ** when the value in the 'cpy' array is changed for some reason the value in 'currentBoard' is being changed as well. I really can't figure out why this is happening....
private void Swap(int[] nbt, int[] bt, ArrayList<State> children, String direction) {
int[][] cpy = copyBoard(currentBoard);
int temp = cpy[nbt[0]][nbt[1]];
**cpy[nbt[0]][nbt[1]] = currentBoard[bt[0]][bt[1]];
cpy[bt[0]][bt[1]] = temp;
children.add(new Board(cpy, this.getGOAL(), this.getRows(), this.getColumns(), (this.getDirections() + direction + ", ")));
}
In case it helps here is the values that are assigned to the variables at the point when the code is on the line marked with **
nbt = {1, 0}
bt = {0, 0}
private int[][] copyBoard(int[][] state)
{
int[][] returnArray = new int[rows][columns];
for (int i = 0, j = 0; i*j < PUZZLE_SIZE; i++, j++)
{
returnArray[i] = state[i];
}
return returnArray;
}
A 2D array is an array of references to arrays. So if you assign returnArray[i] = state[i], you are simply making returnArray[i] refer to the same array that state[i] refers to. Thus, modifying returnArray[i][j] will modify the j'th element of whatever state[i] was. You have to create a deep copy of the "rows", too, e.g.:
private int[][] copyBoard(int[][] state)
{
int[][] returnArray = new int[rows][columns];
for (int i = 0, j = 0; i*j < PUZZLE_SIZE; i++, j++)
{
// deep copy of row:
returnArray[i] = Arrays.copyOf(state[i], state[i].length);
}
return returnArray;
}
Check out this short write-up on 2D arrays, it should give you a better idea of what's going on here. In particular, this little image, which represents int nums[][] = new int[5][4] (although it makes more sense in context):
By the way, your loop logic looks a little odd to me; even if the math happens to work out in your situation, it is a bit clearer to do this instead:
for (int i = 0; i < rows; i++)
Or more generally:
for (int i = 0; i < returnArray.length; i++)
These, of course, assume that state.length == rows; but you get the idea.
Method calculating percentages (from array which I don't want to be changed but it is):
private float values[] = { AGREE, DISAGREE };
private float[] calculateData(float[] data) {
// TODO Auto-generated method stub
float total = 0;
for (int i = 0; i < data.length; i++) {
total += data[i];
}
// 180 is the amount of degrees of the circle - setting it up to half
// circle 360 means full circle
for (int i = 0; i < data.length; i++) {
data[i] = 180 * (data[i] / total);
}
Calling the method:
float[] degrees = calculateData(values);
If I log the values of array before this method was called I get 1.0,1.0 but after method was called I get 90.0,90.0 why? If I don't change values[].
I know that it is happening here in that method because when I remove it I get 1.0,1.0 (what I actually want to get)
EDIT:
Thank you for the answers so if I understand it correctly: if parameter of the method is changed also the object set to be parameter, when method was called, becomes changed.
You are modifying your array here: data[i] = 180 * (data[i] / total);
You get the address of the array in the parameter of your function, not a copy of it, so if you modify it in your function, it will modify the array you passed when walling your calculateData function.
You are modifying the array in the second for
Array variables are just references. If you pass values as data, data points to the same array as values. Consider the following example:
int[] a = new int[] {1, 2, 3};
int[] b = a;
b[0] = 4;
// a is now {4, 2, 3}
If you don't want this, you need to make a copy:
Make copy of array Java
You need a new array inside your method like newData in the code below, which you need to return from a method:
private float[] calculateData(float[] data) {
float[] newData;
float total = 0;
for (int i = 0; i < data.length; i++) {
total += data[i];
}
for (int i = 0; i < data.length; i++) {
newData[i] = 180 * (data[i] / total);
}
return newData;
}
I have a COM method I'm trying to invoke, where there's an argument of type 'object' which must be a 2D double safe array, a collection of lat/long points. How can I create a SafeArray in JACOB to send through the COM interface?
I've tried just passing a 2D array as an object in the object list. The method doesn't return error, but I do not see the results I expect in FalconView (rendering of the polygon).
double polyPoints[][] = new double[5][2];
polyPoints[0][0] = 75.3;
polyPoints[0][1] = 4.5;
polyPoints[1][0] = 3.8;
polyPoints[1][1] = 4.8;
polyPoints[2][0] = 2.3;
polyPoints[2][1] = 2.5;
polyPoints[3][0] = 5.3;
polyPoints[3][1] = 6.5;
polyPoints[4][0] = 0.3;
polyPoints[4][1] = -1.5;
// Can't recreate Variant or SafeArray from double[x][y] array;
Object[] polygonArgs = new Object[] {m_mainLayerHandle, polyPoints, 1};
Variant returnAddPolygon = Dispatch.invoke(mainLayerDispatch, "AddPolygon", Dispatch.Method, polygonArgs, new int[1]);
System.out.println("Polygon Handle: " + returnAddPolygon.getInt());
Object[] refreshArgs = new Object[] {m_mainLayerHandle};
Variant refreshVariant = Dispatch.invoke(mainLayerDispatch, "Refresh", Dispatch.Method, refreshArgs, new int[1]);
The second arument documentation:
lat_lon_array
a two dimensional SAFEARRAY of doubles. The first dimension contains the latitude values. The second dimension contains the longitude values
It seems that SafeArray supports 1 Dimensional, 2 Dimensional, and N-Dimensional arrays using some somewhat unclear constructors. Given the 2D double array I created above, I was able to copy the data in to a 2D Double Safe Array. It would certainly be more efficient to create the double[][] up front, but I'm doing this in some prototype code. There may be ways to copy entire arrays in to the safe array... I am not sure.
// 2D array of type double. First dimension size 5, second dimemnsion size 2.
SafeArray safeArray = new SafeArray(Variant.VariantDouble, 5, 2);
for(int i = 0; i < 5; i++) {
for (int j = 0; j < 2; j++) {
// set the value of safearray[i][j] to value polyPoints[i][j]
safeArray.setDouble(i, j, polyPoints[i][j]);
}
}
I'm using an FFT class I found online to compute the FFT of an image. Here's the code to compute the FFT.
w (width) and h (height) are the same value in this instance.
FFT2 fft = new FFT2(w);
double[] realRow = new double[w];
double[] imagRow = new double[w];
double[][] realVals1 = new double[w][h];
double[][] imagVals1 = new double[w][h];
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
pixel = bmporiginal.getPixel(x, y);
R = (int) (Color.red(pixel));
G = (int) (Color.green(pixel) );
B = (int) (Color.blue(pixel));
I = ((R+G+B)/3);
I *= Math.pow(-1, (x+y) % 2.0 );
realRow[x] = I;
imagRow[x] = 0.0;
}
fft.fft(realRow, imagRow);
realVals1[y] = realRow;
imagVals1[y] = imagRow;
}
The values I need are being stored in realVals and ImagVals. I can print these values within the for loop and get good values. After leaving the for loops I print them again, and get nothing!!! What could be the problem? I appreciate your help!
You're reusing the same row arrays for every iteration of the loop.
So at the end of the two loops, your realVals1 and imagVals1 will each have h references to the same array. You need to create a new array on each iteration of the outer loop:
for (int y = 0; y < h; y++)
{
double[] realRow = new double[w];
double[] imagRow = new double[w];
for (int x = 0; x < w; x++)
{
...
}
fft.fft(realRow, imagRow);
realVals1[y] = realRow;
imagVals1[y] = imagRow;
}
Additionally, I believe your declarations for realVals1 and imagVals1 are a) inefficient and b) the wrong way round. I suspect you want:
double[][] realVals1 = new double[h][];
double[][] imagVals1 = new double[h][];
You're going to be replacing the elements anyway, so there's no point in populating a bunch of empty rows...
You're reusing the same array realRow and imagRow each time through the inner loop. Since Java works with references, when you assign realVals1[y]=realRow, you assign a reference. Since you always use the same array, you assign all the rows to the same array reference. Which is not what you want. You need to recreate realRow and imagRow to a new double[] at the top of the outer for loop.