parent
bf85efe4b5
commit
0c682bf4d8
93
README.ipynb
93
README.ipynb
|
@ -86,7 +86,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"execution_count": 16,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
|
@ -97,7 +97,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"execution_count": 17,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -147,7 +147,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"execution_count": 18,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -224,7 +224,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"execution_count": 19,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -265,7 +265,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"execution_count": 20,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -300,7 +300,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"execution_count": 21,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -363,7 +363,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"execution_count": 22,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -411,7 +411,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 28,
|
||||
"execution_count": 23,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -466,7 +466,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 29,
|
||||
"execution_count": 24,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -509,7 +509,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"execution_count": 25,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -551,7 +551,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 31,
|
||||
"execution_count": 26,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -606,7 +606,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 32,
|
||||
"execution_count": 27,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
|
@ -635,65 +635,58 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### An Advanced Application: Offsetting Bezier Curves\n",
|
||||
"Here we'll find the [offset curve](https://en.wikipedia.org/wiki/Parallel_curve) for a few Bezier cubics."
|
||||
"### An Advanced Application: Offsetting Paths\n",
|
||||
"Here we'll find the [offset curve](https://en.wikipedia.org/wiki/Parallel_curve) for a few paths."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 33,
|
||||
"execution_count": 28,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def display_offset_curve(bezpath, offset_distance, steps=1000,\n",
|
||||
" stripe_width=3, stripe_colors='ygb',\n",
|
||||
" name='offsetcurves.svg', show_normal_line=True):\n",
|
||||
" \"\"\"Takes in a path of bezier curves, `bezpath`, and a distance,\n",
|
||||
" `offset_distance`, and displays the 'parallel' offset curve by placing a\n",
|
||||
" dot at a distance of `offset_distance` away at each step.\"\"\"\n",
|
||||
"from svgpathtools import parse_path, Line, Path, wsvg\n",
|
||||
"def offset_curve(path, offset_distance, steps=1000):\n",
|
||||
" \"\"\"Takes in a Path object, `path`, and a distance,\n",
|
||||
" `offset_distance`, and outputs an piecewise-linear approximation \n",
|
||||
" of the 'parallel' offset curve.\"\"\"\n",
|
||||
" nls = []\n",
|
||||
" nodes = []\n",
|
||||
" line_colors = ''\n",
|
||||
" node_colors = ''\n",
|
||||
"\n",
|
||||
" for bez in bezpath:\n",
|
||||
" for seg in path:\n",
|
||||
" ct = 1\n",
|
||||
" for k in range(steps):\n",
|
||||
" t = k / steps\n",
|
||||
" nl = Line(bez.point(t),\n",
|
||||
" bez.point(t) + offset_distance * bez.normal(t))\n",
|
||||
" offset_vector = offset_distance * seg.normal(t)\n",
|
||||
" nl = Line(seg.point(t), seg.point(t) + offset_vector)\n",
|
||||
" nls.append(nl)\n",
|
||||
" line_colors += stripe_colors[ct % 3]\n",
|
||||
" if not (k % stripe_width):\n",
|
||||
" ct += 1\n",
|
||||
" nodes.append(bez.point(t))\n",
|
||||
" nodes.append(nl.end)\n",
|
||||
" node_colors += 'kr'\n",
|
||||
" # nls.reverse()\n",
|
||||
" if show_normal_line:\n",
|
||||
" wsvg([bezpath] + nls, 'k' + line_colors,\n",
|
||||
" nodes=nodes, node_colors=node_colors,\n",
|
||||
" filename=name)\n",
|
||||
" else:\n",
|
||||
" wsvg(bezpath, 'k',\n",
|
||||
" nodes=nodes, node_colors=node_colors,\n",
|
||||
" filename=name)\n",
|
||||
" connect_the_dots = [Line(nls[k].end, nls[k+1].end) for k in range(len(nls)-1)]\n",
|
||||
" if path.isclosed():\n",
|
||||
" connect_the_dots.append(Line(nls[-1].end, nls[0].end))\n",
|
||||
" offset_path = Path(*connect_the_dots)\n",
|
||||
" return offset_path\n",
|
||||
"\n",
|
||||
"bez1 = parse_path(\"m 288,600 c -52,-28 -42,-61 0,-97 \")[0]\n",
|
||||
"bez2 = parse_path(\"M 151,395 C 407,485 726.17662,160 634,339\")[0]\n",
|
||||
"bez3 = parse_path(\"m 117,695 c 237,-7 -103,-146 457,0\")[0]\n",
|
||||
"path = Path(bez1, bez2.translated(300), bez3.translated(500+400j))\n",
|
||||
"# Examples:\n",
|
||||
"path1 = parse_path(\"m 288,600 c -52,-28 -42,-61 0,-97 \")\n",
|
||||
"path2 = parse_path(\"M 151,395 C 407,485 726.17662,160 634,339\").translated(300)\n",
|
||||
"path3 = parse_path(\"m 117,695 c 237,-7 -103,-146 457,0\").translated(500+400j)\n",
|
||||
"paths = [path1, path2, path3]\n",
|
||||
"\n",
|
||||
"display_offset_curve(path, 500)"
|
||||
"offset_distances = [10*k for k in range(1,51)]\n",
|
||||
"offset_paths = []\n",
|
||||
"for path in paths:\n",
|
||||
" for distances in offset_distances:\n",
|
||||
" offset_paths.append(offset_curve(path, distances))\n",
|
||||
"\n",
|
||||
"# Note: This will take a few moments\n",
|
||||
"wsvg(paths + offset_paths, 'g'*len(paths) + 'r'*len(offset_paths), filename='offset_curves.svg')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"![offsetcurves.svg](offsetcurves.svg)"
|
||||
"![offset_curves.svg](offset_curves.svg)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
74
README.rst
74
README.rst
|
@ -453,7 +453,7 @@ Translations (shifts), reversing orientation, and normal vectors
|
|||
'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])
|
||||
|
||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/test.svg
|
||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/vectorframes.svg
|
||||
:alt: vectorframes.svg
|
||||
|
||||
vectorframes.svg
|
||||
|
@ -554,60 +554,52 @@ Intersections between Bezier curves
|
|||
|
||||
output\_intersections.svg
|
||||
|
||||
An Advanced Application: Offsetting Bezier Curves
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
An Advanced Application: Offsetting Paths
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here we'll find the `offset
|
||||
curve <https://en.wikipedia.org/wiki/Parallel_curve>`__ for a few Bezier
|
||||
cubics.
|
||||
curve <https://en.wikipedia.org/wiki/Parallel_curve>`__ for a few paths.
|
||||
|
||||
.. code:: python
|
||||
|
||||
def display_offset_curve(bezpath, offset_distance, steps=1000,
|
||||
stripe_width=3, stripe_colors='ygb',
|
||||
name='offsetcurves.svg', show_normal_line=True):
|
||||
"""Takes in a path of bezier curves, `bezpath`, and a distance,
|
||||
`offset_distance`, and displays the 'parallel' offset curve by placing a
|
||||
dot at a distance of `offset_distance` away at each step."""
|
||||
from svgpathtools import parse_path, Line, Path, wsvg
|
||||
def offset_curve(path, offset_distance, steps=1000):
|
||||
"""Takes in a Path object, `path`, and a distance,
|
||||
`offset_distance`, and outputs an piecewise-linear approximation
|
||||
of the 'parallel' offset curve."""
|
||||
nls = []
|
||||
nodes = []
|
||||
line_colors = ''
|
||||
node_colors = ''
|
||||
|
||||
for bez in bezpath:
|
||||
for seg in path:
|
||||
ct = 1
|
||||
for k in range(steps):
|
||||
t = k / steps
|
||||
nl = Line(bez.point(t),
|
||||
bez.point(t) + offset_distance * bez.normal(t))
|
||||
offset_vector = offset_distance * seg.normal(t)
|
||||
nl = Line(seg.point(t), seg.point(t) + offset_vector)
|
||||
nls.append(nl)
|
||||
line_colors += stripe_colors[ct % 3]
|
||||
if not (k % stripe_width):
|
||||
ct += 1
|
||||
nodes.append(bez.point(t))
|
||||
nodes.append(nl.end)
|
||||
node_colors += 'kr'
|
||||
# nls.reverse()
|
||||
if show_normal_line:
|
||||
wsvg([bezpath] + nls, 'k' + line_colors,
|
||||
nodes=nodes, node_colors=node_colors,
|
||||
filename=name)
|
||||
else:
|
||||
wsvg(bezpath, 'k',
|
||||
nodes=nodes, node_colors=node_colors,
|
||||
filename=name)
|
||||
connect_the_dots = [Line(nls[k].end, nls[k+1].end) for k in range(len(nls)-1)]
|
||||
if path.isclosed():
|
||||
connect_the_dots.append(Line(nls[-1].end, nls[0].end))
|
||||
offset_path = Path(*connect_the_dots)
|
||||
return offset_path
|
||||
|
||||
bez1 = parse_path("m 288,600 c -52,-28 -42,-61 0,-97 ")[0]
|
||||
bez2 = parse_path("M 151,395 C 407,485 726.17662,160 634,339")[0]
|
||||
bez3 = parse_path("m 117,695 c 237,-7 -103,-146 457,0")[0]
|
||||
path = Path(bez1, bez2.translated(300), bez3.translated(500+400j))
|
||||
# Examples:
|
||||
path1 = parse_path("m 288,600 c -52,-28 -42,-61 0,-97 ")
|
||||
path2 = parse_path("M 151,395 C 407,485 726.17662,160 634,339").translated(300)
|
||||
path3 = parse_path("m 117,695 c 237,-7 -103,-146 457,0").translated(500+400j)
|
||||
paths = [path1, path2, path3]
|
||||
|
||||
display_offset_curve(path, 500)
|
||||
offset_distances = [10*k for k in range(1,51)]
|
||||
offset_paths = []
|
||||
for path in paths:
|
||||
for distances in offset_distances:
|
||||
offset_paths.append(offset_curve(path, distances))
|
||||
|
||||
# Note: This will take a few moments
|
||||
wsvg(paths + offset_paths, 'g'*len(paths) + 'r'*len(offset_paths), filename='offset_curves.svg')
|
||||
|
||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/offsetcurves.svg
|
||||
:alt: offsetcurves.svg
|
||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/offset_curves.svg
|
||||
:alt: offset\_curves.svg
|
||||
|
||||
offsetcurves.svg
|
||||
offset\_curves.svg
|
||||
|
||||
Compatibility Notes for users of svg.path (v2.0)
|
||||
------------------------------------------------
|
||||
|
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 4.3 MiB |
9005
offsetcurves.svg
9005
offsetcurves.svg
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 835 KiB |
Loading…
Reference in New Issue