
    _Mh	5                     X    d Z ddlZddlZddlmZ ddlmZ dgZd Z	 G d d          Z
dS )	z3
Spherical Voronoi Code

.. versionadded:: 0.18.0

    N   )_voronoi)cKDTreeSphericalVoronoic           	         t           j                            |           }dt          j        d| dddf         | dddf                   t          j        d| dddf         | dddf                   z   t          j        d| dddf         | dddf                   z   z   }t          j        dt          j        ||          z            S )zCalculates the solid angles of plane triangles. Implements the method of
    Van Oosterom and Strackee [VanOosterom]_ with some modifications. Assumes
    that input points have unit norm.r   ij,ij->iNr      )nplinalgdeteinsumabsarctan2)R	numeratordenominators      `/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/scipy/spatial/_spherical_voronoi.pycalculate_solid_anglesr      s     	a  IryQqqq!tWa1g>>yQqqq!tWa1g>>?yQqqq!tWa1g>>? @K 6!bjK888999    c                   8    e Zd ZdZddZd Zd Zd Zd	 Zd
 Z	dS )r   a   Voronoi diagrams on the surface of a sphere.

    .. versionadded:: 0.18.0

    Parameters
    ----------
    points : ndarray of floats, shape (npoints, ndim)
        Coordinates of points from which to construct a spherical
        Voronoi diagram.
    radius : float, optional
        Radius of the sphere (Default: 1)
    center : ndarray of floats, shape (ndim,)
        Center of sphere (Default: origin)
    threshold : float
        Threshold for detecting duplicate points and
        mismatches between points and sphere parameters.
        (Default: 1e-06)

    Attributes
    ----------
    points : double array of shape (npoints, ndim)
        the points in `ndim` dimensions to generate the Voronoi diagram from
    radius : double
        radius of the sphere
    center : double array of shape (ndim,)
        center of the sphere
    vertices : double array of shape (nvertices, ndim)
        Voronoi vertices corresponding to points
    regions : list of list of integers of shape (npoints, _ )
        the n-th entry is a list consisting of the indices
        of the vertices belonging to the n-th point in points

    Methods
    -------
    calculate_areas
        Calculates the areas of the Voronoi regions. For 2D point sets, the
        regions are circular arcs. The sum of the areas is ``2 * pi * radius``.
        For 3D point sets, the regions are spherical polygons. The sum of the
        areas is ``4 * pi * radius**2``.

    Raises
    ------
    ValueError
        If there are duplicates in `points`.
        If the provided `radius` is not consistent with `points`.

    Notes
    -----
    The spherical Voronoi diagram algorithm proceeds as follows. The Convex
    Hull of the input points (generators) is calculated, and is equivalent to
    their Delaunay triangulation on the surface of the sphere [Caroli]_.
    The Convex Hull neighbour information is then used to
    order the Voronoi region vertices around each generator. The latter
    approach is substantially less sensitive to floating point issues than
    angle-based methods of Voronoi region vertex sorting.

    Empirical assessment of spherical Voronoi algorithm performance suggests
    quadratic time complexity (loglinear is optimal, but algorithms are more
    challenging to implement).

    References
    ----------
    .. [Caroli] Caroli et al. Robust and Efficient Delaunay triangulations of
                points on or close to a sphere. Research Report RR-7004, 2009.

    .. [VanOosterom] Van Oosterom and Strackee. The solid angle of a plane
                     triangle. IEEE Transactions on Biomedical Engineering,
                     2, 1983, pp 125--126.

    See Also
    --------
    Voronoi : Conventional Voronoi diagrams in N dimensions.

    Examples
    --------
    Do some imports and take some points on a cube:

    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> from scipy.spatial import SphericalVoronoi, geometric_slerp
    >>> from mpl_toolkits.mplot3d import proj3d
    >>> # set input data
    >>> points = np.array([[0, 0, 1], [0, 0, -1], [1, 0, 0],
    ...                    [0, 1, 0], [0, -1, 0], [-1, 0, 0], ])

    Calculate the spherical Voronoi diagram:

    >>> radius = 1
    >>> center = np.array([0, 0, 0])
    >>> sv = SphericalVoronoi(points, radius, center)

    Generate plot:

    >>> # sort vertices (optional, helpful for plotting)
    >>> sv.sort_vertices_of_regions()
    >>> t_vals = np.linspace(0, 1, 2000)
    >>> fig = plt.figure()
    >>> ax = fig.add_subplot(111, projection='3d')
    >>> # plot the unit sphere for reference (optional)
    >>> u = np.linspace(0, 2 * np.pi, 100)
    >>> v = np.linspace(0, np.pi, 100)
    >>> x = np.outer(np.cos(u), np.sin(v))
    >>> y = np.outer(np.sin(u), np.sin(v))
    >>> z = np.outer(np.ones(np.size(u)), np.cos(v))
    >>> ax.plot_surface(x, y, z, color='y', alpha=0.1)
    >>> # plot generator points
    >>> ax.scatter(points[:, 0], points[:, 1], points[:, 2], c='b')
    >>> # plot Voronoi vertices
    >>> ax.scatter(sv.vertices[:, 0], sv.vertices[:, 1], sv.vertices[:, 2],
    ...                    c='g')
    >>> # indicate Voronoi regions (as Euclidean polygons)
    >>> for region in sv.regions:
    ...    n = len(region)
    ...    for i in range(n):
    ...        start = sv.vertices[region][i]
    ...        end = sv.vertices[region][(i + 1) % n]
    ...        result = geometric_slerp(start, end, t_vals)
    ...        ax.plot(result[..., 0],
    ...                result[..., 1],
    ...                result[..., 2],
    ...                c='k')
    >>> ax.azim = 10
    >>> ax.elev = 40
    >>> _ = ax.set_xticks([])
    >>> _ = ax.set_yticks([])
    >>> _ = ax.set_zticks([])
    >>> fig.set_size_inches(4, 4)
    >>> plt.show()

    r   Nư>c                    |t          d          t          |          | _        t          j        |                              t          j                  | _        | j        j        d         | _	        |t          j
        | j	                  | _        n t          j        |t                    | _        t          j                            | j        | j        d         z
  || j        z            | _        | j        | j	        k     rt          d| j	                   t          | j                                      || j        z            rt          d          t          j                            | j        | j        z
  d          }t          j        || j        z
                                            }||| j        z  k    rt          d	          |                                  d S )
NzM`radius` is `None`. Please provide a floating point number (i.e. `radius=1`).r   )dtyper   )tolz&Rank of input points must be at least zDuplicate generators present.axisz$Radius inconsistent with generators.)
ValueErrorfloatradiusr
   arrayastypefloat64pointsshape_dimzeroscenterr   matrix_rank_rankr   query_pairsnormr   max_calc_vertices_regions)selfr#   r   r'   	thresholdradiimax_discrepancys          r   __init__zSphericalVoronoi.__init__   s   > 2 3 3 3 Fmmhv&&--bj99K%a(	>(49--DKK(6777DK Y**4;Q+G/84;/F + H H
:	!!QdiQQRRR4;++I,CDD 	><===	t{T[8qAA&!45599;;i$+555CDDD##%%%%%r   c                    t           j                            | j                  }| j        |j        ddddf         z  | j        z   | _        |j        | _	        t          j        t          | j	                            }t          j        |g| j        z                                            }| j	                                        }t          j        |d          }||                             t          j                  t          j        t          j        |dz                       fdt+          t                    dz
            D             }|| _        dS )a:  
        Calculates the Voronoi vertices and regions of the generators stored
        in self.points. The vertices will be stored in self.vertices and the
        regions in self.regions.

        This algorithm was discussed at PyData London 2015 by
        Tyler Reddy, Ross Hemsley and Nikolai Nowaczyk
        N	mergesort)kindr   c           	      \    g | ](}t          |         |d z                               )S )r   )list).0iflattened_groups	intervalss     r   
<listcomp>z;SphericalVoronoi._calc_vertices_regions.<locals>.<listcomp>   sI     6 6 6 '	!Yq1u5E(EFGG 6 6 6r   )scipyspatial
ConvexHullr#   r   	equationsr'   vertices	simplices
_simplicesr
   arangelencolumn_stackr%   ravelargsortr!   intpcumsumbincountrangeregions)	r.   convsimplex_indicestri_indicespoint_indicesindicesgroupsr;   r<   s	          @@r   r-   z'SphericalVoronoi._calc_vertices_regions   s;    }''44 dnQQQV&<<t{J. )C$8$899o&7$)&CDDJJLL--//*]===&w/66rw??Ibk-!*;<<==	6 6 6 6 6 Y!!3446 6 6r   c                 x    | j         dk    rt          d          t          j        | j        | j                   dS )a3  Sort indices of the vertices to be (counter-)clockwise ordered.

        Raises
        ------
        TypeError
            If the points are not three-dimensional.

        Notes
        -----
        For each region in regions, it sorts the indices of the Voronoi
        vertices such that the resulting points are in a clockwise or
        counterclockwise order around the generator point.

        This is done as follows: Recall that the n-th region in regions
        surrounds the n-th generator in points and that the k-th
        Voronoi vertex in vertices is the circumcenter of the k-th triangle
        in self._simplices.  For each region n, we choose the first triangle
        (=Voronoi vertex) in self._simplices and a vertex of that triangle
        not equal to the center n. These determine a unique neighbor of that
        triangle, which is then chosen as the second triangle. The second
        triangle will have a unique vertex not equal to the current vertex or
        the center. This determines a unique neighbor of the second triangle,
        which is then chosen as the third triangle and so forth. We proceed
        through all the triangles (=Voronoi vertices) belonging to the
        generator in points and obtain a sorted version of the vertices
        of its surrounding region.
           z/Only supported for three-dimensional point setsN)r%   	TypeErrorr   sort_vertices_of_regionsrD   rN   r.   s    r   rX   z)SphericalVoronoi.sort_vertices_of_regions   s;    8 9>>MNNN)$/4<HHHHHr   c                    |                                   d | j        D             }t          j        |          }|d         }d t	          |          D             }t          j        d | j        D                       }t          j        |d          }t          j        |d          }d|d<   ||dz
           ||<   | j        | j        z
  | j	        z  }| j
        | j        z
  | j	        z  }	t          j        ||         |	|         |	|         g                              |ddf          }
t          |
          }t          j        |          |dz
           }|dd xx         |d d         z  cc<   || j	        dz  z  S )	Nc                 ,    g | ]}t          |          S  )rF   )r9   regions     r   r=   z8SphericalVoronoi._calculate_areas_3d.<locals>.<listcomp>	  s    888V888r   r4   c                 <    g | ]\  }}t          |          D ]}|S r\   )rM   )r9   r:   sizejs       r   r=   z8SphericalVoronoi._calculate_areas_3d.<locals>.<listcomp>  sF     / / /wq$"'++/ /  / / / /r   c                     g | ]	}|D ]}|
S r\   r\   )r9   r]   rs      r   r=   z8SphericalVoronoi._calculate_areas_3d.<locals>.<listcomp>  s%    GGGGG1!GGGGr   r   r   rV   r	   )rX   rN   r
   rK   	enumerater    rollr#   r'   r   rB   hstackreshaper   )r.   sizescsizesnum_regionsrR   nbrs1nbrs2rS   pnormalizedvnormalized	trianglestriangle_solid_anglessolid_angless                r   _calculate_areas_3dz$SphericalVoronoi._calculate_areas_3d  s   %%'''884<8885!!Rj
/ /)E*:*: / / / GG$,GGGHH q!!'&!$$
vz*g {T[0DK?}t{2dkA I{=9*51*51! " " #*';1*=">"> 	 !7y A A y!677
CQRRL"-- dk1n,,r   c                    | j         | j                 | j        z
  }t          j        |d d df         |d d df         z
  dz  d          }t          j        d|d| j        dz  z  z  z
            }| j        |z  }t          j        t          j        d|d d df         | j	        | j        z
                      }t          j
        |dk               }dt          j        z  | j        z  ||         z
  ||<   |S )Nr   r   r	   r   r   )r#   rD   r'   r
   sumarccosr   signr   rB   wherepi)r.   arcsdthetaareassignsrS   s          r   _calculate_areas_2dz$SphericalVoronoi._calculate_areas_2d.  s    {4?+dk9 FDAJaaad+1:::	!qA)9$:;<== e# 	*d111a4j.2mdk.IK K L L(519%%RUT[05>Agr   c                     | j         dk    r|                                 S | j         dk    r|                                 S t          d          )a  Calculates the areas of the Voronoi regions.

        For 2D point sets, the regions are circular arcs. The sum of the areas
        is ``2 * pi * radius``.

        For 3D point sets, the regions are spherical polygons. The sum of the
        areas is ``4 * pi * radius**2``.

        .. versionadded:: 1.5.0

        Returns
        -------
        areas : double array of shape (npoints,)
            The areas of the Voronoi regions.
        r	   rV   z'Only supported for 2D and 3D point sets)r%   r}   rq   rW   rY   s    r   calculate_areasz SphericalVoronoi.calculate_areas@  sM      9>>++---Y!^^++---EFFFr   )r   Nr   )
__name__
__module____qualname____doc__r2   r-   rX   rq   r}   r   r\   r   r   r   r   $   s        A AD& & & &>  BI I I@%- %- %-N  $G G G G Gr   )r   numpyr
   r>    r   scipy.spatialr   __all__r   r   r\   r   r   <module>r      s                ! ! ! ! ! !
: : :qG qG qG qG qG qG qG qG qG qGr   