PEP8 and fix in unittest
parent
77cab1e819
commit
ecdade1be3
|
@ -2136,7 +2136,13 @@ class Path(MutableSequence):
|
||||||
|
|
||||||
def cropped(self, T0, T1):
|
def cropped(self, T0, T1):
|
||||||
"""returns a cropped copy of the path."""
|
"""returns a cropped copy of the path."""
|
||||||
|
assert 0 <= T0 <= 1 and 0 <= T1<= 1
|
||||||
assert T0 != T1
|
assert T0 != T1
|
||||||
|
assert not (T0 == 1 and T1 == 0)
|
||||||
|
|
||||||
|
if T0 == 1 and 0 < T1 < 1 and self.isclosed():
|
||||||
|
return self.cropped(0, T1)
|
||||||
|
|
||||||
if T1 == 1:
|
if T1 == 1:
|
||||||
seg1 = self[-1]
|
seg1 = self[-1]
|
||||||
t_seg1 = 1
|
t_seg1 = 1
|
||||||
|
@ -2171,7 +2177,7 @@ class Path(MutableSequence):
|
||||||
|
|
||||||
# T1<T0 must cross discontinuity case
|
# T1<T0 must cross discontinuity case
|
||||||
if T1 < T0:
|
if T1 < T0:
|
||||||
if self.isclosed():
|
if not self.isclosed():
|
||||||
raise ValueError("This path is not closed, thus T0 must "
|
raise ValueError("This path is not closed, thus T0 must "
|
||||||
"be less than T1.")
|
"be less than T1.")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -5,23 +5,21 @@ The main tool being the svg2paths() function."""
|
||||||
from __future__ import division, absolute_import, print_function
|
from __future__ import division, absolute_import, print_function
|
||||||
from xml.dom.minidom import parse
|
from xml.dom.minidom import parse
|
||||||
from os import path as os_path, getcwd
|
from os import path as os_path, getcwd
|
||||||
from shutil import copyfile
|
import numpy as np
|
||||||
|
|
||||||
# Internal dependencies
|
# Internal dependencies
|
||||||
from .parser import parse_path
|
from .parser import parse_path
|
||||||
|
from .path import Path, bpoints2bezier
|
||||||
|
|
||||||
|
|
||||||
def polyline2pathd(polyline_d):
|
def polyline2pathd(polyline_d):
|
||||||
"""converts the string from a polyline d-attribute to a string for a Path
|
"""converts the string from a polyline points-attribute to a string for a
|
||||||
object d-attribute"""
|
Path object d-attribute"""
|
||||||
points = polyline_d.replace(', ', ',')
|
points = polyline_d.replace(', ', ',')
|
||||||
points = points.replace(' ,', ',')
|
points = points.replace(' ,', ',')
|
||||||
points = points.split()
|
points = points.split()
|
||||||
|
|
||||||
if points[0] == points[-1]:
|
closed = points[0] == points[-1]
|
||||||
closed = True
|
|
||||||
else:
|
|
||||||
closed = False
|
|
||||||
|
|
||||||
d = 'M' + points.pop(0).replace(',', ' ')
|
d = 'M' + points.pop(0).replace(',', ' ')
|
||||||
for p in points:
|
for p in points:
|
||||||
|
@ -31,6 +29,30 @@ def polyline2pathd(polyline_d):
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
def polygon2pathd(polyline_d):
|
||||||
|
"""converts the string from a polygon points-attribute to a string for a
|
||||||
|
Path object d-attribute.
|
||||||
|
Note: For a polygon made from n points, the resulting path will be
|
||||||
|
composed of n lines (even if some of these lines have length zero)."""
|
||||||
|
points = polyline_d.replace(', ', ',')
|
||||||
|
points = points.replace(' ,', ',')
|
||||||
|
points = points.split()
|
||||||
|
|
||||||
|
reduntantly_closed = points[0] == points[-1]
|
||||||
|
|
||||||
|
d = 'M' + points[0].replace(',', ' ')
|
||||||
|
for p in points[1:]:
|
||||||
|
d += 'L' + p.replace(',', ' ')
|
||||||
|
|
||||||
|
# The `parse_path` call ignores redundant 'z' (closure) commands
|
||||||
|
# e.g. `parse_path('M0 0L100 100Z') == parse_path('M0 0L100 100L0 0Z')`
|
||||||
|
# This check ensures that an n-point polygon is converted to an n-Line path.
|
||||||
|
if reduntantly_closed:
|
||||||
|
d += 'L' + points[0].replace(',', ' ')
|
||||||
|
|
||||||
|
return d + 'z'
|
||||||
|
|
||||||
|
|
||||||
def svg2paths(svg_file_location,
|
def svg2paths(svg_file_location,
|
||||||
convert_lines_to_paths=True,
|
convert_lines_to_paths=True,
|
||||||
convert_polylines_to_paths=True,
|
convert_polylines_to_paths=True,
|
||||||
|
@ -62,52 +84,126 @@ def svg2paths(svg_file_location,
|
||||||
# else:
|
# else:
|
||||||
doc = parse(svg_file_location)
|
doc = parse(svg_file_location)
|
||||||
|
|
||||||
|
# Parse a list of paths
|
||||||
def dom2dict(element):
|
def dom2dict(element):
|
||||||
"""Converts DOM elements to dictionaries of attributes."""
|
"""Converts DOM elements to dictionaries of attributes."""
|
||||||
keys = list(element.attributes.keys())
|
keys = list(element.attributes.keys())
|
||||||
values = [val.value for val in list(element.attributes.values())]
|
values = [val.value for val in list(element.attributes.values())]
|
||||||
return dict(list(zip(keys, values)))
|
return dict(list(zip(keys, values)))
|
||||||
|
|
||||||
# Use minidom to extract path strings from input SVG
|
def parse_trafo(trafo_str):
|
||||||
paths = [dom2dict(el) for el in doc.getElementsByTagName('path')]
|
"""Returns six matrix elements for a matrix transformation for any valid SVG transformation string."""
|
||||||
d_strings = [el['d'] for el in paths]
|
trafos = trafo_str.split(')')[:-1]
|
||||||
attribute_dictionary_list = paths
|
trafo_matrix = np.array([1., 0., 0., 0., 1., 0., 0., 0., 1.]).reshape((3, 3)) # Start with neutral matrix
|
||||||
# if pathless_svg:
|
|
||||||
# for el in doc.getElementsByTagName('path'):
|
|
||||||
# el.parentNode.removeChild(el)
|
|
||||||
|
|
||||||
# Use minidom to extract polyline strings from input SVG, convert to
|
for trafo_sub_str in trafos:
|
||||||
# path strings, add to list
|
trafo_sub_str = trafo_sub_str.lstrip(', ')
|
||||||
if convert_polylines_to_paths:
|
value_str = trafo_sub_str.split('(')[1]
|
||||||
plins = [dom2dict(el) for el in doc.getElementsByTagName('polyline')]
|
values = list(map(float, value_str.split(',')))
|
||||||
d_strings += [polyline2pathd(pl['points']) for pl in plins]
|
if 'translate' in trafo_sub_str:
|
||||||
attribute_dictionary_list += plins
|
x = values[0]
|
||||||
|
y = values[1] if (len(values) > 1) else 0.
|
||||||
|
trafo_matrix = np.dot(trafo_matrix,
|
||||||
|
np.array([1., 0., x, 0., 1., y, 0., 0., 1.]).reshape((3, 3)))
|
||||||
|
elif 'scale' in trafo_sub_str:
|
||||||
|
x = values[0]
|
||||||
|
y = values[1] if (len(values) > 1) else 0.
|
||||||
|
trafo_matrix = np.dot(trafo_matrix,
|
||||||
|
np.array([x, 0., 0., 0., y, 0., 0., 0., 1.]).reshape((3, 3)))
|
||||||
|
elif 'rotate' in trafo_sub_str:
|
||||||
|
a = values[0]*np.pi/180.
|
||||||
|
x = values[1] if (len(values) > 1) else 0.
|
||||||
|
y = values[2] if (len(values) > 2) else 0.
|
||||||
|
am = np.dot(np.array([np.cos(a), -np.sin(a), 0., np.sin(a), np.cos(a), 0., 0., 0., 1.]).reshape((3, 3)),
|
||||||
|
np.array([1., 0., -x, 0., 1., -y, 0., 0., 1.]).reshape((3, 3)))
|
||||||
|
am = np.dot(np.array([1., 0., x, 0., 1., y, 0., 0., 1.]).reshape((3, 3)), am)
|
||||||
|
trafo_matrix = np.dot(trafo_matrix, am)
|
||||||
|
elif 'skewX' in trafo_sub_str:
|
||||||
|
a = values[0]*np.pi/180.
|
||||||
|
trafo_matrix = np.dot(trafo_matrix,
|
||||||
|
np.array([1., np.tan(a), 0., 0., 1., 0., 0., 0., 1.]).reshape((3, 3)))
|
||||||
|
elif 'skewY' in trafo_sub_str:
|
||||||
|
a = values[0]*np.pi/180.
|
||||||
|
trafo_matrix = np.dot(trafo_matrix,
|
||||||
|
np.array([1., 0., 0., np.tan(a), 1., 0., 0., 0., 1.]).reshape((3, 3)))
|
||||||
|
else: # Assume matrix transformation
|
||||||
|
while len(values) < 6:
|
||||||
|
values += [0.]
|
||||||
|
trafo_matrix = np.dot(trafo_matrix,
|
||||||
|
np.array([values[::2], values[1::2], [0., 0., 1.]]))
|
||||||
|
|
||||||
# Use minidom to extract polygon strings from input SVG, convert to
|
trafo_list = list(trafo_matrix.reshape((9,))[:6])
|
||||||
# path strings, add to list
|
return trafo_list[::3]+trafo_list[1::3]+trafo_list[2::3]
|
||||||
if convert_polygons_to_paths:
|
|
||||||
pgons = [dom2dict(el) for el in doc.getElementsByTagName('polygon')]
|
|
||||||
d_strings += [polyline2pathd(pg['points']) + 'z' for pg in pgons]
|
|
||||||
attribute_dictionary_list += pgons
|
|
||||||
|
|
||||||
if convert_lines_to_paths:
|
def parse_node(node):
|
||||||
lines = [dom2dict(el) for el in doc.getElementsByTagName('line')]
|
"""Recursively iterate over nodes. Parse the groups individually to apply group transformations."""
|
||||||
d_strings += [('M' + l['x1'] + ' ' + l['y1'] +
|
# Get everything in this tag
|
||||||
'L' + l['x2'] + ' ' + l['y2']) for l in lines]
|
data = [parse_node(child) for child in node.childNodes]
|
||||||
attribute_dictionary_list += lines
|
if len(data) == 0:
|
||||||
|
ret_list = []
|
||||||
|
attribute_dictionary_list_int = []
|
||||||
|
else:
|
||||||
|
# Flatten the lists
|
||||||
|
ret_list = []
|
||||||
|
attribute_dictionary_list_int = []
|
||||||
|
for item in data:
|
||||||
|
if type(item) == tuple:
|
||||||
|
if len(item[0]) > 0:
|
||||||
|
ret_list += item[0]
|
||||||
|
attribute_dictionary_list_int += item[1]
|
||||||
|
|
||||||
# if pathless_svg:
|
if node.nodeName == 'g':
|
||||||
# with open(pathless_svg, "wb") as f:
|
# Group found
|
||||||
# doc.writexml(f)
|
# Analyse group properties
|
||||||
|
group = dom2dict(node)
|
||||||
|
if 'transform' in group.keys():
|
||||||
|
trafo = group['transform']
|
||||||
|
|
||||||
|
# Convert all transformations into a matrix operation
|
||||||
|
am = parse_trafo(trafo)
|
||||||
|
am = np.array([am[::2], am[1::2], [0., 0., 1.]])
|
||||||
|
|
||||||
|
# Apply transformation to all elements of the paths
|
||||||
|
def xy(p):
|
||||||
|
return np.array([p.real, p.imag, 1.])
|
||||||
|
|
||||||
|
def z(coords):
|
||||||
|
return coords[0] + 1j*coords[1]
|
||||||
|
|
||||||
|
ret_list = [Path(*[bpoints2bezier([z(np.dot(am, xy(pt)))
|
||||||
|
for pt in seg.bpoints()])
|
||||||
|
for seg in path])
|
||||||
|
for path in ret_list]
|
||||||
|
return ret_list, attribute_dictionary_list_int
|
||||||
|
elif node.nodeName == 'path':
|
||||||
|
# Path found; parsing it
|
||||||
|
path = dom2dict(node)
|
||||||
|
d_string = path['d']
|
||||||
|
return [parse_path(d_string)]+ret_list, [path]+attribute_dictionary_list_int
|
||||||
|
elif convert_polylines_to_paths and node.nodeName == 'polyline':
|
||||||
|
attrs = dom2dict(node)
|
||||||
|
path = parse_path(polyline2pathd(node['points']))
|
||||||
|
return [path]+ret_list, [attrs]+attribute_dictionary_list_int
|
||||||
|
elif convert_polygons_to_paths and node.nodeName == 'polygon':
|
||||||
|
attrs = dom2dict(node)
|
||||||
|
path = parse_path(polygon2pathd(attrs['points']))
|
||||||
|
return [path]+ret_list, [attrs]+attribute_dictionary_list_int
|
||||||
|
elif convert_lines_to_paths and node.nodeName == 'line':
|
||||||
|
line = dom2dict(node)
|
||||||
|
d_string = ('M' + line['x1'] + ' ' + line['y1'] +
|
||||||
|
'L' + line['x2'] + ' ' + line['y2'])
|
||||||
|
path = parse_path(d_string)
|
||||||
|
return [path]+ret_list, [line]+attribute_dictionary_list_int
|
||||||
|
else:
|
||||||
|
return ret_list, attribute_dictionary_list_int
|
||||||
|
|
||||||
|
path_list, attribute_dictionary_list = parse_node(doc)
|
||||||
if return_svg_attributes:
|
if return_svg_attributes:
|
||||||
svg_attributes = dom2dict(doc.getElementsByTagName('svg')[0])
|
svg_attributes = dom2dict(doc.getElementsByTagName('svg')[0])
|
||||||
doc.unlink()
|
doc.unlink()
|
||||||
path_list = [parse_path(d) for d in d_strings]
|
|
||||||
return path_list, attribute_dictionary_list, svg_attributes
|
return path_list, attribute_dictionary_list, svg_attributes
|
||||||
else:
|
else:
|
||||||
doc.unlink()
|
doc.unlink()
|
||||||
path_list = [parse_path(d) for d in d_strings]
|
|
||||||
return path_list, attribute_dictionary_list
|
return path_list, attribute_dictionary_list
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
Metadata-Version: 1.1
|
Metadata-Version: 1.1
|
||||||
Name: svgpathtools
|
Name: svgpathtools
|
||||||
Version: 1.3.1
|
Version: 1.3.2b0
|
||||||
Summary: A collection of tools for manipulating and analyzing SVG Path objects and Bezier curves.
|
Summary: A collection of tools for manipulating and analyzing SVG Path objects and Bezier curves.
|
||||||
Home-page: https://github.com/mathandy/svgpathtools
|
Home-page: https://github.com/mathandy/svgpathtools
|
||||||
Author: Andy Port
|
Author: Andy Port
|
||||||
Author-email: AndyAPort@gmail.com
|
Author-email: AndyAPort@gmail.com
|
||||||
License: MIT
|
License: MIT
|
||||||
Download-URL: http://github.com/mathandy/svgpathtools/tarball/1.3.1
|
Download-URL: http://github.com/mathandy/svgpathtools/tarball/1.3.2beta
|
||||||
Description: svgpathtools
|
Description:
|
||||||
|
svgpathtools
|
||||||
============
|
============
|
||||||
|
|
||||||
svgpathtools is a collection of tools for manipulating and analyzing SVG
|
svgpathtools is a collection of tools for manipulating and analyzing SVG
|
||||||
|
@ -46,11 +47,6 @@ Description: svgpathtools
|
||||||
- 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
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
@ -94,8 +90,6 @@ Description: svgpathtools
|
||||||
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
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
@ -126,11 +120,11 @@ Description: svgpathtools
|
||||||
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
|
||||||
|
@ -167,7 +161,7 @@ Description: svgpathtools
|
||||||
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))
|
||||||
|
@ -234,7 +228,7 @@ Description: svgpathtools
|
||||||
| 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
|
||||||
|
@ -271,7 +265,7 @@ Description: svgpathtools
|
||||||
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')
|
||||||
|
@ -303,7 +297,7 @@ Description: svgpathtools
|
||||||
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:
|
||||||
|
|
||||||
|
@ -333,11 +327,11 @@ Description: svgpathtools
|
||||||
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.
|
||||||
|
@ -369,9 +363,10 @@ Description: svgpathtools
|
||||||
\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)
|
||||||
|
@ -401,15 +396,25 @@ Description: svgpathtools
|
||||||
(-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
|
||||||
ways.
|
|
||||||
|
|
||||||
Tangent vectors (and more on polynomials)
|
Numpy Array operations on Bézier path segments
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: python
|
`Example available
|
||||||
|
here <https://github.com/mathandy/svgpathtools/blob/master/examples/compute-many-points-quickly-using-numpy-arrays.py>`__
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
@ -451,7 +456,7 @@ Description: svgpathtools
|
||||||
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)
|
||||||
|
@ -481,7 +486,7 @@ Description: svgpathtools
|
||||||
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)
|
||||||
|
@ -514,7 +519,7 @@ Description: svgpathtools
|
||||||
``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')
|
||||||
|
@ -556,7 +561,7 @@ Description: svgpathtools
|
||||||
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]
|
||||||
|
@ -580,7 +585,7 @@ Description: svgpathtools
|
||||||
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):
|
||||||
|
@ -638,6 +643,7 @@ Description: svgpathtools
|
||||||
|
|
||||||
This module is under a MIT License.
|
This module is under a MIT License.
|
||||||
|
|
||||||
|
|
||||||
Keywords: svg,svg path,svg.path,bezier,parse svg path,display svg
|
Keywords: svg,svg path,svg.path,bezier,parse svg path,display svg
|
||||||
Platform: OS Independent
|
Platform: OS Independent
|
||||||
Classifier: Development Status :: 4 - Beta
|
Classifier: Development Status :: 4 - Beta
|
||||||
|
|
|
@ -15,12 +15,10 @@ test.svg
|
||||||
vectorframes.svg
|
vectorframes.svg
|
||||||
svgpathtools/__init__.py
|
svgpathtools/__init__.py
|
||||||
svgpathtools/bezier.py
|
svgpathtools/bezier.py
|
||||||
svgpathtools/directional_field.py
|
|
||||||
svgpathtools/misctools.py
|
svgpathtools/misctools.py
|
||||||
svgpathtools/parser.py
|
svgpathtools/parser.py
|
||||||
svgpathtools/path.py
|
svgpathtools/path.py
|
||||||
svgpathtools/paths2svg.py
|
svgpathtools/paths2svg.py
|
||||||
svgpathtools/pathtools.py
|
|
||||||
svgpathtools/polytools.py
|
svgpathtools/polytools.py
|
||||||
svgpathtools/smoothing.py
|
svgpathtools/smoothing.py
|
||||||
svgpathtools/svg2paths.py
|
svgpathtools/svg2paths.py
|
||||||
|
@ -28,10 +26,13 @@ svgpathtools.egg-info/PKG-INFO
|
||||||
svgpathtools.egg-info/SOURCES.txt
|
svgpathtools.egg-info/SOURCES.txt
|
||||||
svgpathtools.egg-info/dependency_links.txt
|
svgpathtools.egg-info/dependency_links.txt
|
||||||
svgpathtools.egg-info/top_level.txt
|
svgpathtools.egg-info/top_level.txt
|
||||||
|
test/groups.svg
|
||||||
|
test/polygons.svg
|
||||||
test/test.svg
|
test/test.svg
|
||||||
test/test_bezier.py
|
test/test_bezier.py
|
||||||
test/test_generation.py
|
test/test_generation.py
|
||||||
test/test_parsing.py
|
test/test_parsing.py
|
||||||
test/test_path.py
|
test/test_path.py
|
||||||
test/test_pathtools.py
|
|
||||||
test/test_polytools.py
|
test/test_polytools.py
|
||||||
|
test/test_svg2paths.py
|
||||||
|
test/test_svg2paths_groups.py
|
|
@ -83,7 +83,7 @@
|
||||||
id="p14"
|
id="p14"
|
||||||
style="stroke:#ff0000;stroke-width:2."
|
style="stroke:#ff0000;stroke-width:2."
|
||||||
d="m 1100.,100. 100.,0." />
|
d="m 1100.,100. 100.,0." />
|
||||||
<g id="concatenated" transform="translate(1150.,150.),rotate(-90.)">
|
<g id="concatenated" transform="translate(1150.,150.) rotate(-90.)">
|
||||||
<path
|
<path
|
||||||
id="p15"
|
id="p15"
|
||||||
style="stroke:#ff0000;stroke-width:2."
|
style="stroke:#ff0000;stroke-width:2."
|
||||||
|
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Loading…
Reference in New Issue