Permalink
Browse files

add a centroid calculation using tetrahedral decomposition. tested.

  • Loading branch information...
1 parent a196025 commit caf61792783a8387ef1d45263adb752d67afce81 Mark Whittemore committed Mar 19, 2011
Showing with 28 additions and 1 deletion.
  1. +28 −1 src/wings_we.erl
View
@@ -34,7 +34,7 @@
visible/1,visible/2,visible_vs/1,visible_vs/2,
visible_edges/1,visible_edges/2,fully_visible_edges/2,
validate_mirror/1,mirror_flatten/2,mirror_projection/1,
- create_mirror/2,freeze_mirror/1,break_mirror/1]).
+ create_mirror/2,freeze_mirror/1,break_mirror/1,centroid/1]).
-include("wings.hrl").
-include("e3d.hrl").
@@ -1204,3 +1204,30 @@ validate_vertex_tab(#we{es=Etab,vc=Vct}) ->
#edge{ve=V} -> ok
end
end, array:sparse_to_orddict(Vct)).
+
+
+%% Geometric center by weighted tetrahedrons
+centroid( #we{}=_We ) ->
+ We = wings_tesselation:triangulate(_We),
+ #we{fs=Ftab}=We,
+ MyAcc = fun(Fi, {{ Tx, Ty, Tz }, VTotal } ) ->
+ { _A, Vol, { CX, CY, CZ } } = centroid_parts(Fi,We),
+ { { Tx+Vol*CX, Ty+Vol*CY, Tz+Vol*CZ }, Vol + VTotal }
+ end,
+
+ {{ X, Y, Z }, VolumeT } = lists:foldl(MyAcc, {{ 0.0, 0.0, 0.0 } , 0.0 } , gb_trees:keys(Ftab) ),
+ { X/VolumeT, Y/VolumeT, Z/VolumeT }.
+
+
+centroid_parts(Face, We) ->
+ [V1,V2,V3] = wings_face:vertex_positions(Face, We),
+ E1 = e3d_vec:sub(V1, V2),
+ E2 = e3d_vec:sub(V3, V2),
+ Cp = e3d_vec:cross(E1, E2),
+ Bc = e3d_vec:cross(V2, V3),
+ Area = e3d_vec:len(Cp)/2.0,
+ Volume = e3d_vec:dot(V1, Bc)/6.0,
+
+ Centroid = e3d_vec:average( [ V1, V2, V3, {0.0, 0.0, 0.0} ] ),
+
+ {Area, Volume, Centroid}.

0 comments on commit caf6179

Please sign in to comment.