Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Ggaliens/centroid by volume #9

wants to merge 3 commits into from

2 participants


OK. This is updated centroids pull request on same branch. Spacing addressed.
link provided.


I didn't mean for the other comments to disappear. What I did was re-pull my original branch down. Maybe I did more than that. Anyway ... I'm still learning GIT process.


OK ... a bit more fussing around. I really should be in bed.
I wanted to make sure to treat / add volume as discrete method at same time as adding centroid since they are so strongly related. I also notice that my prior commit of centroid was not optimized as it still played with Area the same way Scorpius had his function which was called area_volume. For centroid, area was just ignored ... so for optimizations sake ... I thought it very proactive to get rid of the area expressions since they were effectively code-lint.


B.T.W. If a manifold has negative volume ... it is inside out. Pretty cool/basic use of volume.


Dan ... Hope you see this I'm needing to catch a bad arith when volume is ZERO and use fallback scheme.
This is needed for centroid of "FLAT OBJECTS" with zero volume, and oddball case ... but I ran into it. So added the



@dgud dgud closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 19, 2011
Commits on Mar 22, 2011
  1. Add volume calc for a we while we are handling centroid since they ar…

    Mark Whittemore authored
    …e related
Commits on Mar 30, 2011
  1. Make a fix to centroid contributions.

    Mark Whittemore authored
This page is out of date. Refresh to see the latest.
Showing with 44 additions and 1 deletion.
  1. +44 −1 src/wings_we.erl
45 src/wings_we.erl
@@ -34,7 +34,7 @@
- create_mirror/2,freeze_mirror/1,break_mirror/1]).
+ create_mirror/2,freeze_mirror/1,break_mirror/1,centroid/1,volume/1]).
@@ -1204,3 +1204,46 @@ validate_vertex_tab(#we{es=Etab,vc=Vct}) ->
#edge{ve=V} -> ok
end, array:sparse_to_orddict(Vct)).
+%%% Centroid by vol weighted tetrahedron centroids. Paper only talks about vol
+%%% But for constant mass and tetrahedron shapes,
+%%% Centroid calculation is a natural fallout (ggaliens)
+centroid( #we{}=_We ) ->
+ We = wings_tesselation:triangulate(_We),
+ #we{fs=Ftab}=We,
+ MyAcc = fun(Fi, {{Tx,Ty,Tz}, VTotal }) ->
+ {Vol,{CX,CY,CZ}} = centroid_parts(Fi,We),
+ {{Tx+Vol*CX,Ty+Vol*CY,Tz+Vol*CZ},Vol+VTotal}
+ end,
+ Fs = gb_trees:keys(Ftab),
+ {{X,Y,Z}, VolumeT } = lists:foldl(MyAcc, {{0.0,0.0,0.0},0.0} , Fs),
+ case catch {X/VolumeT,Y/VolumeT,Z/VolumeT} of
+ {_,_,_}=Centroid ->
+ Centroid;
+ _ -> %% caught a bad arith error more than likely zero volume, apply fallback scheme
+ #we{vp=VPos}=_We,
+ TempDict = array:sparse_to_orddict(VPos),
+ e3d_bv:center(e3d_bv:box([Point || {_,Point} <- TempDict]))
+ end.
+centroid_parts(Face, We) ->
+ [V1,V2,V3] = wings_face:vertex_positions(Face, We),
+ Bc = e3d_vec:cross(V2, V3),
+ Volume = e3d_vec:dot(V1, Bc)/6.0,
+ Centroid = e3d_vec:average([V1,V2,V3,{0.0,0.0,0.0}]),
+ {Volume,Centroid}.
+volume(#we{}=We0) ->
+ We = wings_tesselation:triangulate(We0),
+ #we{fs=Ftab}=We,
+ VolList = [volume_1(Face, We) || Face <- gb_trees:keys(Ftab)],
+ lists:sum(VolList).
+volume_1(Face, We) ->
+ [V1,V2,V3] = wings_face:vertex_positions(Face, We),
+ Bc = e3d_vec:cross(V2, V3),
+ e3d_vec:dot(V1, Bc)/6.0.
Something went wrong with that request. Please try again.