commit branch
parent
d354b8ffe4
commit
bdbd976e0a
183
README.ipynb
183
README.ipynb
|
@ -2,10 +2,7 @@
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"# svgpathtools\n",
|
"# svgpathtools\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -91,9 +88,7 @@
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 1,
|
"execution_count": 1,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": true,
|
"collapsed": true
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -103,11 +98,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 2,
|
"execution_count": 2,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
|
@ -146,10 +137,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"The ``Path`` class is a mutable sequence, so it behaves much like a list.\n",
|
"The ``Path`` class is a mutable sequence, so it behaves much like a list.\n",
|
||||||
"So segments can **append**ed, **insert**ed, set by index, **del**eted, **enumerate**d, **slice**d out, etc."
|
"So segments can **append**ed, **insert**ed, set by index, **del**eted, **enumerate**d, **slice**d out, etc."
|
||||||
|
@ -158,11 +146,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 3,
|
"execution_count": 3,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
|
@ -226,10 +210,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"### Reading SVGSs\n",
|
"### Reading SVGSs\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -240,11 +221,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 4,
|
"execution_count": 4,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
|
@ -277,10 +254,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"### Writing SVGSs (and some geometric functions and methods)\n",
|
"### Writing SVGSs (and some geometric functions and methods)\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -291,11 +265,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 5,
|
"execution_count": 5,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Let's make a new SVG that's identical to the first\n",
|
"# Let's make a new SVG that's identical to the first\n",
|
||||||
|
@ -304,20 +274,14 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"![output1.svg](output1.svg)"
|
"![output1.svg](output1.svg)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"There will be many more examples of writing and displaying path data below.\n",
|
"There will be many more examples of writing and displaying path data below.\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -334,11 +298,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 6,
|
"execution_count": 6,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
|
@ -374,10 +334,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"### 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",
|
||||||
|
@ -402,11 +359,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": 7,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
|
@ -442,10 +395,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"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",
|
"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",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -461,11 +411,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 8,
|
"execution_count": 8,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
|
@ -510,10 +456,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"### Translations (shifts), reversing orientation, and normal vectors"
|
"### Translations (shifts), reversing orientation, and normal vectors"
|
||||||
]
|
]
|
||||||
|
@ -521,11 +464,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 9,
|
"execution_count": 9,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Speaking of tangents, let's add a normal vector to the picture\n",
|
"# Speaking of tangents, let's add a normal vector to the picture\n",
|
||||||
|
@ -551,20 +490,14 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"![vectorframes.svg](vectorframes.svg)"
|
"![vectorframes.svg](vectorframes.svg)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"### Rotations and Translations"
|
"### Rotations and Translations"
|
||||||
]
|
]
|
||||||
|
@ -572,11 +505,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 10,
|
"execution_count": 10,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Let's take a Line and an Arc and make some pictures\n",
|
"# Let's take a Line and an Arc and make some pictures\n",
|
||||||
|
@ -599,20 +528,14 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"![decorated_ellipse.svg](decorated_ellipse.svg)"
|
"![decorated_ellipse.svg](decorated_ellipse.svg)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"### arc length and inverse arc length\n",
|
"### arc length and inverse arc length\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -622,11 +545,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 11,
|
"execution_count": 11,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# First we'll load the path data from the file test.svg\n",
|
"# First we'll load the path data from the file test.svg\n",
|
||||||
|
@ -664,20 +583,14 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"![output2.svg](output2.svg)"
|
"![output2.svg](output2.svg)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"### Intersections between Bezier curves"
|
"### Intersections between Bezier curves"
|
||||||
]
|
]
|
||||||
|
@ -685,11 +598,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 12,
|
"execution_count": 12,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Let's find all intersections between redpath and the other \n",
|
"# Let's find all intersections between redpath and the other \n",
|
||||||
|
@ -706,20 +615,14 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"![output_intersections.svg](output_intersections.svg)"
|
"![output_intersections.svg](output_intersections.svg)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"### An Advanced Application: Offsetting Paths\n",
|
"### An Advanced Application: Offsetting Paths\n",
|
||||||
"Here we'll find the [offset curve](https://en.wikipedia.org/wiki/Parallel_curve) for a few paths."
|
"Here we'll find the [offset curve](https://en.wikipedia.org/wiki/Parallel_curve) for a few paths."
|
||||||
|
@ -728,11 +631,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 13,
|
"execution_count": 13,
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"collapsed": false,
|
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from svgpathtools import parse_path, Line, Path, wsvg\n",
|
"from svgpathtools import parse_path, Line, Path, wsvg\n",
|
||||||
|
@ -772,20 +671,14 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"![offset_curves.svg](offset_curves.svg)"
|
"![offset_curves.svg](offset_curves.svg)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {},
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
|
||||||
"source": [
|
"source": [
|
||||||
"## Compatibility Notes for users of svg.path (v2.0)\n",
|
"## Compatibility Notes for users of svg.path (v2.0)\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -806,9 +699,7 @@
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": true,
|
"collapsed": true
|
||||||
"deletable": true,
|
|
||||||
"editable": true
|
|
||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": []
|
"source": []
|
||||||
|
@ -823,16 +714,16 @@
|
||||||
"language_info": {
|
"language_info": {
|
||||||
"codemirror_mode": {
|
"codemirror_mode": {
|
||||||
"name": "ipython",
|
"name": "ipython",
|
||||||
"version": 2
|
"version": 3
|
||||||
},
|
},
|
||||||
"file_extension": ".py",
|
"file_extension": ".py",
|
||||||
"mimetype": "text/x-python",
|
"mimetype": "text/x-python",
|
||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython2",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "2.7.12"
|
"version": "3.7.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
"nbformat_minor": 0
|
"nbformat_minor": 1
|
||||||
}
|
}
|
||||||
|
|
95
README.rst
95
README.rst
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
svgpathtools
|
svgpathtools
|
||||||
============
|
============
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ Some included tools:
|
||||||
- find a **bounding box** for a path or segment
|
- find a **bounding box** for a path or segment
|
||||||
- **reverse** segment/path orientation
|
- **reverse** segment/path orientation
|
||||||
- **crop** and **split** paths and segments
|
- **crop** and **split** paths and segments
|
||||||
- **smooth** paths (i.e. smooth away kinks to make paths
|
- **smooth** paths (i.e. smooth away kinks to make paths
|
||||||
differentiable)
|
differentiable)
|
||||||
- **transition maps** from path domain to segment domain and back (T2t
|
- **transition maps** from path domain to segment domain and back (T2t
|
||||||
and t2T)
|
and t2T)
|
||||||
|
@ -47,9 +46,22 @@ Prerequisites
|
||||||
Setup
|
Setup
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
If not already installed, you can **install the prerequisites** using
|
||||||
|
pip.
|
||||||
|
|
||||||
.. code:: bash
|
.. code:: bash
|
||||||
|
|
||||||
$ pip install svgpathtools
|
$ pip install numpy
|
||||||
|
|
||||||
|
.. code:: bash
|
||||||
|
|
||||||
|
$ pip install svgwrite
|
||||||
|
|
||||||
|
Then **install svgpathtools**:
|
||||||
|
|
||||||
|
.. code:: bash
|
||||||
|
|
||||||
|
$ pip install svgpathtools
|
||||||
|
|
||||||
Alternative Setup
|
Alternative Setup
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
@ -59,9 +71,9 @@ You can download the source from Github and install by using the command
|
||||||
|
|
||||||
.. code:: bash
|
.. code:: bash
|
||||||
|
|
||||||
$ python setup.py install
|
$ python setup.py install
|
||||||
|
|
||||||
Credit where credit's due
|
Credit where credit’s due
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Much of the core of this module was taken from `the svg.path (v2.0)
|
Much of the core of this module was taken from `the svg.path (v2.0)
|
||||||
|
@ -98,11 +110,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:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
from __future__ import division, print_function
|
from __future__ import division, print_function
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -139,7 +151,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:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
# 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))
|
||||||
|
@ -206,7 +218,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:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -239,16 +251,16 @@ Writing SVGSs (and some geometric functions and methods)
|
||||||
The **wsvg()** function creates an SVG file from a list of path. This
|
The **wsvg()** function creates an SVG file from a list of path. This
|
||||||
function can do many things (see docstring in *paths2svg.py* for more
|
function can do many things (see docstring in *paths2svg.py* for more
|
||||||
information) and is meant to be quick and easy to use. Note: Use the
|
information) and is meant to be quick and easy to use. Note: Use the
|
||||||
convenience function **disvg()** (or set 'openinbrowser=True') to
|
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:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
# 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')
|
||||||
|
|
||||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/output1.svg
|
.. figure:: output1.svg
|
||||||
:alt: output1.svg
|
:alt: output1.svg
|
||||||
|
|
||||||
output1.svg
|
output1.svg
|
||||||
|
@ -268,14 +280,14 @@ over the domain 0 <= t <= 1.
|
||||||
| **Note:** In this document and in inline documentation and doctrings,
|
| **Note:** In this document and in inline documentation and doctrings,
|
||||||
I use a capital ``T`` when referring to the parameterization of a Path
|
I use a capital ``T`` when referring to the parameterization of a Path
|
||||||
object and a lower case ``t`` when referring speaking about path
|
object and a lower case ``t`` when referring speaking about path
|
||||||
segment objects (i.e. Line, QaudraticBezier, CubicBezier, and Arc
|
segment objects (i.e. Line, QaudraticBezier, CubicBezier, and Arc
|
||||||
objects).
|
objects).
|
||||||
| Given a ``T`` value, the ``Path.T2t()`` method can be used to find the
|
| Given a ``T`` value, the ``Path.T2t()`` method can be used to find the
|
||||||
corresponding segment index, ``k``, and segment parameter, ``t``, such
|
corresponding segment index, ``k``, and segment parameter, ``t``, such
|
||||||
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:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
# Example:
|
# Example:
|
||||||
|
|
||||||
|
@ -313,7 +325,7 @@ Bezier curves as NumPy polynomial objects
|
||||||
``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.
|
||||||
| There's also a ``polynomial2bezier()`` function in the pathtools.py
|
| There’s also a ``polynomial2bezier()`` function in the pathtools.py
|
||||||
submodule to convert polynomials back to Bezier curves.
|
submodule to convert polynomials back to Bezier curves.
|
||||||
|
|
||||||
**Note:** cubic Bezier curves are parameterized as
|
**Note:** cubic Bezier curves are parameterized as
|
||||||
|
@ -328,7 +340,7 @@ form
|
||||||
|
|
||||||
.. math:: \mathcal{B}(t) = c_0t^3 + c_1t^2 +c_2t+c3
|
.. math:: \mathcal{B}(t) = c_0t^3 + c_1t^2 +c_2t+c3
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
.. math::
|
.. math::
|
||||||
|
|
||||||
|
@ -344,7 +356,7 @@ form
|
||||||
``QuadraticBezier.poly()`` and ``Line.poly()`` are `defined
|
``QuadraticBezier.poly()`` and ``Line.poly()`` are `defined
|
||||||
similarly <https://en.wikipedia.org/wiki/B%C3%A9zier_curve#General_definition>`__.
|
similarly <https://en.wikipedia.org/wiki/B%C3%A9zier_curve#General_definition>`__.
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
# Example:
|
# Example:
|
||||||
b = CubicBezier(300+100j, 100+100j, 200+200j, 200+300j)
|
b = CubicBezier(300+100j, 100+100j, 200+200j, 200+300j)
|
||||||
|
@ -392,7 +404,7 @@ different ways.
|
||||||
Tangent vectors (and more on NumPy polynomials)
|
Tangent vectors (and more on NumPy polynomials)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
t = 0.5
|
t = 0.5
|
||||||
### Method 1: the easy way
|
### Method 1: the easy way
|
||||||
|
@ -434,7 +446,7 @@ Tangent vectors (and more on NumPy polynomials)
|
||||||
Translations (shifts), reversing orientation, and normal vectors
|
Translations (shifts), reversing orientation, and normal vectors
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
# 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)
|
||||||
|
@ -456,7 +468,7 @@ Translations (shifts), reversing orientation, and normal vectors
|
||||||
'bgpkgp', nodes=[b.point(t), br.point(t)], filename='vectorframes.svg',
|
'bgpkgp', nodes=[b.point(t), br.point(t)], filename='vectorframes.svg',
|
||||||
text=["b's tangent", "br's tangent"], text_path=[tangent_line, tangent_line_r])
|
text=["b's tangent", "br's tangent"], text_path=[tangent_line, tangent_line_r])
|
||||||
|
|
||||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/vectorframes.svg
|
.. figure:: vectorframes.svg
|
||||||
:alt: vectorframes.svg
|
:alt: vectorframes.svg
|
||||||
|
|
||||||
vectorframes.svg
|
vectorframes.svg
|
||||||
|
@ -464,7 +476,7 @@ Translations (shifts), reversing orientation, and normal vectors
|
||||||
Rotations and Translations
|
Rotations and Translations
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
# 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)
|
||||||
|
@ -483,21 +495,21 @@ Rotations and Translations
|
||||||
decorated_ellipse = decorated_ellipse.translated(4+0j)
|
decorated_ellipse = decorated_ellipse.translated(4+0j)
|
||||||
wsvg([top_half, midline, decorated_ellipse], filename='decorated_ellipse.svg')
|
wsvg([top_half, midline, decorated_ellipse], filename='decorated_ellipse.svg')
|
||||||
|
|
||||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/decorated_ellipse.svg
|
.. figure:: decorated_ellipse.svg
|
||||||
:alt: decorated\_ellipse.svg
|
:alt: decorated_ellipse.svg
|
||||||
|
|
||||||
decorated\_ellipse.svg
|
decorated_ellipse.svg
|
||||||
|
|
||||||
arc length and inverse arc length
|
arc length and inverse arc length
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Here we'll create an SVG that shows off the parametric and geometric
|
Here we’ll create an SVG that shows off the parametric and geometric
|
||||||
midpoints of the paths from ``test.svg``. We'll need to compute use the
|
midpoints of the paths from ``test.svg``. We’ll need to compute use the
|
||||||
``Path.length()``, ``Line.length()``, ``QuadraticBezier.length()``,
|
``Path.length()``, ``Line.length()``, ``QuadraticBezier.length()``,
|
||||||
``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:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
# 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')
|
||||||
|
@ -531,7 +543,7 @@ related inverse arc length methods ``.ilength()`` function to do this.
|
||||||
wsvg(paths, nodes=dots, node_colors=ncols, node_radii=nradii,
|
wsvg(paths, nodes=dots, node_colors=ncols, node_radii=nradii,
|
||||||
attributes=attributes, filename='output2.svg')
|
attributes=attributes, filename='output2.svg')
|
||||||
|
|
||||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/output2.svg
|
.. figure:: output2.svg
|
||||||
:alt: output2.svg
|
:alt: output2.svg
|
||||||
|
|
||||||
output2.svg
|
output2.svg
|
||||||
|
@ -539,7 +551,7 @@ related inverse arc length methods ``.ilength()`` function to do this.
|
||||||
Intersections between Bezier curves
|
Intersections between Bezier curves
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
# 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]
|
||||||
|
@ -552,18 +564,18 @@ Intersections between Bezier curves
|
||||||
disvg(paths, filename='output_intersections.svg', attributes=attributes,
|
disvg(paths, filename='output_intersections.svg', attributes=attributes,
|
||||||
nodes = intersections, node_radii = [5]*len(intersections))
|
nodes = intersections, node_radii = [5]*len(intersections))
|
||||||
|
|
||||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/output_intersections.svg
|
.. figure:: output_intersections.svg
|
||||||
:alt: output\_intersections.svg
|
:alt: output_intersections.svg
|
||||||
|
|
||||||
output\_intersections.svg
|
output_intersections.svg
|
||||||
|
|
||||||
An Advanced Application: Offsetting Paths
|
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:: ipython2
|
.. code:: ipython3
|
||||||
|
|
||||||
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):
|
||||||
|
@ -572,8 +584,9 @@ curve <https://en.wikipedia.org/wiki/Parallel_curve>`__ for a few paths.
|
||||||
of the 'parallel' offset curve."""
|
of the 'parallel' offset curve."""
|
||||||
nls = []
|
nls = []
|
||||||
for seg in path:
|
for seg in path:
|
||||||
|
ct = 1
|
||||||
for k in range(steps):
|
for k in range(steps):
|
||||||
t = k / float(steps)
|
t = k / steps
|
||||||
offset_vector = offset_distance * seg.normal(t)
|
offset_vector = offset_distance * seg.normal(t)
|
||||||
nl = Line(seg.point(t), seg.point(t) + offset_vector)
|
nl = Line(seg.point(t), seg.point(t) + offset_vector)
|
||||||
nls.append(nl)
|
nls.append(nl)
|
||||||
|
@ -595,21 +608,21 @@ curve <https://en.wikipedia.org/wiki/Parallel_curve>`__ for a few paths.
|
||||||
for distances in offset_distances:
|
for distances in offset_distances:
|
||||||
offset_paths.append(offset_curve(path, distances))
|
offset_paths.append(offset_curve(path, distances))
|
||||||
|
|
||||||
# Note: This will take a few moments
|
# Let's take a look
|
||||||
wsvg(paths + offset_paths, 'g'*len(paths) + 'r'*len(offset_paths), filename='offset_curves.svg')
|
wsvg(paths + offset_paths, 'g'*len(paths) + 'r'*len(offset_paths), filename='offset_curves.svg')
|
||||||
|
|
||||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/offset_curves.svg
|
.. figure:: offset_curves.svg
|
||||||
:alt: offset\_curves.svg
|
:alt: offset_curves.svg
|
||||||
|
|
||||||
offset\_curves.svg
|
offset_curves.svg
|
||||||
|
|
||||||
Compatibility Notes for users of svg.path (v2.0)
|
Compatibility Notes for users of svg.path (v2.0)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
- renamed Arc.arc attribute as Arc.large\_arc
|
- renamed Arc.arc attribute as Arc.large_arc
|
||||||
|
|
||||||
- Path.d() : For behavior similar\ `2 <#f2>`__\ to svg.path (v2.0),
|
- Path.d() : For behavior similar\ `2 <#f2>`__\ to svg.path (v2.0),
|
||||||
set both useSandT and use\_closed\_attrib to be True.
|
set both useSandT and use_closed_attrib to be True.
|
||||||
|
|
||||||
2 The behavior would be identical, but the string formatting used in
|
2 The behavior would be identical, but the string formatting used in
|
||||||
this method has been changed to use default format (instead of the
|
this method has been changed to use default format (instead of the
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue