improved README curve offsetting example

pull/4/head 1.1
Andy 2016-07-10 17:24:36 -07:00
parent bf85efe4b5
commit 0c682bf4d8
4 changed files with 233 additions and 9096 deletions

View File

@ -86,7 +86,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 21, "execution_count": 16,
"metadata": { "metadata": {
"collapsed": true "collapsed": true
}, },
@ -97,7 +97,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 22, "execution_count": 17,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -147,7 +147,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 23, "execution_count": 18,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -224,7 +224,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 24, "execution_count": 19,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -265,7 +265,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 25, "execution_count": 20,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -300,7 +300,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 26, "execution_count": 21,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -363,7 +363,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 27, "execution_count": 22,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -411,7 +411,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 28, "execution_count": 23,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -466,7 +466,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 29, "execution_count": 24,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -509,7 +509,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 30, "execution_count": 25,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -551,7 +551,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 31, "execution_count": 26,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -606,7 +606,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 32, "execution_count": 27,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
@ -635,65 +635,58 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### An Advanced Application: Offsetting Bezier Curves\n", "### An Advanced Application: Offsetting Paths\n",
"Here we'll find the [offset curve](https://en.wikipedia.org/wiki/Parallel_curve) for a few Bezier cubics." "Here we'll find the [offset curve](https://en.wikipedia.org/wiki/Parallel_curve) for a few paths."
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 33, "execution_count": 28,
"metadata": { "metadata": {
"collapsed": true "collapsed": false
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"def display_offset_curve(bezpath, offset_distance, steps=1000,\n", "from svgpathtools import parse_path, Line, Path, wsvg\n",
" stripe_width=3, stripe_colors='ygb',\n", "def offset_curve(path, offset_distance, steps=1000):\n",
" name='offsetcurves.svg', show_normal_line=True):\n", " \"\"\"Takes in a Path object, `path`, and a distance,\n",
" \"\"\"Takes in a path of bezier curves, `bezpath`, and a distance,\n", " `offset_distance`, and outputs an piecewise-linear approximation \n",
" `offset_distance`, and displays the 'parallel' offset curve by placing a\n", " of the 'parallel' offset curve.\"\"\"\n",
" dot at a distance of `offset_distance` away at each step.\"\"\"\n",
" nls = []\n", " nls = []\n",
" nodes = []\n", " for seg in path:\n",
" line_colors = ''\n",
" node_colors = ''\n",
"\n",
" for bez in bezpath:\n",
" ct = 1\n", " ct = 1\n",
" for k in range(steps):\n", " for k in range(steps):\n",
" t = k / steps\n", " t = k / steps\n",
" nl = Line(bez.point(t),\n", " offset_vector = offset_distance * seg.normal(t)\n",
" bez.point(t) + offset_distance * bez.normal(t))\n", " nl = Line(seg.point(t), seg.point(t) + offset_vector)\n",
" nls.append(nl)\n", " nls.append(nl)\n",
" line_colors += stripe_colors[ct % 3]\n", " connect_the_dots = [Line(nls[k].end, nls[k+1].end) for k in range(len(nls)-1)]\n",
" if not (k % stripe_width):\n", " if path.isclosed():\n",
" ct += 1\n", " connect_the_dots.append(Line(nls[-1].end, nls[0].end))\n",
" nodes.append(bez.point(t))\n", " offset_path = Path(*connect_the_dots)\n",
" nodes.append(nl.end)\n", " return offset_path\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",
"\n", "\n",
"bez1 = parse_path(\"m 288,600 c -52,-28 -42,-61 0,-97 \")[0]\n", "# Examples:\n",
"bez2 = parse_path(\"M 151,395 C 407,485 726.17662,160 634,339\")[0]\n", "path1 = parse_path(\"m 288,600 c -52,-28 -42,-61 0,-97 \")\n",
"bez3 = parse_path(\"m 117,695 c 237,-7 -103,-146 457,0\")[0]\n", "path2 = parse_path(\"M 151,395 C 407,485 726.17662,160 634,339\").translated(300)\n",
"path = Path(bez1, bez2.translated(300), bez3.translated(500+400j))\n", "path3 = parse_path(\"m 117,695 c 237,-7 -103,-146 457,0\").translated(500+400j)\n",
"paths = [path1, path2, path3]\n",
"\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", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"![offsetcurves.svg](offsetcurves.svg)" "![offset_curves.svg](offset_curves.svg)"
] ]
}, },
{ {

View File

@ -453,7 +453,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/test.svg .. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/vectorframes.svg
:alt: vectorframes.svg :alt: vectorframes.svg
vectorframes.svg vectorframes.svg
@ -554,60 +554,52 @@ Intersections between Bezier curves
output\_intersections.svg output\_intersections.svg
An Advanced Application: Offsetting Bezier Curves 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 Bezier curve <https://en.wikipedia.org/wiki/Parallel_curve>`__ for a few paths.
cubics.
.. code:: python .. code:: python
def display_offset_curve(bezpath, offset_distance, steps=1000, from svgpathtools import parse_path, Line, Path, wsvg
stripe_width=3, stripe_colors='ygb', def offset_curve(path, offset_distance, steps=1000):
name='offsetcurves.svg', show_normal_line=True): """Takes in a Path object, `path`, and a distance,
"""Takes in a path of bezier curves, `bezpath`, and a distance, `offset_distance`, and outputs an piecewise-linear approximation
`offset_distance`, and displays the 'parallel' offset curve by placing a of the 'parallel' offset curve."""
dot at a distance of `offset_distance` away at each step."""
nls = [] nls = []
nodes = [] for seg in path:
line_colors = ''
node_colors = ''
for bez in bezpath:
ct = 1 ct = 1
for k in range(steps): for k in range(steps):
t = k / steps t = k / steps
nl = Line(bez.point(t), offset_vector = offset_distance * seg.normal(t)
bez.point(t) + offset_distance * bez.normal(t)) nl = Line(seg.point(t), seg.point(t) + offset_vector)
nls.append(nl) nls.append(nl)
line_colors += stripe_colors[ct % 3] connect_the_dots = [Line(nls[k].end, nls[k+1].end) for k in range(len(nls)-1)]
if not (k % stripe_width): if path.isclosed():
ct += 1 connect_the_dots.append(Line(nls[-1].end, nls[0].end))
nodes.append(bez.point(t)) offset_path = Path(*connect_the_dots)
nodes.append(nl.end) return offset_path
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)
bez1 = parse_path("m 288,600 c -52,-28 -42,-61 0,-97 ")[0] # Examples:
bez2 = parse_path("M 151,395 C 407,485 726.17662,160 634,339")[0] path1 = parse_path("m 288,600 c -52,-28 -42,-61 0,-97 ")
bez3 = parse_path("m 117,695 c 237,-7 -103,-146 457,0")[0] path2 = parse_path("M 151,395 C 407,485 726.17662,160 634,339").translated(300)
path = Path(bez1, bez2.translated(300), bez3.translated(500+400j)) 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))
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/offsetcurves.svg # Note: This will take a few moments
:alt: offsetcurves.svg wsvg(paths + offset_paths, 'g'*len(paths) + 'r'*len(offset_paths), filename='offset_curves.svg')
offsetcurves.svg .. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/offset_curves.svg
:alt: offset\_curves.svg
offset\_curves.svg
Compatibility Notes for users of svg.path (v2.0) Compatibility Notes for users of svg.path (v2.0)
------------------------------------------------ ------------------------------------------------

157
offset_curves.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.3 MiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 835 KiB