Here is another solution of the first, specific question about the volumes of Phobos and Deimos. The idea is to use the polygons provided by example data:
polygonObjs =
ExampleData[{"Geometry3D", "Deimos"}, "PolygonObjects"];
polygonObjs // Length
(* Out[74]= 18816 *)
Graphics3D[RandomSample[polygonObjs, 2000], Axes -> True]
Suppose we have shifted those polygons so all their points have positive z-coordinates. Then we can estimate the Deimos volume by summing the volumes of the truncated prisms made by these polygons and their projections on the xy plane while taking into account which polygons are on top and which are under.
First, we have to figure out which polygons are on top an which are under. We can use the "VertexNormals" data for this.
polygonData = ExampleData[{"Geometry3D", "Deimos"}, "PolygonData"];
polygonData // Length
(* 18816 *)
vNormals = ExampleData[{"Geometry3D", "Deimos"}, "VertexNormals"];
vNormals // Length
(* 9410 *)
pNormals = Map[Mean[vNormals[[#]]] &, polygonData];
pNormals // Length
(* 18816 *)
polygons = polygonObjs[[All, 1]];
Here is a sample of polygons and their corresponding vectors (note the shift in the z-axis by 10):
sInds = RandomSample[Range[Length[polygons]], 600];
Graphics3D[
Translate[#, {0, 0, 10}] &@{ Polygon /@ polygons[[sInds]], Gray,
Opacity[0.3], Thin, Arrowheads[0.005],
MapThread[
Arrow[{Mean[#1], #2}] &, {polygons[[sInds]], pNormals[[sInds]]}]},
Axes -> True]
Next we define a function (taken from here) to find the area of a projected (2D) polygon:
PolygonArea =
Compile[{{v, _Real, 2}}, Block[{x, y}, {x, y} = Transpose[v];
Abs[x.RotateLeft[y] - RotateLeft[x].y]/2]]
Now we are ready to compute the volume by multiplying the projections` areas with hight means and normals direction signs:
Dot[Map[PolygonArea[#[[All, 1 ;; 2]]] &, polygons],
(Mean[#[[All, 3]]] + 10) & /@ polygons*
Sign[pNormals[[All, 3]]]]
(* 1026.06 *)
( The result seems closer to the one pointed out in Wikipedia than the solution using ConvexHullMesh.)
The computation of the volumes of the truncated prisms can be refined to be more precise -- note that I just take the means of the z-coordinates of the shifted polygons. (We can use precise formulas or Integrate.)
This idea is very similar to the mathematical formulas for using type-2 surface integrals to compute volumes, but I was too lazy to implement that.
For Phobos this solution gives 5788.04 which is very close to the one given in Wikipedia's article on Phobos, 5783.61. Using the ConvexHullMesh
solution we get again a more overestimated volume:
phobos = ExampleData[{"Geometry3D", "Phobos"}, "VertexData"];
phobos = ConvexHullMesh[phobos];
Volume@BoundaryMeshRegion[phobos]
(* Out[147]= 5987.53 *)