0
$\begingroup$

Like always, I am probably over complicating this and there is a much simpler way to derive a general formula using built-in Mathematica functions, think about it differently, or a faster way to solve the equation in step 9 below. But having a fairly simple solution to this problem in Mathematica would mean being able to solve many problems on Mathematica Stack Exchange and Math Stack Exchange. And I think an imperative approach is probably not best.

So, if we have a specific convex polyhedron in space (so the exact starting coordinates matter) that is rotated by the RollPitchYawMatrix in Mathematica, and take the orthographic projection into the xy-plane, we always have a formula for the area of the silhouette of the form of a piecewise function:

$$ silhouetteArea = \begin{cases} \sum_{shownface|(\alpha, \beta, \gamma)}^{numShownFaces|(\alpha, \beta, \gamma)} (shownFaceArea*TrigProd(\alpha, \beta, \gamma)), & \text{ if $a_{i} \le \alpha \le a_{f}, b_{i} \le \beta \le b_{f}, c_{i} \le \gamma \le c_{f}$}, ... \end{cases} $$, where each case is a sum of the area of the shadow of the faces in the xy-plane with a domain of angles, where each angle can take a value from $[-2\pi, 2\pi]$.

The main problem is finding which faces show up at which angles, which makes the solution complicated.

So, here is my algorithm that I thought of:

  1. Create a random convex polyhedron.
  2. Extract and name the vertex coordinates of the random convex polyhedron.
  3. Extract and name the faces with corresponding groups the vertices.
  4. Order the points of each face in a clockwise or counterclockwise manner.
  5. Use the shoelace theorem to find the area formula of each of the polygons using the names of the vertices instead of the actual coordinates.
  6. Calculate the centroid of the random convex polyhedron and each face.
  7. Find each of the normal vectors of each of the faces of the polygon going through the centroid of the polyhedron of the polyhedron and face with it pointing out.
  8. Apply the rotation matrix, RollPitchYawMatrix[], to each of the face's normal vectors.
  9. Since we are concerned about the shape projected onto the xy-plane, we only need to look at the faces whose normal vectors have a positive z-coordinate for its normal vector after applying the rotation. But finding the boundary conditions for this is also very difficult Which kind of circles back to our original problem.
  10. Once we have the $\alpha, \beta, \gamma$-boundaries for which faces show, then use that to create our formula.

This is an example of a possible datum structure at the end of step 3:

    exampleDatumStructure=
{
   {
      {
         {{-1.1135163644116066`,0.8090169943749475`,-0.2628655560595668`},"V1"}, 
         {{-0.6881909602355868`,0.5`,-1.1135163644116066`},"V2"}, 
         {{-0.6881909602355868`,-0.5`,-1.1135163644116066`},"V3"}, 
         {{-1.1135163644116066`,-0.8090169943749475`,-0.2628655560595668`},"V4"}, 
         {{-1.3763819204711736`,0.`,0.2628655560595668`},"V5"}
      },"F1"}, 
   {
      {
         {{1.3763819204711736`,0.`,-0.2628655560595668`},"V6"}, 
         {{1.1135163644116066`,0.8090169943749475`,0.2628655560595668`},"V7"}, 
         {{0.6881909602355868`,0.5`,1.1135163644116066`},"V8"}, 
         {{0.6881909602355868`,-0.5`,1.1135163644116066`},"V9"}, 
         {{1.1135163644116066`,-0.8090169943749475`,0.2628655560595668`},"V10"}
      },"F2"},
   {
      {
         {{1.1135163644116066`,-0.8090169943749475`,0.2628655560595668`},"V10"}, 
         {{0.6881909602355868`,-0.5`,1.1135163644116066`},"V9"}, 
         {{-0.2628655560595668`,-0.8090169943749475`,1.1135163644116066`},"V11"}, 
         {{-0.42532540417602`,-1.3090169943749475`,0.2628655560595668`},"V12"}, 
         {{0.42532540417601994`,-1.3090169943749475`,-0.2628655560595668`},"V13"}
      },"F3"},
   {
      {
          {{0.6881909602355868`,-0.5`,1.1135163644116066`},"V9"}, 
          {{0.6881909602355868`,0.5`,1.1135163644116066`},"V8"}, 
          {{-0.2628655560595668`,0.8090169943749475`,1.1135163644116066`},"V14"}, 
          {{-0.85065080835204`,0.`,1.1135163644116066`},"V15"}, 
          {{-0.2628655560595668`,-0.8090169943749475`,1.1135163644116066`},"V11"}
       },"F4"}, 
   {
       {
           {{0.6881909602355868`,0.5`,1.1135163644116066`},"V8"}, 
           {{1.1135163644116066`,0.8090169943749475`,0.2628655560595668`},"V7"}, 
           {{0.42532540417601994`,1.3090169943749475`,-0.2628655560595668`},"V16"}, 
           {{-0.42532540417602`,1.3090169943749475`,0.2628655560595668`},"V17"}, 
           {{-0.2628655560595668`,0.8090169943749475`,1.1135163644116066`},"V14"}
       },"F5"}, 
   {
       {
          {{1.1135163644116066`,0.8090169943749475`,0.2628655560595668`},"V7"}, 
          {{1.3763819204711736`,0.`,-0.2628655560595668`},"V6"}, 
          {{0.85065080835204`,0.`,-1.1135163644116066`},"V18"}, 
          {{0.2628655560595668`,0.8090169943749475`,-1.1135163644116066`},"V19"}, 
          {{0.42532540417601994`,1.3090169943749475`,-0.2628655560595668`},"V16"}
       },"F6"}, 
   {
       {
          {{1.3763819204711736`,0.`,-0.2628655560595668`},"V6"}, 
          {{1.1135163644116066`,-0.8090169943749475`,0.2628655560595668`},"V10"}, 
          {{0.42532540417601994`,-1.3090169943749475`,-0.2628655560595668`},"V13"}, 
          {{0.2628655560595668`,-0.8090169943749475`,-1.1135163644116066`},"V20"}, 
          {{0.85065080835204`,0.`,-1.1135163644116066`},"V18"}
       },"F7"},
   {
       {
          {{-0.42532540417602`,1.3090169943749475`,0.2628655560595668`},"V17"}, 
          {{0.42532540417601994`,1.3090169943749475`,-0.2628655560595668`},"V16"}, 
          {{0.2628655560595668`,0.8090169943749475`,-1.1135163644116066`},"V19"}, 
          {{-0.6881909602355868`,0.5`,-1.1135163644116066`},"V2"}, 
          {{-1.1135163644116066`,0.8090169943749475`,-0.2628655560595668`},"V1"}
        },"F8"}, 
   {
       {
            {{0.2628655560595668`,0.8090169943749475`,-1.1135163644116066`},"V19"}, 
            {{0.85065080835204`,0.`,-1.1135163644116066`},"V18"}, 
            {{0.2628655560595668`,-0.8090169943749475`,-1.1135163644116066`},"V20"}, 
            {{-0.6881909602355868`,-0.5`,-1.1135163644116066`},"V3"}, 
            {{-0.6881909602355868`,0.5`,-1.1135163644116066`},"V2"}
       },"F9"}, 
    {
       {
            {{0.2628655560595668`,-0.8090169943749475`,-1.1135163644116066`},"V20"}, 
            {{0.42532540417601994`,-1.3090169943749475`,-0.2628655560595668`},"V13"}, 
            {{-0.42532540417602`,-1.3090169943749475`,0.2628655560595668`},"V12"}, 
            {{-1.1135163644116066`,-0.8090169943749475`,-0.2628655560595668`},"V4"}, 
            {{-0.6881909602355868`,-0.5`,-1.1135163644116066`},"V3"}
        },"F10"},
    {
        {
           {{-0.42532540417602`,-1.3090169943749475`,0.2628655560595668`},"V12"}, 
           {{-0.2628655560595668`,-0.8090169943749475`,1.1135163644116066`},"V11"}, 
           {{-0.85065080835204`,0.`,1.1135163644116066`},"V15"}, 
           {{-1.3763819204711736`,0.`,0.2628655560595668`},"V5"}, 
           {{-1.1135163644116066`,-0.8090169943749475`,-0.2628655560595668`},"V4"}
        },"F11"},
    {
        {
           {{-0.85065080835204`,0.`,1.1135163644116066`},"V15"}, 
           {{-0.2628655560595668`,0.8090169943749475`,1.1135163644116066`},"V14"}, 
           {{-0.42532540417602`,1.3090169943749475`,0.2628655560595668`},"V17"}, 
           {{-1.1135163644116066`,0.8090169943749475`,-0.2628655560595668`},"V1"}, 
           {{-1.3763819204711736`,0.`,0.2628655560595668`},"V5"}
         },"F12"}
 };

Ordering the vertices can be done by modifying this.

And the centroid and normals can be calculated by modifying these:

centroid = Mean[Flatten[vertices, 1]]

(* Function to compute normal for a face *)
getNormal[face_] := 
 Module[{A, B, C, normal, directionToCentroid},
  {A, B, C} = face[[1 ;; 3, 1]];
  normal = Cross[B - A, C - A];
  directionToCentroid = centroid - A;
  
  (* Ensure the normal points outward *)
  If[Dot[normal, directionToCentroid] > 0, 
   normal = -normal];
  normal
 ]

(* Compute normals for all faces *)
normals = getNormal /@ exampleDatumStructure[[All, 1]];

But I have a strong hunch that there is a simpler answer out there that does not use any of the algorithms or code that I provided.

$\endgroup$
4
  • 1
    $\begingroup$ I'm not sure what you're asking. But if you want the area of the xy-projection, you could find the area of the convex hull of the projected vertices. Or you could project the mesh itself and take 0.5 it's area since a convex polyhedron has an 'up' side and a 'down' side. SeedRandom[1]; reg = RandomPolyhedron[{"ConvexHull", 20}]; convex hull area: Area[ConvexHullMesh[reg[[1, All, 1 ;; 2]]]] (* 0.477824 *) projection area: 0.5Area[MeshRegion[reg[[1, All, 1 ;; 2]], Polygon[reg[[2]]]]] (* 0.477824 *) $\endgroup$
    – Greg Hurst
    Oct 12, 2023 at 0:38
  • $\begingroup$ @GregHurst You gave a great comment! While, yes your solution finds the area after a particular rotation there is a drawback. It is numeric, so it doesn't give a general formula for finding the exact area after a known roll-pitch-yaw. It isn't computationally optimal and it doesn't help to find interesting mathematical relationships. $\endgroup$
    – Teg Louis
    Oct 12, 2023 at 15:24
  • $\begingroup$ @GregHurst Here is the partial cuboid formula. It is not general, because it only works when $\gamma = 0$. It would be great if all of the angles can be between $[-2\pi, 2\pi]$ which would mean the general solution is a piecewise function. And it would be great to be able to do it for any convex polyhedron. I feel like there would be a way for Mathematica to solve this fairly easily instead of focusing so much on the Mathematics behind it. $\endgroup$
    – Teg Louis
    Oct 12, 2023 at 15:27
  • $\begingroup$ Well, I don't think there is a simpler method except to do the method I had described, and just simplify the format. So, I will work on that and post it. $\endgroup$
    – Teg Louis
    Oct 29, 2023 at 16:51

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.