Skip to content

Commit

Permalink
Prep for release
Browse files Browse the repository at this point in the history
  • Loading branch information
nvictus committed Nov 20, 2018
1 parent 21da8df commit 46a6d78
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 22 deletions.
11 changes: 11 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
Changelog
=========

0.2.1 (2018-11-19)
++++++++++++++++++

- First release.

0.2.0 (2018-10)
+++++++++++++++

- Parser re-write based largely on svg.path (https://github.com/regebro/svg.path/blob/master/src/svg/path/parser.py)
- 2D coordinates are now encoded as complex numbers.

0.1.0 (2016-04-10)
++++++++++++++++++

Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ This module adds the path commands missing from (1), including smooth curves and
>>> parse_path('M 100 100 L 300 100')
Path(array([[ 100., 100.], [ 300., 100.]]), array([1, 2], dtype=uint8))

There are likely still issues with implicit commands and subpaths to be sorted out.
See the Jupyter Notebook `gallery <http://nbviewer.jupyter.org/github/nvictus/svgpath2mpl/tree/master/examples/>`_ of examples.

Resources
---------
Expand All @@ -36,4 +36,4 @@ See the matplotlib path `tutorial <http://matplotlib.org/users/path_tutorial.htm
License
-------

BSD (New).
BSD (3-Clause).
58 changes: 38 additions & 20 deletions svgpath2mpl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""
SVGPATH2MPL
~~~~~~~~~~~
Parse SVG path data strings into matplotlib `Path` objects.
Parse SVG path definition strings into matplotlib Path objects.
A path in SVG is defined by a 'path' element which contains a
``d="(path data)"`` attribute that contains moveto, line, curve (both
cubic and quadratic Béziers), arc and closepath instructions. See the SVG
Expand All @@ -11,12 +11,6 @@
:copyright: (c) 2016, Nezar Abdennur.
:license: BSD.
Notes
~~~~~
2018-10: Parser re-write based largely on svg.path
(https://github.com/regebro/svg.path/blob/master/src/svg/path/parser.py)
2D coordinates are now encoded as complex numbers.
"""
from __future__ import division, print_function
from math import sin, cos, sqrt, degrees, radians, acos
Expand Down Expand Up @@ -161,7 +155,7 @@ def endpoint_to_center(start, radius, rotation, large, sweep, end):
if uy < 0:
theta = -theta

# the angle between two vectors ((x1'-cx')/rx, (y1'-c1y/ry)) and
# the angle between two vectors ((x1'-cx')/rx, (y1'-c1y/ry)) and
# ((-x1'-cx')/rx, (-y1'-c1y/ry))
p = ux * vx + uy * vy
n = sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy))
Expand Down Expand Up @@ -190,7 +184,7 @@ def _tokenize_path(pathdef):
for token in FLOAT_RE.findall(x):
yield token


def _next_pos(elements):
return float(elements.pop()) + float(elements.pop()) * 1j

Expand Down Expand Up @@ -244,7 +238,7 @@ def _parse_path(pathdef, current_pos):
start_pos = current_pos

yield COMMAND_CODES['M'], [(current_pos.real, current_pos.imag)]

# Implicit moveto commands are treated as lineto commands.
# So we set command to lineto here, in case there are
# further implicit commands after this moveto.
Expand All @@ -264,7 +258,7 @@ def _parse_path(pathdef, current_pos):
current_pos = start_pos
start_pos = None
command = None # You can't have implicit commands after closing.

# LINETO
elif command == 'L':
pos = _next_pos(elements)
Expand Down Expand Up @@ -389,20 +383,20 @@ def _parse_path(pathdef, current_pos):
end += current_pos

center, theta1, theta2 = endpoint_to_center(
current_pos,
radius,
rotation,
large,
sweep,
current_pos,
radius,
rotation,
large,
sweep,
end
)

# Create an arc on the unit circle
if theta2 > theta1:
arc = Path.arc(theta1=theta1, theta2=theta2)
else:
arc = Path.arc(theta1=theta2, theta2=theta1)

# Transform it into an elliptical arc:
# * scale the minor and major axes
# * translate it to the center
Expand All @@ -417,7 +411,7 @@ def _parse_path(pathdef, current_pos):
arc = trans.transform_path(arc)

verts = np.array(arc.vertices)
codes = np.array(arc.codes)
codes = np.array(arc.codes)
if sweep:
# mysterious hack needed to render properly when sweeping the
# arc angle in the "positive" angular direction
Expand All @@ -427,8 +421,32 @@ def _parse_path(pathdef, current_pos):

current_pos = end


def parse_path(pathdef, current_pos=0 + 0j):
"""
Parse an SVG path definition string into a matplotlib Path object.
Parameters
----------
pathdef : str
SVG path 'd' attribute, e.g. 'M 100 100 L 300 100 L 200 300 z'.
current_pos : complex, optional
Coordinates of the starting position of the path, given as a complex
number. When provided, an initial moveto operation will be intepreted
as relative to this position even if given as M.
Returns
-------
:class:`matplotlib.path.Path` instance
See also
--------
matplotlib.path.Path
matplotlib.patches.PathPatch
matplotlib.collections.PathCollection
matplotlib.transforms
"""
codes = []
verts = []
for c, v in _parse_path(pathdef, current_pos):
Expand Down

0 comments on commit 46a6d78

Please sign in to comment.