The area of irregular closed polygons defined by coordinates may be conveniently calculated by summing the areas of adjacent trapeziums, as shown below. The area of each trapezium is calculated from the X axis. Note that with the apex coordinates defined in a clockwise direction the area between the bottom of the polygon and the x-axis is first added in (red trapeziums), then deducted (green trapeziums), leaving the correct area for the polygon, shaded blue. Other section properties, such as first and second moment of area, may be found in the same way, taking care to ensure that the formula gives a positive value for a positive XD, and negative for negative XD, for line segments above the X axis, and vice versa for segments below the X axis.

Voided shapes may be defined by connecting any external apex to one apex of the internal void, then listing the void apex coordinates in an anti-clockwise direction, then finally returning to the external apex. This procedure is shown for a regular hollow octagon below, but may also be used for any irregular shape, with any number of voids.

### Like this:

Like Loading...

*Related*

Pingback: Daily Download 20: Section Properties | Newton Excel Bach, not (just) an Excel Blog

Thanks doug!

This is the same method I used to get the centroid of a polygon as part of an app I’m building since 2011. This process is the same one it’s used to calculate locations by modern GPS systems. My app does exactly the same, but applied to topography.

Here’s part of the code of this method:

Function Centroid(oRng As Range, Optional sType As String) As Variant

Dim vCoords As Variant

Dim vRow() As Variant

Dim i As Long

Dim Area As Double

Dim xPos As Double, yPos As Double

vCoords = oRng.Value

Redim vRow(LBound(vCoords, 2) To UBound(vCoords, 2))

For i = LBound(vCoords, 2) To UBound(vCoords, 2)

vRow(i) = vCoords(1, i)

Next i

vCoords = AddRow(vCoords, vRow)

Area = CalcArea(vCoords) ‘Note that this is a signed area; if the points are numbered in clockwise order then the area will have a negative sign

xPos = CalcxPos(vCoords, Area)

yPos = CalcyPos(vCoords, Area)

If UCase(sType) = “X” Then

Centroid = xPos

ElseIf UCase(sType) = “Y” Then

Centroid = yPos

ElseIf UCase(sType) = “AREA” Then

Centroid = Abs(Area)

ElseIf UCase(sType) = “SAREA” Then

Centroid = Area

Else

Centroid = “(” & Round(xPos, 3) & “,” & Round(yPos, 3) & “)”

End If

End Function

Private Function CalcxPos(vCoords As Variant, Area As Double) As Double

Dim i As Long

For i = 1 To UBound(vCoords, 1) – 1

CalcxPos = CalcxPos + (vCoords(i, 1) + vCoords(i + 1, 1)) * (vCoords(i, 1) * vCoords(i + 1, 2) – vCoords(i + 1, 1) * vCoords(i, 2))

Next i

CalcxPos = CalcxPos / (6 * Area)

End Function

Private Function CalcyPos(vCoords As Variant, Area As Double) As Double

Dim i As Long

For i = 1 To UBound(vCoords, 1) – 1

CalcyPos = CalcyPos + (vCoords(i, 2) + vCoords(i + 1, 2)) * (vCoords(i, 1) * vCoords(i + 1, 2) – vCoords(i + 1, 1) * vCoords(i, 2))

Next i

CalcyPos = CalcyPos / (6 * Area)

End Function

Private Function CalcArea(vCoords As Variant) As Double

Dim i As Long

For i = 1 To UBound(vCoords, 1) – 1

CalcArea = CalcArea + vCoords(i, 1) * vCoords(i + 1, 2) – vCoords(i + 1, 1) * vCoords(i, 2)

Next i

CalcArea = 0.5 * CalcArea

End Function

Private Function AddRow(InputArr As Variant, vRow As Variant) As Variant

Dim vTemp As Variant

Dim i As Long

If LBound(vRow) LBound(InputArr, 2) Or UBound(vRow) UBound(InputArr, 2) Then AddRow = 0: Exit Function

vTemp = TransposeArray(InputArr)

Redim Preserve vTemp(LBound(vTemp, 1) To UBound(vTemp, 1), LBound(vTemp, 2) To UBound(vTemp, 2) + 1)

vTemp = TransposeArray(vTemp)

For i = LBound(vTemp, 2) To UBound(vTemp, 2)

vTemp(UBound(vTemp, 1), i) = vRow(i)

Next i

AddRow = vTemp

End Function

Private Function TransposeArray(InputArr As Variant) As Variant

Dim RowNdx As Long

Dim ColNdx As Long

Dim LB1 As Long

Dim LB2 As Long

Dim UB1 As Long

Dim UB2 As Long

Dim OutputArr() As Variant

LB1 = LBound(InputArr, 1)

LB2 = LBound(InputArr, 2)

UB1 = UBound(InputArr, 1)

UB2 = UBound(InputArr, 2)

Redim OutputArr(LB2 To LB2 + UB2 – LB2, LB1 To LB1 + UB1 – LB1)

For RowNdx = LB2 To UB2

For ColNdx = LB1 To UB1

OutputArr(RowNdx, ColNdx) = InputArr(ColNdx, RowNdx)

Next ColNdx

Next RowNdx

TransposeArray = OutputArr

End Function

LikeLike