Search code examples
javaalgorithmcentroid

Centroid of matrix


Given a 2D array, I am required to come up with an algorithm which outputs the center of mass. I came up with algorithm below, however, it is producing incorrect solution when the array size is increased to 10 x 10 matrix. I wrote and ran the algorithm using java. I have not provided the codes here, but just an explanation of my algorithm as i feel that it is not right. However, I am unable to find out why.

Store into an array: Mean of each row
Store into an array: Mean of each column

The algo below is used for row and column:
Loop through the row array,
if(row = 1){
value = (mean of row 1) - (mean of row 2 + mean of row 3+ mean of row 4)
}else if(row =Length of array){
value = (mean of row 1 + mean of row 2 + mean of row 3) - (mean of row 4)}
else{
value = (mean of rows until ith row) - (ith row till end of array)
}
final value = lowest value;

I know that it is supposed to deal with mean of the rows and columns. So in my algorithm, i find out the means of rows and columns and then conduct the calculation shown above. The same algo applies to the columns.

Any and all help is appreciated. Maybe, my understanding of center of mass is incorrect. If something is not clear, then do ask. This is my own algorithm, created from my understanding of center of mass, so if its not clear, please do ask. Thank you!


Solution

  • Expanding on my comment, you should be able calculate the center of mass as follows:

    foreach col 
      foreach row
        massvector.x += matrix[col][row] * col
        massvector.y += matrix[col][row] * row
        totalmass += matrix[col][row]
    massvector.x /= totalmass    
    massvector.y /= totalmass
    

    The idea is based on the section "A system of particles" in https://en.wikipedia.org/wiki/Center_of_mass: treat the matrix elements as equally spaced particles laid out on a 2D plane. The position of each element is equal to its position within the matrix, i.e. column and row, while the particle mass is the value of that cell/element/matrix position.

    Example-Implementation using your (now deleted) test case:

    double[][] matrix = new double[][]{
        {0.70,0.75,0.70,0.75,0.80},
        {0.55,0.30,0.20,0.10,0.70},
        {0.80,0.10,0.00,0.00,0.80},
        {0.70,0.00,0.00,0.00,0.80},
        {0.80,0.90,0.80,0.75,0.90}};
    
    double cx = 0;
    double cy = 0;
    double m = 0;
    
    for(int x = 0; x < matrix.length; x++ ) {
      for(int y = 0; y < matrix[x].length; y++) {
        cx += matrix[x][y] * x;
        cy += matrix[x][y] * y;
        m += matrix[x][y];
      }
    }
    
    //those are center's the cell coordinates within the matrix
    int cmx = (int)(cx/m); 
    int cmy = (int)(cy/m);
    
    //whatever you'd need that value for (the position is more likely what you're after)
    double centerOfMassValue = matrix[cmx][cmy];
    

    The example above would return coordinates 2/2 with is the center of the 5x5 matrix.