class_docstr: A solid spherical object.
  
  Explanation
  ===========
  
  A wrapping geometry that allows for circular arcs to be defined between
  pairs of points. These paths are always geodetic (the shortest possible).
  
  Examples
  ========
  
  To create a ``WrappingSphere`` instance, a ``Symbol`` denoting its radius
  and ``Point`` at which its center will be located are needed:
  
  >>> from sympy import symbols
  >>> from sympy.physics.mechanics import Point, WrappingSphere
  >>> r = symbols('r')
  >>> pO = Point('pO')
  
  A sphere with radius ``r`` centered on ``pO`` can be instantiated with:
  
  >>> WrappingSphere(r, pO)
  WrappingSphere(radius=r, point=pO)
  
  Parameters
  ==========
  
  radius : Symbol
      Radius of the sphere. This symbol must represent a value that is
      positive and constant, i.e. it cannot be a dynamic symbol, nor can it
      be an expression.
  point : Point
      A point at which the sphere is centered.
  
  See Also
  ========
  
  WrappingCylinder: Cylindrical geometry where the wrapping direction can be
      defined.
docstr: Returns the shortest distance between two points on the sphere's
  surface.
  
  Explanation
  ===========
  
  The geodesic length, i.e. the shortest arc along the surface of a
  sphere, connecting two points can be calculated using the formula:
  
  .. math::
  
     l = \arccos\left(\mathbf{v}_1 \cdot \mathbf{v}_2\right)
  
  where $\mathbf{v}_1$ and $\mathbf{v}_2$ are the unit vectors from the
  sphere's center to the first and second points on the sphere's surface
  respectively. Note that the actual path that the geodesic will take is
  undefined when the two points are directly opposite one another.
  
  Examples
  ========
  
  A geodesic length can only be calculated between two points on the
  sphere's surface. Firstly, a ``WrappingSphere`` instance must be
  created along with two points that will lie on its surface:
  
  >>> from sympy import symbols
  >>> from sympy.physics.mechanics import (Point, ReferenceFrame,
  ...     WrappingSphere)
  >>> N = ReferenceFrame('N')
  >>> r = symbols('r')
  >>> pO = Point('pO')
  >>> pO.set_vel(N, 0)
  >>> sphere = WrappingSphere(r, pO)
  >>> p1 = Point('p1')
  >>> p2 = Point('p2')
  
  Let's assume that ``p1`` lies at a distance of ``r`` in the ``N.x``
  direction from ``pO`` and that ``p2`` is located on the sphere's
  surface in the ``N.y + N.z`` direction from ``pO``. These positions can
  be set with:
  
  >>> p1.set_pos(pO, r*N.x)
  >>> p1.pos_from(pO)
  r*N.x
  >>> p2.set_pos(pO, r*(N.y + N.z).normalize())
  >>> p2.pos_from(pO)
  sqrt(2)*r/2*N.y + sqrt(2)*r/2*N.z
  
  The geodesic length, which is in this case is a quarter of the sphere's
  circumference, can be calculated using the ``geodesic_length`` method:
  
  >>> sphere.geodesic_length(p1, p2)
  pi*r/2
  
  If the ``geodesic_length`` method is passed an argument, the ``Point``
  that doesn't lie on the sphere's surface then a ``ValueError`` is
  raised because it's not possible to calculate a value in this case.
  
  Parameters
  ==========
  
  point_1 : Point
      Point from which the geodesic length should be calculated.
  point_2 : Point
      Point to which the geodesic length should be calculated.
code: def geodesic_length(self, point_1, point_2):
      r"""Returns the shortest distance between two points on the sphere's
      surface.
  
      Explanation
      ===========
  
      The geodesic length, i.e. the shortest arc along the surface of a
      sphere, connecting two points can be calculated using the formula:
  
      .. math::
  
         l = \arccos\left(\mathbf{v}_1 \cdot \mathbf{v}_2\right)
  
      where $\mathbf{v}_1$ and $\mathbf{v}_2$ are the unit vectors from the
      sphere's center to the first and second points on the sphere's surface
      respectively. Note that the actual path that the geodesic will take is
      undefined when the two points are directly opposite one another.
  
      Examples
      ========
  
      A geodesic length can only be calculated between two points on the
      sphere's surface. Firstly, a ``WrappingSphere`` instance must be
      created along with two points that will lie on its surface:
  
      >>> from sympy import symbols
      >>> from sympy.physics.mechanics import (Point, ReferenceFrame,
      ...     WrappingSphere)
      >>> N = ReferenceFrame('N')
      >>> r = symbols('r')
      >>> pO = Point('pO')
      >>> pO.set_vel(N, 0)
      >>> sphere = WrappingSphere(r, pO)
      >>> p1 = Point('p1')
      >>> p2 = Point('p2')
  
      Let's assume that ``p1`` lies at a distance of ``r`` in the ``N.x``
      direction from ``pO`` and that ``p2`` is located on the sphere's
      surface in the ``N.y + N.z`` direction from ``pO``. These positions can
      be set with:
  
      >>> p1.set_pos(pO, r*N.x)
      >>> p1.pos_from(pO)
      r*N.x
      >>> p2.set_pos(pO, r*(N.y + N.z).normalize())
      >>> p2.pos_from(pO)
      sqrt(2)*r/2*N.y + sqrt(2)*r/2*N.z
  
      The geodesic length, which is in this case is a quarter of the sphere's
      circumference, can be calculated using the ``geodesic_length`` method:
  
      >>> sphere.geodesic_length(p1, p2)
      pi*r/2
  
      If the ``geodesic_length`` method is passed an argument, the ``Point``
      that doesn't lie on the sphere's surface then a ``ValueError`` is
      raised because it's not possible to calculate a value in this case.
  
      Parameters
      ==========
  
      point_1 : Point
          Point from which the geodesic length should be calculated.
      point_2 : Point
          Point to which the geodesic length should be calculated.
  
      """
      for point in (point_1, point_2):
          if not self.point_on_surface(point):
              msg = (
                  f"Geodesic length cannot be calculated as point {point} "
                  f"with radius {point.pos_from(self.point).magnitude()} "
                  f"from the sphere's center {self.point} does not lie on "
                  f"the surface of {self} with radius {self.radius}."
              )
              raise ValueError(msg)
      point_1_vector = point_1.pos_from(self.point).normalize()
      point_2_vector = point_2.pos_from(self.point).normalize()
      central_angle = acos(point_2_vector.dot(point_1_vector))
      geodesic_length = self.radius * central_angle
      return geodesic_length
  
imports: from abc import ABC, abstractmethod
  from sympy import Integer, acos, pi, sqrt, sympify, tan
  from sympy.core.relational import Eq
  from sympy.functions.elementary.trigonometric import atan2
  from sympy.polys.polytools import cancel
  from sympy.physics.vector import Vector, dot
  from sympy.simplify.simplify import trigsimp
label_desc: Use image node_id 7 for calling the WrappingSphere obj's underlying member method code with example usage: obj.geodesic_length(point_1, point_2) and returns: geodesic_length