# Compute Centroid of Geometry in Geometry Nodes

Say I want to export a vector from the output of a geometry stream that represents the centroid of the geometry. How would I do it?

Thanks!

Anson

It ultimately depends on whether or not you consider your mesh as volumetric, "areametric", "lengthmetric", or just a set of points.

By "areametric", I mean the mesh is not considered as having a volume, just an area (it's a surface - like a sheet of paper or a a hollow shell of points).

Treating a mesh as volumetric assumes it's a completely filled in solid object, occupying volume (like a ball of cement filled completely).

Going down in dimensions, by "lengthmetric", I'm implying a mesh is treated as only containing verts and edges (like a wire with no area and no volume, just length, maybe a curve converted to a mesh).

Going lower, it is possible a mesh only consists of vertices, which is the easiest case. The order of dimensions I'll treat this answer will be 2, 3, 1, 0.

The centroid $$\bar{c}$$ of a surface mesh can be calculated using

$$\bar{c} = \dfrac{\sum_{i = 0}^{n-1}(c_iA_i)}{\sum_{i = 0}^{n-1}(A_i)}$$

where

• $$n$$ is the number of faces
• $$i$$ is a face index iterator from $$0$$ through $$n - 1$$
• $$c_i$$ is the area-centroid of the $$i^{th}$$ face
• $$A_i$$ is the area of the $$i^{th}$$ face

Here is the node set-up I used:

The face centroids are found with a "Capture Attribute" node (face vert average). The area summations are handled with "Accumulate Field" nodes. At the end, within the geometry nodes, I add in a tiny sphere and place it at the centroid location for confirmation. I needed a "Sample Index" to get rid of the field of centroids (all same answer) and just use a single one of them to set the sphere translation.

Here I added a rock with the rock generator, converted the rock to a mesh, and applied the modifier:

The centroid $$\bar{c}$$ of a volume mesh can be calculated using:

$$\bar{c} = \dfrac{\sum_{i = 0}^{n-1}(c_iV_i)}{\sum_{i = 0}^{n-1}(V_i)}$$

where

• $$n$$ is the number of volumetric chunks such that the chunk's volumes summate to the mesh volume
• $$i$$ is a chunk index iterator from $$0$$ through $$n - 1$$
• $$c_i$$ is the volumetric centroid of the $$i^{th}$$ chunk
• $$V_i$$ is the volume of the $$i^{th}$$ chunk

The mesh needs to be triangulated and volumized by tetrahedrons to compute the volume of the mesh. The fourth point of the tetrahedron is the origin for each of the triangulated faces. Depending on whether the origin can be defined by the positive or negative normal of each triangle face, some of these tetrahedrons are treated with negative volume, otherwise positive or rarely zero. The volume of a tetrahedron is precisely $$\dfrac{1}{6}|(\overline{AB} \times \overline{AC}) \cdot \overline{AD}|$$ - derived from vector math on connected edge segments.

Thankfully, this non-trivial mesh volume calculation task has already been done in geo-nodes here:

How do you measure the volume of a mesh?

Utilizing the above file, my task is to now summate the centroid of each tetrahedron (the volumetric centroid of each tetrahedron is, thankfully, the same as its point average; the sum of the tetra points / by 4 , ignoring the origin, so only 3 points) multiplied by its volume, for each tetrahedron, and then divide the resulting vector by the volume of the entire mesh (summation of tetrahedrons).

So, here is the node set up for this volumetric centroid (quite similar to the area-based centroid node set-up, except with a tricky volume calculation and an easy tetrahedron centroid calculation):

As you can see, for the rock (now treated as a solid), the volumetric centroid (denoted by the tiny sphere) is now slightly different than the previous area based centroid as a cycle between the two different approaches.

The centroid $$\bar{c}$$ of a wire mesh can be calculated using

$$\bar{c} = \dfrac{\sum_{i = 0}^{n-1}(c_iL_i)}{\sum_{i = 0}^{n-1}(L_i)}$$

where

• $$n$$ is the number of edges
• $$i$$ is an edge index iterator from $$0$$ through $$n - 1$$
• $$c_i$$ is the center of the $$i^{th}$$ edge
• $$L_i$$ is the length of the $$i^{th}$$ edge

In geo-nodes, edge length is captured as the distance between the edge vertices

The centroid $$\bar{c}$$ of a point mesh can be calculated using

$$\bar{c} = \dfrac{\sum_{i = 0}^{n-1}(p_i)}{n}$$

where

• $$n$$ is the number of vertices of the mesh
• $$i$$ is an point index iterator from $$0$$ through $$n - 1$$
• $$p_i$$ is the location of the $$i^{th}$$ point

In geo-nodes, for this case, an "Attribute Statistic" can now replace the "Accumulate Field" nodes.

Here I quickly cycle through all the centroid choices on the rock, going lowest to highest in dimensions. Thus, it's first treated as a set of points, then as a wired mesh, going forth as a surface mesh, and finally as a volume.

For fun, you can tease your brain of the 4-dimesnional case, calculating a hyper-centroid of a hyper-mesh in 4D space. The "surface" of the object would actually be volumetric, and for the algorithm, need to be filled with tetrahedrons (analogous to triangulated surface). The hyper-mesh would need to be hyper-volumized by a set of 4-simplexes (3 simplex is tetrahedron, 2 simplex is triangle). etc...

• +1 and my math may be out.. but is this the same thing? imgur.com/a/Rvj7SLL Nov 9, 2023 at 19:48
• @RobinBetts It appears that your attribute statistic is dividing the correct weighted summation (numerator of the centroid equation) by a denominator of $n$, the number of faces, for the centroid. The denominator should be the surface area of the mesh, which would explain the tiny centroid vector I received using your image (.0031, .0046, .0062), due to the number of faces (1920) being larger than the surface area of the rock (27.104) Nov 9, 2023 at 21:38
• Thanks for the clear explanation! I had my suspicions that yours was the correct way, and it wasn't jumping to me, why.. :) Nov 10, 2023 at 6:03
• What an amazing answer! I only started analyzing it, so for starters, the great advantage of using accumulate field instead of attribute statistic node is that you can make it work for multiple groups like so: i.imgur.com/2NEBnvc.png Nov 10, 2023 at 23:05
• Works great, thanks! Very detailed answer! Very much appreciated :) Nov 12, 2023 at 2:41