Skip to content

Latest commit

 

History

History
597 lines (523 loc) · 24.7 KB

triangle.rst

File metadata and controls

597 lines (523 loc) · 24.7 KB

triangle module

This is a collection of procedures for performing computations on a Bézier triangle.

Note

In most of the procedures below both the number of nodes N and the degree d of a Bézier triangle are provided. It is redundant to require both as arguments since N = \binom{d + 2}{2}. However, both are provided as arguments to avoid unnecessary re-computation, i.e. we expect the caller to know both N and d.

Procedures

.. c:function:: void BEZ_compute_area(const int *num_edges, \
                                      const int *sizes, \
                                      const double* const* nodes_pointers, \
                                      double *area, \
                                      bool *not_implemented)

   This computes the area of a curved polygon in :math:`\mathbf{R}^2` via
   Green's theorem. In order to do this, it assumes that the edges

   * form a closed loop
   * have no intersections with another edge (including self)
   * are oriented in the direction of the exterior

   :param num_edges:
      **[Input]** The number of edges :math:`N` that bound the curved polygon.
   :type num_edges: :c:expr:`const int*`
   :param sizes:
      **[Input]** An array of the size (i.e. the number of nodes) of each
      of the :math:`N` edges.
   :type sizes: :c:expr:`const int*`
   :param nodes_pointers:
      **[Input]** An array of :math:`N` pointers. Pointer :math:`j` points to
      the start of the edge :math:`E_j` along the boundary of the curved
      polygon. (This is a ``const`` array of ``const`` pointers, i.e. the
      ``double**`` pointer array cannot be modified and the underlying
      ``double*`` arrays pointed to by each element cannot be modified.)
   :type nodes_pointers: :c:expr:`const double* const*`
   :param area:
      **[Output]** The computed area of the curved polygon. If
      ``not_implemented`` is ``TRUE``, then this is undefined.
   :type area: :c:expr:`double*`
   :param not_implemented:
      **[Output]** Indicates if a Green's theorem implementation exists for
      each of the edges. (Currently, the only degrees supported are 1, 2,
      3 and 4.)
   :type not_implemented: :c:expr:`bool*`

   **Signature:**

   .. code-block:: c

      void
      BEZ_compute_area(const int *num_edges,
                       const int *sizes,
                       const double* const* nodes_pointers,
                       double *area,
                       bool *not_implemented);

.. c:function:: void BEZ_compute_edge_nodes(const int *num_nodes, \
                                            const int *dimension, \
                                            const double *nodes, \
                                            const int *degree, \
                                            double *nodes1, \
                                            double *nodes2, \
                                            double *nodes3)

   Extracts the edge nodes from the control net of a B |eacute| zier triangle.
   For example, if the control net of a quadratic triangle is:

   .. math::

      \left[\begin{array}{c c c c c c}
          v_{2,0,0} & v_{1,1,0} &
          v_{0,2,0} & v_{1,0,1} &
          v_{0,1,1} & v_{0,0,2} \end{array}\right] =
      \left[\begin{array}{c c c c c c}
          a & b & c & d & e & f \end{array}\right]

   then the edges are

   .. math::

      \begin{align*}
      E_1 &= \left[\begin{array}{c c c}
          a & b & c \end{array}\right] \\
      E_2 &= \left[\begin{array}{c c c}
          c & e & f \end{array}\right] \\
      E_3 &= \left[\begin{array}{c c c}
          f & d & a \end{array}\right].
      \end{align*}

   :param num_nodes:
      **[Input]** The number of nodes :math:`N` in the control net of the
      B |eacute| zier triangle.
   :type num_nodes: :c:expr:`const int*`
   :param dimension:
      **[Input]** The dimension :math:`D` such that the triangle lies in
      :math:`\mathbf{R}^D`.
   :type dimension: :c:expr:`const int*`
   :param nodes:
      **[Input]** The actual control net of the B |eacute| zier triangle as a
      :math:`D \times N` array. This should be laid out in Fortran order, with
      :math:`D N` total values.
   :type nodes: :c:expr:`const double*`
   :param degree:
      **[Input]** The degree :math:`d` of the B |eacute| zier triangle.
   :type degree: :c:expr:`const int*`
   :param nodes1:
      **[Output]** The control points of the first edge B |eacute| zier curve
      as a :math:`D \times (d + 1)` array, laid out in Fortran order.
   :type nodes1: :c:expr:`double*`
   :param nodes2:
      **[Output]** The control points of the second edge B |eacute| zier curve
      as a :math:`D \times (d + 1)` array, laid out in Fortran order.
   :type nodes2: :c:expr:`double*`
   :param nodes3:
      **[Output]** The control points of the third edge B |eacute| zier curve
      as a :math:`D \times (d + 1)` array, laid out in Fortran order.
   :type nodes3: :c:expr:`double*`

   **Signature:**

   .. code-block:: c

      void
      BEZ_compute_edge_nodes(const int *num_nodes,
                             const int *dimension,
                             const double *nodes,
                             const int *degree,
                             double *nodes1,
                             double *nodes2,
                             double *nodes3);

.. c:function:: void BEZ_de_casteljau_one_round(const int *num_nodes, \
                                                const int *dimension, \
                                                const double *nodes, \
                                                const int *degree, \
                                                const double *lambda1, \
                                                const double *lambda2, \
                                                const double *lambda3, \
                                                double *new_nodes)

   This performs a single round of the de Casteljau algorithm for evaluation
   in barycentric coordinates :math:`B(\lambda_1, \lambda_2, \lambda_3)`. This
   reduces the control net :math:`v_{i, j, k}^d` to a lower degree control net

   .. math::

      v_{i, j, k}^{d - 1} = \lambda_1 v_{i + 1, j, k}^d +
          \lambda_2 v_{i, j + 1, k}^d + \lambda_3 v_{i, j, k + 1}^d.

   :param num_nodes:
      **[Input]** The number of nodes :math:`N` in the control net of the
      B |eacute| zier triangle.
   :type num_nodes: :c:expr:`const int*`
   :param dimension:
      **[Input]** The dimension :math:`D` such that the triangle lies in
      :math:`\mathbf{R}^D`.
   :type dimension: :c:expr:`const int*`
   :param nodes:
      **[Input]** The actual control net of the B |eacute| zier triangle as a
      :math:`D \times N` array. This should be laid out in Fortran order, with
      :math:`D N` total values.
   :type nodes: :c:expr:`const double*`
   :param degree:
      **[Input]** The degree :math:`d` of the B |eacute| zier triangle.
   :type degree: :c:expr:`const int*`
   :param lambda1:
      **[Input]** The first barycentric parameter along the reference triangle.
   :type lambda1: :c:expr:`const double*`
   :param lambda2:
      **[Input]** The second barycentric parameter along the reference
      triangle.
   :type lambda2: :c:expr:`const double*`
   :param lambda3:
      **[Input]** The third barycentric parameter along the reference triangle.
   :type lambda3: :c:expr:`const double*`
   :param new_nodes:
      **[Output]** The newly-formed degree :math:`d - 1` control net. This will
      be a :math:`D \times (N - d - 1)` array.
   :type new_nodes: :c:expr:`double*`

   **Signature:**

   .. code-block:: c

      void
      BEZ_de_casteljau_one_round(const int *num_nodes,
                                 const int *dimension,
                                 const double *nodes,
                                 const int *degree,
                                 const double *lambda1,
                                 const double *lambda2,
                                 const double *lambda3,
                                 double *new_nodes);

.. c:function:: void BEZ_evaluate_barycentric(const int *num_nodes, \
                                              const int *dimension, \
                                              const double *nodes, \
                                              const int *degree, \
                                              const double *lambda1, \
                                              const double *lambda2, \
                                              const double *lambda3, \
                                              double *point)

   Evaluates a single point on a B |eacute| zier triangle, with input
   in barycentric coordinates: :math:`B(\lambda_1, \lambda_2, \lambda_3)`.

   :param num_nodes:
      **[Input]** The number of nodes :math:`N` in the control net of the
      B |eacute| zier triangle.
   :type num_nodes: :c:expr:`const int*`
   :param dimension:
      **[Input]** The dimension :math:`D` such that the triangle lies in
      :math:`\mathbf{R}^D`.
   :type dimension: :c:expr:`const int*`
   :param nodes:
      **[Input]** The actual control net of the B |eacute| zier triangle as a
      :math:`D \times N` array. This should be laid out in Fortran order, with
      :math:`D N` total values.
   :type nodes: :c:expr:`const double*`
   :param degree:
      **[Input]** The degree :math:`d` of the B |eacute| zier triangle.
   :type degree: :c:expr:`const int*`
   :param lambda1:
      **[Input]** The first barycentric parameter along the reference triangle.
   :type lambda1: :c:expr:`const double*`
   :param lambda2:
      **[Input]** The second barycentric parameter along the reference
      triangle.
   :type lambda2: :c:expr:`const double*`
   :param lambda3:
      **[Input]** The third barycentric parameter along the reference triangle.
   :type lambda3: :c:expr:`const double*`
   :param point:
      **[Output]** A :math:`D \times 1` array, will contain
      :math:`B(\lambda_1, \lambda_2, \lambda_3)`.
   :type point: :c:expr:`double*`

   **Signature:**

   .. code-block:: c

      void
      BEZ_evaluate_barycentric(const int *num_nodes,
                               const int *dimension,
                               const double *nodes,
                               const int *degree,
                               const double *lambda1,
                               const double *lambda2,
                               const double *lambda3,
                               double *point);

.. c:function:: void BEZ_evaluate_barycentric_multi(const int *num_nodes, \
                                                    const int *dimension, \
                                                    const double *nodes, \
                                                    const int *degree, \
                                                    const int *num_vals, \
                                                    const double *param_vals, \
                                                    double *evaluated)

   Evaluates many points on a B |eacute| zier triangle, with input
   in barycentric coordinates:
   :math:`\left\{B(\lambda_{1,j}, \lambda_{2,j}, \lambda_{3,j})\right\}_j`.

   :param num_nodes:
      **[Input]** The number of nodes :math:`N` in the control net of the
      B |eacute| zier triangle.
   :type num_nodes: :c:expr:`const int*`
   :param dimension:
      **[Input]** The dimension :math:`D` such that the triangle lies in
      :math:`\mathbf{R}^D`.
   :type dimension: :c:expr:`const int*`
   :param nodes:
      **[Input]** The actual control net of the B |eacute| zier triangle as a
      :math:`D \times N` array. This should be laid out in Fortran order, with
      :math:`D N` total values.
   :type nodes: :c:expr:`const double*`
   :param degree:
      **[Input]** The degree :math:`d` of the B |eacute| zier triangle.
   :type degree: :c:expr:`const int*`
   :param num_vals:
      **[Input]** The number of points :math:`k` where :math:`B` is
      being evaluated.
   :type num_vals: :c:expr:`const int*`
   :param param_vals:
      **[Input]** A :math:`k \times 3` array of :math:`k` triples of
      barycentric coordinates, laid out in Fortran order. This way, the
      first column contains all :math:`\lambda_1` values in contiguous order,
      and similarly for the other columns.
   :type param_vals: :c:expr:`const double*`
   :param evaluated:
      **[Output]** A :math:`D \times k` array of all evaluated points on the
      triangle. Column :math:`j` will contain
      :math:`B(\lambda_{1,j}, \lambda_{2,j}, \lambda_{3,j})`.
   :type evaluated: :c:expr:`double*`

   **Signature:**

   .. code-block:: c

      void
      BEZ_evaluate_barycentric_multi(const int *num_nodes,
                                     const int *dimension,
                                     const double *nodes,
                                     const int *degree,
                                     const int *num_vals,
                                     const double *param_vals,
                                     double *evaluated);

.. c:function:: void BEZ_evaluate_cartesian_multi(const int *num_nodes, \
                                                  const int *dimension, \
                                                  const double *nodes, \
                                                  const int *degree, \
                                                  const int *num_vals, \
                                                  const double *param_vals, \
                                                  double *evaluated)

   Evaluates many points on a B |eacute| zier triangle, with input
   in cartesian coordinates:
   :math:`\left\{B(s_j, t_j)\right\}_j`. Each input :math:`(s, t)` is
   equivalent to the barycentric input :math:`\lambda_1 = 1 - s - t`,
   :math:`\lambda_2 = s` and :math:`\lambda_3 = t`.

   :param num_nodes:
      **[Input]** The number of nodes :math:`N` in the control net of the
      B |eacute| zier triangle.
   :type num_nodes: :c:expr:`const int*`
   :param dimension:
      **[Input]** The dimension :math:`D` such that the triangle lies in
      :math:`\mathbf{R}^D`.
   :type dimension: :c:expr:`const int*`
   :param nodes:
      **[Input]** The actual control net of the B |eacute| zier triangle as a
      :math:`D \times N` array. This should be laid out in Fortran order, with
      :math:`D N` total values.
   :type nodes: :c:expr:`const double*`
   :param degree:
      **[Input]** The degree :math:`d` of the B |eacute| zier triangle.
   :type degree: :c:expr:`const int*`
   :param num_vals:
      **[Input]** The number of points :math:`k` where :math:`B` is
      being evaluated.
   :type num_vals: :c:expr:`const int*`
   :param param_vals:
      **[Input]** A :math:`k \times 2` array of :math:`k` pairs of
      cartesian coordinates, laid out in Fortran order. This way, the
      first column contains all :math:`s`\-values in contiguous order,
      and similarly for the other column.
   :type param_vals: :c:expr:`const double*`
   :param evaluated:
      **[Output]** A :math:`D \times k` array of all evaluated points on the
      triangle. Column :math:`j` will contain
      :math:`B(s_j, t_j)`.
   :type evaluated: :c:expr:`double*`

   **Signature:**

   .. code-block:: c

      void
      BEZ_evaluate_cartesian_multi(const int *num_nodes,
                                   const int *dimension,
                                   const double *nodes,
                                   const int *degree,
                                   const int *num_vals,
                                   const double *param_vals,
                                   double *evaluated);

.. c:function:: void BEZ_jacobian_both(const int *num_nodes, \
                                       const int *dimension, \
                                       const double *nodes, \
                                       const int *degree, \
                                       double *new_nodes)

   Computes control nets for both cartesian partial derivatives of a
   B |eacute| zier triangle :math:`B_s(s, t)` and :math:`B_t(s, t)`. Taking
   a single (partial) derivative lowers the degree by 1.

   :param num_nodes:
      **[Input]** The number of nodes :math:`N` in the control net of the
      B |eacute| zier triangle.
   :type num_nodes: :c:expr:`const int*`
   :param dimension:
      **[Input]** The dimension :math:`D` such that the triangle lies in
      :math:`\mathbf{R}^D`.
   :type dimension: :c:expr:`const int*`
   :param nodes:
      **[Input]** The actual control net of the B |eacute| zier triangle as a
      :math:`D \times N` array. This should be laid out in Fortran order, with
      :math:`D N` total values.
   :type nodes: :c:expr:`const double*`
   :param degree:
      **[Input]** The degree :math:`d` of the B |eacute| zier triangle.
   :type degree: :c:expr:`const int*`
   :param new_nodes:
      **[Output]** The combined control nets :math:`B_s` and :math:`B_t` as
      a :math:`(2D) \times (N - d - 1)` array, laid out in Fortran order. The
      first :math:`D` columns contain the control net of :math:`B_s` and
      final :math:`D` columns contain the control net of :math:`B_t`.
   :type new_nodes: :c:expr:`double*`

   **Signature:**

   .. code-block:: c

      void
      BEZ_jacobian_both(const int *num_nodes,
                        const int *dimension,
                        const double *nodes,
                        const int *degree,
                        double *new_nodes);

.. c:function:: void BEZ_jacobian_det(const int *num_nodes, \
                                      const double *nodes, \
                                      const int *degree, \
                                      const int *num_vals, \
                                      const double *param_vals, \
                                      double *evaluated)

   Computes :math:`\det(DB)` at many points :math:`(s_j, t_j)`. This is only
   well-defined if :math:`\det(DB)` has two rows, hence the triangle must lie
   in :math:`\mathbf{R}^2`.

   :param num_nodes:
      **[Input]** The number of nodes :math:`N` in the control net of the
      B |eacute| zier triangle.
   :type num_nodes: :c:expr:`const int*`
   :param nodes:
      **[Input]** The actual control net of the B |eacute| zier triangle as a
      :math:`2 \times N` array. This should be laid out in Fortran order, with
      :math:`2 N` total values.
   :type nodes: :c:expr:`const double*`
   :param degree:
      **[Input]** The degree :math:`d` of the B |eacute| zier triangle.
   :type degree: :c:expr:`const int*`
   :param num_vals:
      **[Input]** The number of points :math:`k` where :math:`\det(DB)` is
      being evaluated.
   :type num_vals: :c:expr:`const int*`
   :param param_vals:
      **[Input]** A :math:`k \times 2` array of :math:`k` pairs of
      cartesian coordinates, laid out in Fortran order. This way, the
      first column contains all :math:`s`\-values in contiguous order,
      and similarly for the other column.
   :type param_vals: :c:expr:`const double*`
   :param evaluated:
      **[Output]** A :math:`k` array of all evaluated determinants. The
      :math:`j`\-th value will be :math:`\det(DB(s_j, t_j))`.
   :type evaluated: :c:expr:`double*`

   **Signature:**

   .. code-block:: c

      void
      BEZ_jacobian_det(const int *num_nodes,
                       const double *nodes,
                       const int *degree,
                       const int *num_vals,
                       const double *param_vals,
                       double *evaluated);

.. c:function:: void BEZ_specialize_triangle(const int *num_nodes, \
                                             const int *dimension, \
                                             const double *nodes, \
                                             const int *degree, \
                                             const double *weights_a, \
                                             const double *weights_b, \
                                             const double *weights_c, \
                                             double *specialized)

   Changes the control net for a B |eacute| zier triangle by specializing
   from the original triangle :math:`(0, 0), (1, 0), (0, 1)` to a new
   triangle :math:`p_1, p_2, p_3`.

   :param num_nodes:
      **[Input]** The number of nodes :math:`N` in the control net of the
      B |eacute| zier triangle.
   :type num_nodes: :c:expr:`const int*`
   :param dimension:
      **[Input]** The dimension :math:`D` such that the triangle lies in
      :math:`\mathbf{R}^D`.
   :type dimension: :c:expr:`const int*`
   :param nodes:
      **[Input]** The actual control net of the B |eacute| zier triangle as a
      :math:`D \times N` array. This should be laid out in Fortran order, with
      :math:`D N` total values.
   :type nodes: :c:expr:`const double*`
   :param degree:
      **[Input]** The degree :math:`d` of the B |eacute| zier triangle.
   :type degree: :c:expr:`const int*`
   :param weights_a:
      **[Input]** A 3-array containing the barycentric weights for the first
      node :math:`p_1` in the new triangle.
   :type weights_a: :c:expr:`const double*`
   :param weights_b:
      **[Input]** A 3-array containing the barycentric weights for the second
      node :math:`p_2` in the new triangle.
   :type weights_b: :c:expr:`const double*`
   :param weights_c:
      **[Input]** A 3-array containing the barycentric weights for the third
      node :math:`p_3` in the new triangle.
   :type weights_c: :c:expr:`const double*`
   :param specialized:
      **[Output]** The control net of the newly formed B |eacute| zier triangle
      as a :math:`D \times N` array.
   :type specialized: :c:expr:`double*`

   **Signature:**

   .. code-block:: c

      void
      BEZ_specialize_triangle(const int *num_nodes,
                              const int *dimension,
                              const double *nodes,
                              const int *degree,
                              const double *weights_a,
                              const double *weights_b,
                              const double *weights_c,
                              double *specialized);

.. c:function:: void BEZ_subdivide_nodes_triangle(const int *num_nodes, \
                                                  const int *dimension, \
                                                  const double *nodes, \
                                                  const int *degree, \
                                                  double *nodes_a, \
                                                  double *nodes_b, \
                                                  double *nodes_c, \
                                                  double *nodes_d)

   Subdivides a B |eacute| zier triangle into four sub-triangles that cover
   the original triangle. See :meth:`.Triangle.subdivide` for more
   details

   :param num_nodes:
      **[Input]** The number of nodes :math:`N` in the control net of the
      B |eacute| zier triangle.
   :type num_nodes: :c:expr:`const int*`
   :param dimension:
      **[Input]** The dimension :math:`D` such that the triangle lies in
      :math:`\mathbf{R}^D`.
   :type dimension: :c:expr:`const int*`
   :param nodes:
      **[Input]** The actual control net of the B |eacute| zier triangle as a
      :math:`D \times N` array. This should be laid out in Fortran order, with
      :math:`D N` total values.
   :type nodes: :c:expr:`const double*`
   :param degree:
      **[Input]** The degree :math:`d` of the B |eacute| zier triangle.
   :type degree: :c:expr:`const int*`
   :param nodes_a:
      **[Output]** The control net of the lower left sub-triangle as a
      :math:`D \times N` array, laid out in Fortran order.
   :type nodes_a: :c:expr:`double*`
   :param nodes_b:
      **[Output]** The control net of the central sub-triangle as a
      :math:`D \times N` array, laid out in Fortran order.
   :type nodes_b: :c:expr:`double*`
   :param nodes_c:
      **[Output]** The control net of the lower right sub-triangle as a
      :math:`D \times N` array, laid out in Fortran order.
   :type nodes_c: :c:expr:`double*`
   :param nodes_d:
      **[Output]** The control net of the upper left sub-triangle as a
      :math:`D \times N` array, laid out in Fortran order.
   :type nodes_d: :c:expr:`double*`

   **Signature:**

   .. code-block:: c

      void
      BEZ_subdivide_nodes_triangle(const int *num_nodes,
                                   const int *dimension,
                                   const double *nodes,
                                   const int *degree,
                                   double *nodes_a,
                                   double *nodes_b,
                                   double *nodes_c,
                                   double *nodes_d);