05-26-2010 06:28 AM
Hello!
I want to make a sub-vi that calculates the centroid of the values in a 2D-Array (I32).
Input:
2D-Array (I32)
Output
CentroidX (I32 Integer)
CentroidY (I32 Integer)
I found this code on the web:
FUNCTION Centroid, array
ndim = Size(array, /N_Dimensions)
IF ndim NE 2 THEN BEGIN
Message, 'Array must be two-dimensional. Returning...', /Informational
RETURN, -1
ENDIF
s = Size(array, /Dimensions)
totalMass = Total(array)
xcm = Total( Total(array, 2) * Indgen(s[0]) ) / totalMass
ycm = Total( Total(array, 1) * Indgen(s[1]) ) / totalMass
RETURN, [xcm, ycm]
END
But I cannot determine what Indgen() and Total() do.
Can you guys give me some tips to help me on the way, this must be fairly easy.
Thx you in advanced an Kudo's will be given!
Solved! Go to Solution.
05-26-2010 09:45 AM
05-26-2010 10:22 AM
It will be quite difficult to figure out that code, because they use their own functions,
but dont show you the guts of the function.
Try the attached VI.
It will give you the centroid of 2D array.
X and Y are distances, assuming the top left corner is (0,0).
05-26-2010 10:29 AM - edited 05-26-2010 10:35 AM
Actually let me clarify what my function does.
It uses the index of each element as the distance, and the value of the element as a force.
Is this what you wanted it to do?
For example look at the following array:
2 1
8 6
There is a 2 (gram?) force acting 1 cm to the right and 1 cm below the origin.
There is a 1 g force acting 2 cm to the right and 1 cm below the origin.
There is a 8 g force acting 1 cm to the right and 2 cm below the origin.
There is a 6 g force acting 2 cm to the right and 2 cm below the origin.
You then calculate the centroid in the following way:
X = ( (2+8)*1 + (1+6)*2 ) / ( (2+8) + (1+6) ) = 1.294 cm
Y = ( (2+1)*1 + (8+6)*2 ) / ( (2+1) + (8+6) ) = 1.765 cm
05-26-2010 10:47 AM - edited 05-26-2010 10:55 AM
I think there may be a flaw in yours cory. If you put this array in from this link it doesn't give the right answer. Here is my crack at it. Might not be the most elegant. Who else wants to play???
Inner for loop:
calculate x and y distances from center (i - 0)
multiply by the mass of the element. Store in array
continue on for next index.
After this for loop finishes:
Sum all x moments for that row
Sum all y moments for that row
Add to any previous x and y moments calculated
Outside for loops:
divide by sum of the masses.
Also, comments should not say Ycm and Xcm, they are actually the moments caused by that individual element.
05-26-2010 10:59 AM
for(imstuck) wrote:If you put this array in from this link it doesn't give the right answer.
It depends on where you define your center. I defined my center as (0,0) in the upper left hand corner.
This would mean the first element is at location (1,1).
Using that origin, my answer is correct. Notice that my answer is exactly (x+1),(y+1).
I guess it depends how the OP defines their coordinates
05-26-2010 11:00 AM - edited 05-26-2010 11:02 AM
Good catch. I didn't even notice that. I guess he doesn't really specify...In fact, I originally did it as the center being at (3,3), not realizing that the post at the other link assumed a different one. The devil is in the details.
Probalby explains my B in statics instead of an A 😉
05-26-2010 01:18 PM - edited 05-26-2010 01:18 PM
First of all, in case you are wondering, the function is from IDL. INDGEN as it is used there generates an array of integers with each value equal to its index. TOTAL (as you might guess) is the sum of a given array. The syntax may be tricky, if you specify a dimension (1 or 2) of a 2D array, you get a 1D array where each element is the sum over the other dimension. In this case, xcm sums over columns and ycm sums over rows.
Knowing enough IDL to translate to LV gives me this:
05-26-2010 03:18 PM
05-27-2010 02:06 AM