コード例 #1
0
def locate_point(nodes, degree, x_val, y_val):
    r"""Locate a point on a triangle.

    .. note::

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

    Does so by recursively subdividing the triangle and rejecting
    sub-triangles with bounding boxes that don't contain the point.
    After the sub-triangles are sufficiently small, uses Newton's
    method to narrow in on the pre-image of the point.

    Args:
        nodes (numpy.ndarray): Control points for B |eacute| zier triangle
            (assumed to be two-dimensional).
        degree (int): The degree of the triangle.
        x_val (float): The :math:`x`-coordinate of a point
            on the triangle.
        y_val (float): The :math:`y`-coordinate of a point
            on the triangle.

    Returns:
        Optional[Tuple[float, float]]: The :math:`s` and :math:`t`
        values corresponding to ``x_val`` and ``y_val`` or
        :data:`None` if the point is not on the ``triangle``.
    """
    # We track the centroid rather than base_x/base_y/width (by storing triple
    # the centroid -- to avoid division by three until needed). We also need
    # to track the width (or rather, just the sign of the width).
    candidates = [(1.0, 1.0, 1.0, nodes)]
    for _ in range(MAX_LOCATE_SUBDIVISIONS + 1):
        next_candidates = []
        for candidate in candidates:
            update_locate_candidates(
                candidate, next_candidates, x_val, y_val, degree
            )
        candidates = next_candidates
    if not candidates:
        return None

    # We take the average of all centroids from the candidates
    # that may contain the point.
    s_approx, t_approx = mean_centroid(candidates)
    s, t = newton_refine(nodes, degree, x_val, y_val, s_approx, t_approx)
    actual = triangle_helpers.evaluate_barycentric(
        nodes, degree, 1.0 - s - t, s, t
    )
    expected = np.asfortranarray([x_val, y_val])
    if not _py_helpers.vector_close(
        actual.ravel(order="F"), expected, eps=LOCATE_EPS
    ):
        s, t = newton_refine(nodes, degree, x_val, y_val, s, t)
    return s, t
コード例 #2
0
ファイル: test_helpers.py プロジェクト: jzhang73/bezier
    def _call_function_under_test(vec1, vec2, **kwargs):
        from bezier.hazmat import helpers

        return helpers.vector_close(vec1, vec2, **kwargs)