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
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
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
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
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...