Lately I was thinking about computing section properties programatically. Of course, any engineering undergrad can compute the area and moment of inertia of a section comprising rectangles and other simple shapes — for example, a tee-section or an I-beam section. There is software out there that computes section properties of arbitrary sections, including the area, centroid and moment of inertia. Presumably that software is doing something other than just breaking down the shape into a bunch of rectangles or other simple shapes.
As I was thinking about this, I remembered back nearly twenty years to an undergrad course that taught Green’s Theorem. This is a way to compute an area integral using a contour intergral. It seems to me that computing a contour integram of an arbitrary shape is probably easier than computing an area integral.
Green’s theorem is as follows:
Area
The first section property that is obviously needed is area. Area is (clearly) given by:
This means that to apply Green’s theorum, we need to select functions \(M\) and \(L\) such that:
There are an infinite number of functions that would satisfy that equality, but let’s choose:
We’ll need to integrate these functions over the closed contour enclosing the shape. It will be convinient to evaluate that contour interval if the shape can be described as piecewise functions of the parameter \(s\) that varies from \(0\) to \(1\) over each piecewise segment describing the closed contour. With this in mind, we’ll define two functions as follows:
For a linear segment with endpoints \(\left(x_a, y_a\right)\) and \(\left(x_b, y_b\right)\), these functions would be as follows. Similar functions can be written for other segments.
Noting the following:
We can make the following substitutions:
Example Implementation of Area Computation
For a simple example, let’s consider the computation of the area bounded by a set of line segments. The functions \(f\) and \(g\) for this case are given above; the derivatives, which are also needed, are as follows:
The area bounded by \(n\) such line segments is:
This can be implemented in Python. This implementation will take a
numpy array of size (N, 2) representing the vertecies.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches
def compute_area(v):
v_offset = np.concat((v[1:], v[0:1]))
return 1 / 2 * float(sum([
xa * (yb - ya) - ya * (xb - xa)
for (xa, ya), (xb, yb) in zip(v, v_offset)
]))
We’ll also create a function that plots the shape.
def plot_shape(v):
fig, ax = plt.subplots()
ax.add_patch(matplotlib.patches.Polygon(v))
ax.autoscale(axis="both")
Let’s try a few examples. First, a 4x2 rectangle centered on the origin.
rect2_4 = np.array([
[-2, -1],
[2, -1],
[2, 1],
[-2, 1]
])
plot_shape(rect2_4)

The area should be \(4 \times 2 = 8\). Let’s check what the function returns:
compute_area(rect2_4)
8.0
Next, let’s try a triangle.
tri3_2 = np.array([
[0, 0],
[3, 0],
[0, 2]
])
plot_shape(tri3_2)

The area should be \(\frac{1}{2} \times 3 \times 2 = 3\). Let’s check what the function returns:
compute_area(tri3_2)
3.0
Computation of the Centroid
The centroid in the \(X\) axis is given by:
Using Green’s theorem again, we need to choose two new functions \(M\) and \(L\) such that
We’ll choose:
As before, we’ll use the functions \(f\left(s\right)\) and \(g\left(s\right)\)
When the shape comprises \(n\) line segments, this becomes:
The centroid in the \(Y\) axis can be found the same way, but reversing the \(x\)‘s and \(y\)‘s and reversing the sign.
Example Implementation of Centroid Computation
This can be implemented in Python as follows:
def compute_centroid(v):
area = compute_area(v)
v_offset = np.concat((v[1:], v[0:1]))
x_bar = 1 / (2 * area) * float(sum([
(xa**2 + xa * (xb - xa) + 1 / 3 * (xb - xa)**2) * (yb - ya)
for (xa, ya), (xb, yb) in zip(v, v_offset)
]))
y_bar = -1 / (2 * area) * float(sum([
(ya**2 + ya * (yb - ya) + 1 / 3 * (yb - ya)**2) * (xb - xa)
for (xa, ya), (xb, yb) in zip(v, v_offset)
]))
return x_bar, y_bar
Trying this with the previous example of a 4x2 rectangle centered on the origin should result with the centroid on the origin.
compute_centroid(rect2_4)
(0.0, -0.0)
For the previous triangle, the centroid should be located \(1/3\) of the way from the base.
compute_centroid(tri3_2)
(1.0, 0.6666666666666666)
Computation of the Moment of Inertia
When computing the moment of inertia, the origin needs to be set coincident with the centroid. In the following derrivation, it will be assumed that the centroid is coincident with \(\left(x, y\right) = \left(0, 0\right)\). The moment of inertia about the \(Y\) asis is:
Using Green’s theorem again, we need to choose two new functions \(M\) and \(L\) such that
We’ll choose:
As before, we’ll use the functions \(f\left(s\right)\) and \(g\left(s\right)\)
When the shape comprises \(n\) line segments, this becomes:
The moment of inertia in the \(X\) axis can be found the same way, but reversing the \(x\)‘s and \(y\)‘s and reversing the sign.
Example Implementation of Moment of Inertia Computation
This can be implemented in Python as follows:
def compute_moi(v):
centroid = compute_centroid(v)
v = v - centroid
v_offset = np.concat((v[1:], v[0:1]))
Iyy = 1 / 3 * float(sum([
(xa**3 + 3 / 2 * xa**2 * (xb - xa) + xa * (xb - xa)**2 + 1 / 4 * (xb - xa)**3) * (yb - ya)
for (xa, ya), (xb, yb) in zip(v, v_offset)
]))
Ixx = -1 / 3 * float(sum([
(ya**3 + 3 / 2 * ya**2 * (yb - ya) + ya * (yb - ya)**2 + 1 / 4 * (yb - ya)**3) * (xb - xa)
for (xa, ya), (xb, yb) in zip(v, v_offset)
]))
return Ixx, Iyy
Trying this with the previous example of a 4x2 rectangle. The moments of inertia should be:
compute_moi(rect2_4)
(2.6666666666666665, 10.666666666666666)
For the previous 3x2 right triangle, the moment of inertia should be:
compute_moi(tri3_2)
(0.6666666666666666, 1.5)
Conclusion
Using Green’s Theorem can be used to help compute section properties of shapes given the contour of the shape. In this post, we computed the area, centroid location and moment of inertia of arbitrary closed shapes bounded by a series of line segments. This approach could be extended to conisder other bounding curves (for example, circular arcs, etc.). While I’m not sure how commercial software computes section properties of arbitrary sections, this approach seems like a pretty good guess.