Esempio n. 1
0
    def evaluate_cartesian(self, s, t, _verify=True):
        r"""Compute a point on the triangle.

        Evaluates :math:`B\left(1 - s - t, s, t\right)` by calling
        :meth:`evaluate_barycentric`:

        This method acts as a (partial) inverse to :meth:`locate`.

        .. testsetup:: triangle-cartesian

           import numpy as np
           import bezier

        .. doctest:: triangle-cartesian
           :options: +NORMALIZE_WHITESPACE

           >>> nodes = np.asfortranarray([
           ...     [0.0, 0.5, 1.0  , 0.0, 0.5, 0.25],
           ...     [0.0, 0.5, 0.625, 0.5, 0.5, 1.0 ],
           ... ])
           >>> triangle = bezier.Triangle(nodes, degree=2)
           >>> point = triangle.evaluate_cartesian(0.125, 0.375)
           >>> point
           array([[0.16015625],
                  [0.44726562]])
           >>> triangle.evaluate_barycentric(0.5, 0.125, 0.375)
           array([[0.16015625],
                  [0.44726562]])

        Args:
            s (float): Parameter along the reference triangle.
            t (float): Parameter along the reference triangle.
            _verify (Optional[bool]): Indicates if the coordinates should be
                verified inside of the reference triangle. Defaults to
                :data:`True`.

        Returns:
            numpy.ndarray: The point on the triangle (as a two dimensional
            NumPy array).
        """
        if _verify:
            self._verify_cartesian(s, t)
        return _triangle_helpers.evaluate_barycentric(self._nodes,
                                                      self._degree,
                                                      1.0 - s - t, s, t)
Esempio n. 2
0
    def evaluate_barycentric(self, lambda1, lambda2, lambda3, _verify=True):
        r"""Compute a point on the triangle.

        Evaluates :math:`B\left(\lambda_1, \lambda_2, \lambda_3\right)`.

        .. image:: ../../images/triangle_evaluate_barycentric.png
           :align: center

        .. testsetup:: triangle-barycentric, triangle-barycentric-fail1,
                       triangle-barycentric-fail2,
                       triangle-barycentric-no-verify

           import numpy as np
           import bezier
           nodes = np.asfortranarray([
               [0.0, 0.5, 1.0 , 0.125, 0.375, 0.25],
               [0.0, 0.0, 0.25, 0.5  , 0.375, 1.0 ],
           ])
           triangle = bezier.Triangle(nodes, degree=2)

        .. doctest:: triangle-barycentric
           :options: +NORMALIZE_WHITESPACE

           >>> nodes = np.asfortranarray([
           ...     [0.0, 0.5, 1.0 , 0.125, 0.375, 0.25],
           ...     [0.0, 0.0, 0.25, 0.5  , 0.375, 1.0 ],
           ... ])
           >>> triangle = bezier.Triangle(nodes, degree=2)
           >>> point = triangle.evaluate_barycentric(0.125, 0.125, 0.75)
           >>> point
           array([[0.265625  ],
                  [0.73046875]])

        .. testcleanup:: triangle-barycentric

           import make_images
           make_images.triangle_evaluate_barycentric(triangle, point)

        However, this can't be used for points **outside** the
        reference triangle:

        .. doctest:: triangle-barycentric-fail1

           >>> triangle.evaluate_barycentric(-0.25, 0.75, 0.5)
           Traceback (most recent call last):
             ...
           ValueError: ('Weights must be positive', -0.25, 0.75, 0.5)

        or for non-barycentric coordinates;

        .. doctest:: triangle-barycentric-fail2

           >>> triangle.evaluate_barycentric(0.25, 0.25, 0.25)
           Traceback (most recent call last):
             ...
           ValueError: ('Weights do not sum to 1', 0.25, 0.25, 0.25)

        However, these "invalid" inputs can be used if ``_verify`` is
        :data:`False`.

        .. doctest:: triangle-barycentric-no-verify
           :options: +NORMALIZE_WHITESPACE

           >>> triangle.evaluate_barycentric(-0.25, 0.75, 0.5, _verify=False)
           array([[0.6875  ],
                  [0.546875]])
           >>> triangle.evaluate_barycentric(0.25, 0.25, 0.25, _verify=False)
           array([[0.203125],
                  [0.1875  ]])

        Args:
            lambda1 (float): Parameter along the reference triangle.
            lambda2 (float): Parameter along the reference triangle.
            lambda3 (float): Parameter along the reference triangle.
            _verify (Optional[bool]): Indicates if the barycentric coordinates
                should be verified as summing to one and all non-negative (i.e.
                verified as barycentric). Can either be used to evaluate at
                points outside the domain, or to save time when the caller
                already knows the input is verified. Defaults to :data:`True`.

        Returns:
            numpy.ndarray: The point on the triangle (as a two dimensional
            NumPy array with a single column).

        Raises:
            ValueError: If the weights are not valid barycentric
                coordinates, i.e. they don't sum to ``1``. (Won't raise if
                ``_verify=False``.)
            ValueError: If some weights are negative. (Won't raise if
                ``_verify=False``.)
        """
        if _verify:
            self._verify_barycentric(lambda1, lambda2, lambda3)
        return _triangle_helpers.evaluate_barycentric(self._nodes,
                                                      self._degree, lambda1,
                                                      lambda2, lambda3)