docstr: Gets the ground plane under the box.
docstr_tok: ["Gets","the","ground","plane","under","the","box","."]
code: def _get_ground_plane(self, gravity_axis=1):
      """Gets the ground plane under the box."""
      gravity = np.zeros(3)
      gravity[gravity_axis] = 1
  
      def _get_face_normal(face, center):
          v1 = self.vertices[face[0], :] - center
          v2 = self.vertices[face[1], :] - center
          normal = np.cross(v1, v2)
          return normal
  
      def _get_face_center(face):
          center = np.zeros(3)
          for vertex in face:
              center += self.vertices[vertex, :]
          center /= len(face)
          return center
  
      ground_plane_id = 0
      ground_plane_error = 10.0
  
      # The ground plane is defined as a plane aligned with gravity.
      # gravity is the (0, 1, 0) vector in the world coordinate system.
      for i in [0, 2, 4]:
          face = _FACES[i, :]
          center = _get_face_center(face)
          normal = _get_face_normal(face, center)
          w = np.cross(gravity, normal)
          w_sq_norm = np.linalg.norm(w)
          if w_sq_norm < ground_plane_error:
              ground_plane_error = w_sq_norm
              ground_plane_id = i
  
      face = _FACES[ground_plane_id, :]
      center = _get_face_center(face)
      normal = _get_face_normal(face, center)
  
      # For each face, we also have a parallel face that it's normal is also
      # aligned with gravity vector. We pick the face with lower height
      # (y-value). The parallel to face 0 is 1, face 2 is 3, and face 4 is 5.
      parallel_face_id = ground_plane_id + 1
      parallel_face = _FACES[parallel_face_id]
      parallel_face_center = _get_face_center(parallel_face)
      parallel_face_normal = _get_face_normal(
          parallel_face, parallel_face_center
      )
      if parallel_face_center[gravity_axis] < center[gravity_axis]:
          center = parallel_face_center
          normal = parallel_face_normal
      return center, normal
  
imports: import itertools
  import logging
  import warnings
  import numpy
  import scipy.spatial
  import eta.core.numutils
  import fiftyone.core.fields
  import fiftyone.core.labels
  import fiftyone.core.media
  from fiftyone.core.sample import Sample
  import fiftyone.core.utils
  import fiftyone.core.validation
  from fiftyone.core.odm import DynamicEmbeddedDocument
  import fiftyone.utils.image
label_desc: Use image node_id 5 for calling the _Box obj's underlying member method code with example usage: obj._get_ground_plane(gravity_axis) and returns: center,  normal, normal, center