Project: bezier

Helper for Bézier Curves, Triangles, and Higher Order Objects

Project Details

Latest version
2023.7.28
Home Page
https://github.com/dhermes/bezier
PyPI Page
https://pypi.org/project/bezier/

Project Popularity

PageRank
0.0015248169796761278
Number of downloads
345585

bezier

Helper for B |eacute| zier Curves, Triangles, and Higher Order Objects

|linux-build| |macos-build| |windows-build| |coverage|

|docs| |zenodo| |JOSS|

.. |eacute| unicode:: U+000E9 .. LATIN SMALL LETTER E WITH ACUTE :trim:

This library provides:

  • Support for B |eacute| zier Curves_
  • Support for B |eacute| zier Triangles_

Dive in and take a look!

.. image:: https://raw.githubusercontent.com/dhermes/bezier/2023.7.28/docs/images/triangles6Q_and_7Q.png :align: center

Why B |eacute| zier?

A B |eacute| zier curve (and triangle, etc.) is a parametric curve that uses the Bernstein basis_:

.. image:: https://raw.githubusercontent.com/dhermes/bezier/2023.7.28/docs/images/bernstein_basis.png :align: center

to define a curve as a linear combination:

.. image:: https://raw.githubusercontent.com/dhermes/bezier/2023.7.28/docs/images/bezier_defn.png :align: center

This comes from the fact that the weights sum to one:

.. image:: https://raw.githubusercontent.com/dhermes/bezier/2023.7.28/docs/images/sum_to_unity.png :align: center

This can be generalized to higher order by considering three, four, etc. non-negative weights that sum to one (in the above we have the two non-negative weights s and 1 - s).

Due to their simple form, B |eacute| zier curves:

  • can easily model geometric objects as parametric curves, triangles, etc.
  • can be computed in an efficient and numerically stable way via de Casteljau's algorithm_
  • can utilize convex optimization techniques for many algorithms (such as curve-curve intersection), since curves (and triangles, etc.) are convex combinations of the basis

Many applications -- as well as the history of their development -- are described in "The Bernstein polynomial basis: A centennial retrospective_", for example;

  • aids physical analysis using finite element methods (FEM) on isogeometric models by using geometric shape functions called NURBS to represent data
  • used in robust control of dynamic systems; utilizes convexity to create a hull of curves

.. _retrospective: https://dx.doi.org/10.1016/j.cagd.2012.03.001 .. _Bernstein basis: https://en.wikipedia.org/wiki/Bernstein_polynomial .. _de Casteljau's algorithm: https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm .. _FEM: https://en.wikipedia.org/wiki/Finite_element_method .. _NURBS: https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline

Installing

The bezier Python package can be installed with pip_:

.. code-block:: console

$ python -m pip install --upgrade bezier $ python3.11 -m pip install --upgrade bezier $ # To install optional dependencies, e.g. SymPy $ python -m pip install --upgrade bezier[full]

To install a pure Python version (i.e. with no binary extension):

.. code-block:: console

$ BEZIER_NO_EXTENSION=true \

python -m pip install --upgrade bezier --no-binary=bezier

bezier is open-source, so you can alternatively grab the source code from GitHub_ and install from source.

.. _pip: https://pip.pypa.io .. _GitHub: https://github.com/dhermes/bezier/

Getting Started

For example, to create a curve:

.. code-block:: python

import bezier import numpy as np nodes1 = np.asfortranarray([ ... [0.0, 0.5, 1.0], ... [0.0, 1.0, 0.0], ... ]) curve1 = bezier.Curve(nodes1, degree=2)

The intersection (points) between two curves can also be determined:

.. code-block:: python

nodes2 = np.asfortranarray([ ... [0.0, 0.25, 0.5, 0.75, 1.0], ... [0.0, 2.0 , -2.0, 2.0 , 0.0], ... ]) curve2 = bezier.Curve.from_nodes(nodes2) intersections = curve1.intersect(curve2) intersections array([[0.31101776, 0.68898224, 0. , 1. ], [0.31101776, 0.68898224, 0. , 1. ]]) s_vals = np.asfortranarray(intersections[0, :]) points = curve1.evaluate_multi(s_vals) points array([[0.31101776, 0.68898224, 0. , 1. ], [0.42857143, 0.42857143, 0. , 0. ]])

and then we can plot these curves (along with their intersections):

.. code-block:: python

import seaborn seaborn.set()

ax = curve1.plot(num_pts=256) _ = curve2.plot(num_pts=256, ax=ax) lines = ax.plot( ... points[0, :], points[1, :], ... marker="o", linestyle="None", color="black") _ = ax.axis("scaled") _ = ax.set_xlim(-0.125, 1.125) _ = ax.set_ylim(-0.0625, 0.625)

.. image:: https://raw.githubusercontent.com/dhermes/bezier/2023.7.28/docs/images/curves1_and_13.png :align: center

For API-level documentation, check out the B |eacute| zier Python package_ documentation.

Development

To work on adding a feature or to run the functional tests, see the DEVELOPMENT doc_ for more information on how to get started.

Citation

For publications that use bezier, there is a JOSS paper_ that can be cited. The following BibTeX entry can be used:

.. code-block:: rest

@article{Hermes2017, doi = {10.21105/joss.00267}, url = {https://doi.org/10.21105%2Fjoss.00267}, year = {2017}, month = {Aug}, publisher = {The Open Journal}, volume = {2}, number = {16}, pages = {267}, author = {Danny Hermes}, title = {Helper for B{'{e}}zier Curves, Triangles, and Higher Order Objects}, journal = {The Journal of Open Source Software} }

A particular version of this library can be cited via a Zenodo DOI; see a full list by version_.

.. _JOSS paper: https://joss.theoj.org/papers/10.21105/joss.00267 .. _list by version: https://zenodo.org/search?page=1&size=20&q=conceptrecid:%22838307%22&sort=-version&all_versions=True

License

bezier is made available under the Apache 2.0 License. For more details, see the LICENSE_.

.. _Curves: https://bezier.readthedocs.io/en/2023.7.28/python/reference/bezier.curve.html .. _Triangles: https://bezier.readthedocs.io/en/2023.7.28/python/reference/bezier.triangle.html .. _package: https://bezier.readthedocs.io/en/2023.7.28/python/reference/bezier.html .. _DEVELOPMENT doc: https://github.com/dhermes/bezier/blob/2023.7.28/DEVELOPMENT.rst .. _the LICENSE: https://github.com/dhermes/bezier/blob/2023.7.28/LICENSE

.. |docs| image:: https://readthedocs.org/projects/bezier/badge/?version=2023.7.28 :target: https://bezier.readthedocs.io/en/2023.7.28/ :alt: Documentation Status .. |linux-build| image:: https://raw.githubusercontent.com/dhermes/bezier/2023.7.28/docs/linux-passing.svg?sanitize=true :target: https://github.com/dhermes/bezier/actions/runs/5698156661 :alt: Linux Build (GitHub Actions) .. |macos-build| image:: https://raw.githubusercontent.com/dhermes/bezier/2023.7.28/docs/macos-passing.svg?sanitize=true :target: https://github.com/dhermes/bezier/actions/runs/5698156663 :alt: macOS Build (GitHub Actions) .. |windows-build| image:: https://raw.githubusercontent.com/dhermes/bezier/2023.7.28/docs/windows-passing.svg?sanitize=true :target: https://github.com/dhermes/bezier/actions/run/5698156662 :alt: Windows Build (GitHub Actions) .. |coverage| image:: https://s3.amazonaws.com/assets.coveralls.io/badges/coveralls_100.svg :target: https://coveralls.io/builds/61654285 :alt: Code Coverage .. |zenodo| image:: https://zenodo.org/badge/73047402.svg :target: https://zenodo.org/badge/latestdoi/73047402 :alt: Zenodo DOI for bezier .. |JOSS| image:: https://joss.theoj.org/papers/10.21105/joss.00267/status.svg :target: https://dx.doi.org/10.21105/joss.00267 :alt: "Journal of Open Source Science" DOI for bezier