added example to README plus minor changed
example regarding computing many points quickly with numpy arrayspull/7/merge
parent
dcd4896fd6
commit
3ad65aa3c5
45
README.ipynb
45
README.ipynb
|
@ -86,7 +86,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 5,
|
"execution_count": 1,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": true
|
"collapsed": true
|
||||||
},
|
},
|
||||||
|
@ -97,7 +97,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 6,
|
"execution_count": 2,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -147,7 +147,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": 3,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -224,7 +224,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 8,
|
"execution_count": 4,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -270,7 +270,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 9,
|
"execution_count": 5,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -305,7 +305,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 10,
|
"execution_count": 6,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -346,8 +346,8 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Tangent vectors and Bezier curves as numpy polynomial objects\n",
|
"### Bezier curves as NumPy polynomial objects\n",
|
||||||
"Another great way to work with the parameterizations for Line, QuadraticBezier, and CubicBezier objects is to convert them to ``numpy.poly1d`` objects. This is done easily using the ``Line.poly()``, ``QuadraticBezier.poly()`` and ``CubicBezier.poly()`` methods. \n",
|
"Another great way to work with the parameterizations for `Line`, `QuadraticBezier`, and `CubicBezier` objects is to convert them to ``numpy.poly1d`` objects. This is done easily using the ``Line.poly()``, ``QuadraticBezier.poly()`` and ``CubicBezier.poly()`` methods. \n",
|
||||||
"There's also a ``polynomial2bezier()`` function in the pathtools.py submodule to convert polynomials back to Bezier curves. \n",
|
"There's also a ``polynomial2bezier()`` function in the pathtools.py submodule to convert polynomials back to Bezier curves. \n",
|
||||||
"\n",
|
"\n",
|
||||||
"**Note:** cubic Bezier curves are parameterized as $$\\mathcal{B}(t) = P_0(1-t)^3 + 3P_1(1-t)^2t + 3P_2(1-t)t^2 + P_3t^3$$\n",
|
"**Note:** cubic Bezier curves are parameterized as $$\\mathcal{B}(t) = P_0(1-t)^3 + 3P_1(1-t)^2t + 3P_2(1-t)t^2 + P_3t^3$$\n",
|
||||||
|
@ -363,12 +363,12 @@
|
||||||
"\\end{bmatrix}\n",
|
"\\end{bmatrix}\n",
|
||||||
"\\begin{bmatrix}P_0\\\\P_1\\\\P_2\\\\P_3\\end{bmatrix}$$ \n",
|
"\\begin{bmatrix}P_0\\\\P_1\\\\P_2\\\\P_3\\end{bmatrix}$$ \n",
|
||||||
"\n",
|
"\n",
|
||||||
"QuadraticBezier.poly() and Line.poly() are defined similarly."
|
"`QuadraticBezier.poly()` and `Line.poly()` are [defined similarly](https://en.wikipedia.org/wiki/B%C3%A9zier_curve#General_definition)."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 11,
|
"execution_count": 7,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -409,14 +409,23 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"To illustrate the awesomeness of being able to convert our Bezier curve objects to numpy.poly1d objects and back, lets compute the unit tangent vector of the above CubicBezier object, b, at t=0.5 in four different ways.\n",
|
"The ability to convert between Bezier objects to NumPy polynomial objects is very useful. For starters, we can take turn a list of Bézier segments into a NumPy array \n",
|
||||||
|
"### Numpy Array operations on Bézier path segments\n",
|
||||||
|
"[Example available here](https://github.com/mathandy/svgpathtools/blob/master/examples/compute-many-points-quickly-using-numpy-arrays.py)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"To further illustrate the power of being able to convert our Bezier curve objects to numpy.poly1d objects and back, lets compute the unit tangent vector of the above CubicBezier object, b, at t=0.5 in four different ways.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"### Tangent vectors (and more on polynomials)"
|
"### Tangent vectors (and more on NumPy polynomials)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 12,
|
"execution_count": 8,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -471,7 +480,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 13,
|
"execution_count": 9,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -514,7 +523,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 14,
|
"execution_count": 10,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -556,7 +565,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 15,
|
"execution_count": 11,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -611,7 +620,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 16,
|
"execution_count": 12,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -646,7 +655,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 17,
|
"execution_count": 13,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
|
64
README.rst
64
README.rst
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
svgpathtools
|
svgpathtools
|
||||||
============
|
============
|
||||||
|
|
||||||
|
@ -37,11 +38,6 @@ Some included tools:
|
||||||
- compute **inverse arc length**
|
- compute **inverse arc length**
|
||||||
- convert RGB color tuples to hexadecimal color strings and back
|
- convert RGB color tuples to hexadecimal color strings and back
|
||||||
|
|
||||||
Note on Python 3
|
|
||||||
----------------
|
|
||||||
While I am hopeful that this package entirely works with Python 3, it was born from a larger project coded in Python 2 and has not been thoroughly tested in
|
|
||||||
Python 3. Please let me know if you find any incompatibilities.
|
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
@ -85,8 +81,6 @@ Much of the core of this module was taken from `the svg.path (v2.0)
|
||||||
module <https://github.com/regebro/svg.path>`__. Interested svg.path
|
module <https://github.com/regebro/svg.path>`__. Interested svg.path
|
||||||
users should see the compatibility notes at bottom of this readme.
|
users should see the compatibility notes at bottom of this readme.
|
||||||
|
|
||||||
Also, a big thanks to the author(s) of `A Primer on Bézier Curves <http://pomax.github.io/bezierinfo/>`_, an outstanding resource for learning about Bézier curves and Bézier curve-related algorithms.
|
|
||||||
|
|
||||||
Basic Usage
|
Basic Usage
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
@ -117,11 +111,11 @@ information on what each parameter means.
|
||||||
on discontinuous Path objects. A simple workaround is provided, however,
|
on discontinuous Path objects. A simple workaround is provided, however,
|
||||||
by the ``Path.continuous_subpaths()`` method. `↩ <#a1>`__
|
by the ``Path.continuous_subpaths()`` method. `↩ <#a1>`__
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
from __future__ import division, print_function
|
from __future__ import division, print_function
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
# Coordinates are given as points in the complex plane
|
# Coordinates are given as points in the complex plane
|
||||||
from svgpathtools import Path, Line, QuadraticBezier, CubicBezier, Arc
|
from svgpathtools import Path, Line, QuadraticBezier, CubicBezier, Arc
|
||||||
|
@ -158,7 +152,7 @@ The ``Path`` class is a mutable sequence, so it behaves much like a
|
||||||
list. So segments can **append**\ ed, **insert**\ ed, set by index,
|
list. So segments can **append**\ ed, **insert**\ ed, set by index,
|
||||||
**del**\ eted, **enumerate**\ d, **slice**\ d out, etc.
|
**del**\ eted, **enumerate**\ d, **slice**\ d out, etc.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
# Let's append another to the end of it
|
# Let's append another to the end of it
|
||||||
path.append(CubicBezier(250+350j, 275+350j, 250+225j, 200+100j))
|
path.append(CubicBezier(250+350j, 275+350j, 250+225j, 200+100j))
|
||||||
|
@ -225,7 +219,7 @@ Reading SVGSs
|
||||||
| Note: Line, Polyline, Polygon, and Path SVG elements can all be
|
| Note: Line, Polyline, Polygon, and Path SVG elements can all be
|
||||||
converted to Path objects using this function.
|
converted to Path objects using this function.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
# Read SVG into a list of path objects and list of dictionaries of attributes
|
# Read SVG into a list of path objects and list of dictionaries of attributes
|
||||||
from svgpathtools import svg2paths, wsvg
|
from svgpathtools import svg2paths, wsvg
|
||||||
|
@ -262,7 +256,7 @@ convenience function **disvg()** (or set 'openinbrowser=True') to
|
||||||
automatically attempt to open the created svg file in your default SVG
|
automatically attempt to open the created svg file in your default SVG
|
||||||
viewer.
|
viewer.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
# Let's make a new SVG that's identical to the first
|
# Let's make a new SVG that's identical to the first
|
||||||
wsvg(paths, attributes=attributes, svg_attributes=svg_attributes, filename='output1.svg')
|
wsvg(paths, attributes=attributes, svg_attributes=svg_attributes, filename='output1.svg')
|
||||||
|
@ -294,7 +288,7 @@ over the domain 0 <= t <= 1.
|
||||||
that ``path.point(T)=path[k].point(t)``.
|
that ``path.point(T)=path[k].point(t)``.
|
||||||
| There is also a ``Path.t2T()`` method to solve the inverse problem.
|
| There is also a ``Path.t2T()`` method to solve the inverse problem.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
# Example:
|
# Example:
|
||||||
|
|
||||||
|
@ -324,11 +318,11 @@ over the domain 0 <= t <= 1.
|
||||||
True
|
True
|
||||||
|
|
||||||
|
|
||||||
Tangent vectors and Bezier curves as numpy polynomial objects
|
Bezier curves as NumPy polynomial objects
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
| Another great way to work with the parameterizations for Line,
|
| Another great way to work with the parameterizations for ``Line``,
|
||||||
QuadraticBezier, and CubicBezier objects is to convert them to
|
``QuadraticBezier``, and ``CubicBezier`` objects is to convert them to
|
||||||
``numpy.poly1d`` objects. This is done easily using the
|
``numpy.poly1d`` objects. This is done easily using the
|
||||||
``Line.poly()``, ``QuadraticBezier.poly()`` and ``CubicBezier.poly()``
|
``Line.poly()``, ``QuadraticBezier.poly()`` and ``CubicBezier.poly()``
|
||||||
methods.
|
methods.
|
||||||
|
@ -360,9 +354,10 @@ form
|
||||||
\end{bmatrix}
|
\end{bmatrix}
|
||||||
\begin{bmatrix}P_0\\P_1\\P_2\\P_3\end{bmatrix}
|
\begin{bmatrix}P_0\\P_1\\P_2\\P_3\end{bmatrix}
|
||||||
|
|
||||||
QuadraticBezier.poly() and Line.poly() are defined similarly.
|
``QuadraticBezier.poly()`` and ``Line.poly()`` are `defined
|
||||||
|
similarly <https://en.wikipedia.org/wiki/B%C3%A9zier_curve#General_definition>`__.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
# Example:
|
# Example:
|
||||||
b = CubicBezier(300+100j, 100+100j, 200+200j, 200+300j)
|
b = CubicBezier(300+100j, 100+100j, 200+200j, 200+300j)
|
||||||
|
@ -392,15 +387,21 @@ QuadraticBezier.poly() and Line.poly() are defined similarly.
|
||||||
(-400 + -100j) t + (900 + 300j) t - 600 t + (300 + 100j)
|
(-400 + -100j) t + (900 + 300j) t - 600 t + (300 + 100j)
|
||||||
|
|
||||||
|
|
||||||
To illustrate the awesomeness of being able to convert our Bezier curve
|
The ability to convert between Bezier objects to NumPy polynomial
|
||||||
objects to numpy.poly1d objects and back, lets compute the unit tangent
|
objects is very useful. For starters, we can take turn a list of Bézier
|
||||||
vector of the above CubicBezier object, b, at t=0.5 in four different
|
segments into a NumPy array ### Numpy Array operations on Bézier path
|
||||||
ways.
|
segments `Example available
|
||||||
|
here <https://github.com/mathandy/svgpathtools/blob/master/examples/compute-many-points-quickly-using-numpy-arrays.py>`__
|
||||||
|
|
||||||
Tangent vectors (and more on polynomials)
|
To further illustrate the power of being able to convert our Bezier
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
curve objects to numpy.poly1d objects and back, lets compute the unit
|
||||||
|
tangent vector of the above CubicBezier object, b, at t=0.5 in four
|
||||||
|
different ways.
|
||||||
|
|
||||||
.. code:: python
|
Tangent vectors (and more on NumPy polynomials)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. code:: ipython2
|
||||||
|
|
||||||
t = 0.5
|
t = 0.5
|
||||||
### Method 1: the easy way
|
### Method 1: the easy way
|
||||||
|
@ -442,7 +443,7 @@ Tangent vectors (and more on polynomials)
|
||||||
Translations (shifts), reversing orientation, and normal vectors
|
Translations (shifts), reversing orientation, and normal vectors
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
# Speaking of tangents, let's add a normal vector to the picture
|
# Speaking of tangents, let's add a normal vector to the picture
|
||||||
n = b.normal(t)
|
n = b.normal(t)
|
||||||
|
@ -472,7 +473,7 @@ Translations (shifts), reversing orientation, and normal vectors
|
||||||
Rotations and Translations
|
Rotations and Translations
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
# Let's take a Line and an Arc and make some pictures
|
# Let's take a Line and an Arc and make some pictures
|
||||||
top_half = Arc(start=-1, radius=1+2j, rotation=0, large_arc=1, sweep=1, end=1)
|
top_half = Arc(start=-1, radius=1+2j, rotation=0, large_arc=1, sweep=1, end=1)
|
||||||
|
@ -505,7 +506,7 @@ midpoints of the paths from ``test.svg``. We'll need to compute use the
|
||||||
``CubicBezier.length()``, and ``Arc.length()`` methods, as well as the
|
``CubicBezier.length()``, and ``Arc.length()`` methods, as well as the
|
||||||
related inverse arc length methods ``.ilength()`` function to do this.
|
related inverse arc length methods ``.ilength()`` function to do this.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
# First we'll load the path data from the file test.svg
|
# First we'll load the path data from the file test.svg
|
||||||
paths, attributes = svg2paths('test.svg')
|
paths, attributes = svg2paths('test.svg')
|
||||||
|
@ -547,7 +548,7 @@ related inverse arc length methods ``.ilength()`` function to do this.
|
||||||
Intersections between Bezier curves
|
Intersections between Bezier curves
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
# Let's find all intersections between redpath and the other
|
# Let's find all intersections between redpath and the other
|
||||||
redpath = paths[0]
|
redpath = paths[0]
|
||||||
|
@ -571,7 +572,7 @@ An Advanced Application: Offsetting Paths
|
||||||
Here we'll find the `offset
|
Here we'll find the `offset
|
||||||
curve <https://en.wikipedia.org/wiki/Parallel_curve>`__ for a few paths.
|
curve <https://en.wikipedia.org/wiki/Parallel_curve>`__ for a few paths.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: ipython2
|
||||||
|
|
||||||
from svgpathtools import parse_path, Line, Path, wsvg
|
from svgpathtools import parse_path, Line, Path, wsvg
|
||||||
def offset_curve(path, offset_distance, steps=1000):
|
def offset_curve(path, offset_distance, steps=1000):
|
||||||
|
@ -628,3 +629,4 @@ Licence
|
||||||
-------
|
-------
|
||||||
|
|
||||||
This module is under a MIT License.
|
This module is under a MIT License.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue