Calculation of second area moment

Hi Everyone
I’ve been trying to make a script that would take a mesh of cross section and then calculate basic properties like second moment of area(geometric moment of inertia), torsional constant and area. I tried few methods of achieving the results but outputs are quiet inconsistent with expected values that should be returned.

So at first I’ve tried to use SciPy to achieve this and just integrate with dblquad function but the outputs sometimes became not moment of area but area ofr i wasn’t quite sure what caused that but i deem that on my poor understanding of integration.

My current approach is way more error prone than integration but the results are closer to the expected ones, although Im kind of lost since its working only in the case of certain figures and some return values that look like it was elevated to some certain power.

For e.g. circle with radius of 1 returns value of around 0.59 which is close enough to square of the expected value of 0,78.

While square with base of 2 returns 1.325 which is close enough to expected value of 1.333
Same goes with triangle(with all sides equal) that also returns almost precise values

So here’s the code

import bpy
import bmesh
from mathutils import Vector
import numpy as np
import scipy as sp
import os 

obj = bpy.context.object
vertsx = [v for v in obj.data.vertices]
vertsy = [v for v in obj.data.vertices]

#calculation of area
center_of_mesh = Vector()
bm = bmesh.new()
bm.from_mesh(obj.data)
for face in bm.faces:
    center_of_mesh += face.calc_center_median()
center_of_mesh/len(bm.faces)
area = sum(f.calc_area() for f in bm.faces)
bm.free()
#clear the console
os.system('cls') 
print("center of mesh = {}".format(center_of_mesh.xy))
print("area = ", area)
#calculation of second moment of area
ix = []
iy = []
for v in obj.data.vertices: 
    ix.append(abs(center_of_mesh.x-v.co.x)) #this loop should return estimate area
    iy.append(abs(v.co.y - center_of_mesh.y))
    for v in obj.data.vertices:
        ix.append(abs(center_of_mesh.x-v.co.x)) #this loop should return estimate of first moment of area
        iy.append(abs(v.co.y - center_of_mesh.y))
        for v in obj.data.vertices:
            ix.append(abs(center_of_mesh.x-v.co.x)) #this loop should return estimate of first moment of area
            iy.append(abs(v.co.y - center_of_mesh.y))

#averaging out the value    
ixx = ((sum(ix)/len(obj.data.vertices))/len(obj.data.vertices))/len(obj.data.vertices)
iyy = (((sum(iy)/len(obj.data.vertices))/len(obj.data.vertices))/len(obj.data.vertices))   
#printing out values
print("ixx = ", ixx)
print("iyy = ", iyy)

The method itself is quite inefficient and im aware of that but its simple enough and seems to be working to some degree and im wondering what cause the inconsistence with the outputs. I would like to use it for more complicated shapes and id love to hear anyone’s idea how to fix that up i spend quite some time doing that by try and error but i find no clues what may be causing this

Hi,

I am not sure we are talking about the same, but in my mind, the moment of inertia is : integral(r².dm). Is it this that you are trying to get?

If yes, i believe that your calculation method is a bit off. Following the integral i am talking about above, you are only integrating the along the edge (as your vertices also are along the edge). That way, you are forgetting all the points inside.

What i would advise, if you want to calculate that using vertices is to do a lattice (a regular grid), only keep the vertices that are inside your geometry, and do your thing on all selected vertices. That would work in 2D and 3D. When you do such thing on 2D, you actually do it on a 3D assuming that the thickness is constant and small compared to other dimensions.

The average step is not correct either. You are meant to multiply it by the mass/volume for each point. Which is the same when the volume equals 1, but won’t apply for more complex shapes. If you follow the grid, you will want to first multiply your ix, and iy with dxdydz.

Another point i want to make, 0.59 to 0.78 is not “close enough”, you are 27% off, for such geometry, you can go below 1%.

Keep us informed of your progress!

Zelfior

Thanks for your response
yes im indirectly referring to the moment of inertia but to be more precise im only going for the geometrical moment of inertia also called as i written in the previous post second moment of area

I said before that square root of 0.59 which is 0.76 is close enough to 0.78 since i wasn’t sure whether im properly integrating that and getting that value i was hesitating if im not doing something wrong way. Yet you’re right that i should be able to go below 1% while that is 2.6% of error.

Thanks for pointing it out it makes a lot of sense then why i got proper values for square and triangle. Im not sure how to implement your idea with lattice but ill try to figure it out. I also have another idea how to solve that im not sure whether it will be good solution but ill try it out if i wont be able to applicate your idea.

Would make sense for moment of inertia itself but its not necessary for the second moment of area as far as im aware, yet i might be wrong.

Thanks for your help I’ll post my progress when ill find some time to work on the script.

OK so the definition in that article is the same as mine, but in 2D. So it valids what i said removing one dimension.

In that case, the area near the cursor would be over-represented with an average.

i would suggest something like this.

Hard to tell why you were that close with your method, but certainly thanks to how simple were the shapes. The circle requires the ² to be close but not the square?