def _locate_point(nodes, point):
    r"""Locate a point on a curve.

    Does so by recursively subdividing the curve and rejecting
    sub-curves with bounding boxes that don't contain the point.
    After the sub-curves are sufficiently small, uses Newton's
    method to zoom in on the parameter value.

    .. note::

       This assumes, but does not check, that ``point`` is ``D x 1``,
       where ``D`` is the dimension that ``curve`` is in.

    .. note::

       There is also a Fortran implementation of this function, which
       will be used if it can be built.

    Args:
        nodes (numpy.ndarray): The nodes defining a B |eacute| zier curve.
        point (numpy.ndarray): The point to locate.

    Returns:
        Optional[float]: The parameter value (:math:`s`) corresponding
        to ``point`` or :data:`None` if the point is not on the ``curve``.

    Raises:
        ValueError: If the standard deviation of the remaining start / end
            parameters among the subdivided intervals exceeds a given
            threshold (e.g. :math:`2^{-20}`).
    """
    candidates = [(0.0, 1.0, nodes)]
    for _ in six.moves.xrange(_MAX_LOCATE_SUBDIVISIONS + 1):
        next_candidates = []
        for start, end, candidate in candidates:
            if _helpers.contains_nd(candidate, point.ravel(order="F")):
                midpoint = 0.5 * (start + end)
                left, right = subdivide_nodes(candidate)
                next_candidates.extend(
                    ((start, midpoint, left), (midpoint, end, right))
                )
        candidates = next_candidates
    if not candidates:
        return None

    params = [(start, end) for start, end, _ in candidates]
    if np.std(params) > _LOCATE_STD_CAP:
        raise ValueError("Parameters not close enough to one another", params)

    s_approx = np.mean(params)
    s_approx = newton_refine(nodes, point, s_approx)
    # NOTE: Since ``np.mean(params)`` must be in ``[0, 1]`` it's
    #       "safe" to push the Newton-refined value back into the unit
    #       interval.
    if s_approx < 0.0:
        return 0.0

    elif s_approx > 1.0:
        return 1.0

    else:
        return s_approx
def _locate_point ( nodes , point ) : candidates = [ ( 0.0 , 1.0 , nodes ) ] for _ in six . moves . xrange ( _MAX_LOCATE_SUBDIVISIONS + 1 ) : next_candidates = [ ] for start , end , candidate in candidates : if _helpers . contains_nd ( candidate , point . ravel ( order = "F" ) ) : midpoint = 0.5 * ( start + end ) left , right = subdivide_nodes ( candidate ) next_candidates . extend ( ( ( start , midpoint , left ) , ( midpoint , end , right ) ) ) candidates = next_candidates if not candidates : return None params = [ ( start , end ) for start , end , _ in candidates ] if np . std ( params ) > _LOCATE_STD_CAP : raise ValueError ( "Parameters not close enough to one another" , params ) s_approx = np . mean ( params ) s_approx = newton_refine ( nodes , point , s_approx ) if s_approx < 0.0 : return 0.0 elif s_approx > 1.0 : return 1.0 else : return s_approx
r"""Locate a point on a curve.

    Does so by recursively subdividing the curve and rejecting
    sub-curves with bounding boxes that don't contain the point.
    After the sub-curves are sufficiently small, uses Newton's
    method to zoom in on the parameter value.

    .. note::

       This assumes, but does not check, that ``point`` is ``D x 1``,
       where ``D`` is the dimension that ``curve`` is in.

    .. note::

       There is also a Fortran implementation of this function, which
       will be used if it can be built.

    Args:
        nodes (numpy.ndarray): The nodes defining a B |eacute| zier curve.
        point (numpy.ndarray): The point to locate.

    Returns:
        Optional[float]: The parameter value (:math:`s`) corresponding
        to ``point`` or :data:`None` if the point is not on the ``curve``.

    Raises:
        ValueError: If the standard deviation of the remaining start / end
            parameters among the subdivided intervals exceeds a given
            threshold (e.g. :math:`2^{-20}`).