Skip to content

Commit

Permalink
add a centroid calculation using tetrahedral decomposition. tested.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Whittemore committed Mar 19, 2011
1 parent a196025 commit caf6179
Showing 1 changed file with 28 additions and 1 deletion.
29 changes: 28 additions & 1 deletion src/wings_we.erl
Original file line number Diff line number Diff line change
Expand Up @@ -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").
Expand Down Expand Up @@ -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.