futurized for Python 3 compatibility
and some other minor changes of no effectpull/12/merge
parent
f697a91190
commit
8815ddcd52
2
setup.py
2
setup.py
|
@ -3,7 +3,7 @@ import codecs
|
|||
import os
|
||||
|
||||
|
||||
VERSION = '1.2.6'
|
||||
VERSION = '1.3'
|
||||
AUTHOR_NAME = 'Andy Port'
|
||||
AUTHOR_EMAIL = 'AndyAPort@gmail.com'
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ points given by their standard representation."""
|
|||
|
||||
# External dependencies:
|
||||
from __future__ import division, absolute_import, print_function
|
||||
from builtins import range
|
||||
from builtins import object
|
||||
from math import factorial as fac, ceil, log, sqrt
|
||||
from numpy import poly1d
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ aren't specific to SVGs or related mathematical objects."""
|
|||
|
||||
# External dependencies:
|
||||
from __future__ import division, absolute_import, print_function
|
||||
from builtins import range
|
||||
import os
|
||||
import sys
|
||||
import webbrowser
|
||||
|
|
|
@ -4,6 +4,10 @@ Arc."""
|
|||
|
||||
# External dependencies
|
||||
from __future__ import division, absolute_import, print_function
|
||||
from builtins import map
|
||||
from builtins import zip
|
||||
from builtins import range
|
||||
from builtins import object
|
||||
from math import sqrt, cos, sin, acos, degrees, radians, log, pi
|
||||
from cmath import exp, sqrt as csqrt, phase
|
||||
from collections import MutableSequence
|
||||
|
@ -355,7 +359,8 @@ def inv_arclength(curve, s, s_tol=ILENGTH_S_TOL, maxits=ILENGTH_MAXITS,
|
|||
if curve is a Path object, then seg is a segment in curve.
|
||||
error - used to compute lengths of cubics and arcs
|
||||
min_depth - used to compute lengths of cubics and arcs
|
||||
Note: This function is not designed to be efficient."""
|
||||
Note: This function is not designed to be efficient, but if it's slower
|
||||
than you need, make sure you have scipy installed."""
|
||||
|
||||
curve_length = curve.length(error=error, min_depth=min_depth)
|
||||
assert curve_length > 0
|
||||
|
@ -1514,7 +1519,7 @@ class Arc(object):
|
|||
u1poly_mag2 = real(u1poly)**2 + imag(u1poly)**2
|
||||
t2s = polyroots01(u1poly_mag2 - 1)
|
||||
t1s = [self.phase2t(phase(u1poly(t2))) for t2 in t2s]
|
||||
return zip(t1s, t2s)
|
||||
return list(zip(t1s, t2s))
|
||||
elif isinstance(other_seg, Arc):
|
||||
assert other_seg != self
|
||||
# This could be made explicit to increase efficiency
|
||||
|
@ -2126,7 +2131,7 @@ class Path(MutableSequence):
|
|||
"""returns a bounding box for the input Path object in the form
|
||||
(xmin, xmax, ymin, ymax)."""
|
||||
bbs = [seg.bbox() for seg in self._segments]
|
||||
xmins, xmaxs, ymins, ymaxs = zip(*bbs)
|
||||
xmins, xmaxs, ymins, ymaxs = list(zip(*bbs))
|
||||
xmin = min(xmins)
|
||||
xmax = max(xmaxs)
|
||||
ymin = min(ymins)
|
||||
|
|
|
@ -3,6 +3,8 @@ segments."""
|
|||
|
||||
# External dependencies:
|
||||
from __future__ import division, absolute_import, print_function
|
||||
from builtins import zip
|
||||
from builtins import str
|
||||
from math import ceil
|
||||
from os import getcwd, path as os_path, makedirs
|
||||
from xml.dom.minidom import parse as md_xml_parse
|
||||
|
@ -74,7 +76,7 @@ def big_bounding_box(paths_n_stuff):
|
|||
raise TypeError(
|
||||
"paths_n_stuff can only contains Path, CubicBezier, "
|
||||
"QuadraticBezier, Line, and complex objects.")
|
||||
xmins, xmaxs, ymins, ymaxs = zip(*bbs)
|
||||
xmins, xmaxs, ymins, ymaxs = list(zip(*bbs))
|
||||
xmin = min(xmins)
|
||||
xmax = max(xmaxs)
|
||||
ymin = min(ymins)
|
||||
|
|
|
@ -5,6 +5,7 @@ curves."""
|
|||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
# Internal Dependencies
|
||||
from builtins import range
|
||||
from .path import Path, CubicBezier, Line
|
||||
from .misctools import isclose
|
||||
from .paths2svg import disvg
|
||||
|
|
|
@ -3,6 +3,7 @@ The main tool being the svg2paths() function."""
|
|||
|
||||
# External dependencies
|
||||
from __future__ import division, absolute_import, print_function
|
||||
from builtins import zip
|
||||
from xml.dom.minidom import parse
|
||||
from os import path as os_path, getcwd
|
||||
from shutil import copyfile
|
||||
|
@ -64,9 +65,9 @@ def svg2paths(svg_file_location,
|
|||
|
||||
def dom2dict(element):
|
||||
"""Converts DOM elements to dictionaries of attributes."""
|
||||
keys = element.attributes.keys()
|
||||
values = [val.value for val in element.attributes.values()]
|
||||
return dict(zip(keys, values))
|
||||
keys = list(element.attributes.keys())
|
||||
values = [val.value for val in list(element.attributes.values())]
|
||||
return dict(list(zip(keys, values)))
|
||||
|
||||
# Use minidom to extract path strings from input SVG
|
||||
paths = [dom2dict(el) for el in doc.getElementsByTagName('path')]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from __future__ import division, absolute_import, print_function
|
||||
import numpy as np
|
||||
from builtins import range
|
||||
import unittest
|
||||
from svgpathtools.bezier import *
|
||||
from svgpathtools.path import bpoints2bezier
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
# Note: This file was taken mostly as is from the svg.path module (v 2.0)
|
||||
#------------------------------------------------------------------------------
|
||||
from __future__ import division, absolute_import, print_function
|
||||
from builtins import zip
|
||||
import unittest
|
||||
from svgpathtools import *
|
||||
|
||||
|
||||
class TestGeneration(unittest.TestCase):
|
||||
|
||||
def test_svg_examples(self):
|
||||
def test_path_parsing(self):
|
||||
"""Examples from the SVG spec"""
|
||||
paths = [
|
||||
'M 100,100 L 300,100 L 200,300 Z',
|
||||
|
@ -26,7 +27,7 @@ class TestGeneration(unittest.TestCase):
|
|||
'M 0,0 L 50,20 M 50,20 L 200,100 Z',
|
||||
'M 600,350 L 650,325 A 25,25 -30 0,1 700,300 L 750,275',
|
||||
]
|
||||
pathsf = [
|
||||
float_paths = [
|
||||
'M 100.0,100.0 L 300.0,100.0 L 200.0,300.0 L 100.0,100.0',
|
||||
'M 0.0,0.0 L 50.0,20.0 M 100.0,100.0 L 300.0,100.0 L 200.0,300.0 L 100.0,100.0',
|
||||
'M 100.0,100.0 L 200.0,200.0',
|
||||
|
@ -41,11 +42,32 @@ class TestGeneration(unittest.TestCase):
|
|||
'M 200.0,300.0 Q 400.0,50.0 600.0,300.0 Q 800.0,550.0 1000.0,300.0',
|
||||
'M -3.4e+38,3.4e+38 L -3.4e-38,3.4e-38',
|
||||
'M 0.0,0.0 L 50.0,20.0 L 200.0,100.0 L 50.0,20.0',
|
||||
'M 600.0,350.0 L 650.0,325.0 A 27.9508497187,27.9508497187 -30.0 0,1 700.0,300.0 L 750.0,275.0'
|
||||
('M 600.0,350.0 L 650.0,325.0 A 27.9508497187,27.9508497187 -30.0 0,1 700.0,300.0 L 750.0,275.0', # Python 2
|
||||
'M 600.0,350.0 L 650.0,325.0 A 27.95084971874737,27.95084971874737 -30.0 0,1 700.0,300.0 L 750.0,275.0') # Python 3
|
||||
]
|
||||
|
||||
for k, path in enumerate(paths):
|
||||
self.assertTrue(parse_path(path).d() in (path, pathsf[k]))
|
||||
for path, flpath in zip(paths[::-1], float_paths[::-1]):
|
||||
# Note: Python 3 and Python 2 differ in the number of digits
|
||||
# truncated when returning a string representation of a float
|
||||
parsed_path = parse_path(path)
|
||||
res = parsed_path.d()
|
||||
if isinstance(flpath, tuple):
|
||||
option3 = res == flpath[1] # Python 3
|
||||
flpath = flpath[0]
|
||||
else:
|
||||
option3 = False
|
||||
option1 = res == path
|
||||
option2 = res == flpath
|
||||
|
||||
msg = ('\npath =\n {}\nflpath =\n {}\nparse_path(path).d() =\n {}'
|
||||
''.format(path, flpath, res))
|
||||
self.assertTrue(option1 or option2 or option3, msg=msg)
|
||||
|
||||
for flpath in float_paths[:-1]:
|
||||
res = parse_path(flpath).d()
|
||||
msg = ('\nflpath =\n {}\nparse_path(path).d() =\n {}'
|
||||
''.format(flpath, res))
|
||||
self.assertTrue(res == flpath, msg=msg)
|
||||
|
||||
def test_normalizing(self):
|
||||
# Relative paths will be made absolute, subpaths merged if they can,
|
||||
|
@ -54,3 +76,7 @@ class TestGeneration(unittest.TestCase):
|
|||
ps = 'M 0,0 L 340,-10 L 100,100 L 200,0'
|
||||
psf = 'M 0.0,0.0 L 340.0,-10.0 L 100.0,100.0 L 200.0,0.0'
|
||||
self.assertTrue(parse_path(path).d() in (ps, psf))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# External dependencies
|
||||
from __future__ import division, absolute_import, print_function
|
||||
from builtins import zip
|
||||
from builtins import str
|
||||
import unittest
|
||||
from math import sqrt, pi
|
||||
from operator import itemgetter
|
||||
|
@ -661,11 +663,11 @@ class TestPath(unittest.TestCase):
|
|||
|
||||
|
||||
class Test_ilength(unittest.TestCase):
|
||||
def test_ilength(self):
|
||||
# See svgpathtools.notes.inv_arclength.py for information on how these
|
||||
# test values were generated (using the .length() method).
|
||||
##############################################################
|
||||
# Lines
|
||||
|
||||
def test_ilength_lines(self):
|
||||
l = Line(1, 3-1j)
|
||||
nodall = Line(1+1j, 1+1j)
|
||||
|
||||
|
@ -678,8 +680,7 @@ class Test_ilength(unittest.TestCase):
|
|||
for (l, t, s) in tests:
|
||||
self.assertAlmostEqual(l.ilength(s), t)
|
||||
|
||||
###############################################################
|
||||
# Quadratics
|
||||
def test_ilength_quadratics(self):
|
||||
q1 = QuadraticBezier(200 + 300j, 400 + 50j, 600 + 300j)
|
||||
q2 = QuadraticBezier(200 + 300j, 400 + 50j, 500 + 200j)
|
||||
closedq = QuadraticBezier(6 + 2j, 5 - 1j, 6 + 2j)
|
||||
|
@ -716,8 +717,7 @@ class Test_ilength(unittest.TestCase):
|
|||
print(t)
|
||||
raise
|
||||
|
||||
###############################################################
|
||||
# Cubics
|
||||
def test_ilength_cubics(self):
|
||||
c1 = CubicBezier(200 + 300j, 400 + 50j, 600+100j, -200)
|
||||
symc = CubicBezier(1-2j, 10-1j, 10+1j, 1+2j)
|
||||
closedc = CubicBezier(1-2j, 10-1j, 10+1j, 1-2j)
|
||||
|
@ -741,8 +741,7 @@ class Test_ilength(unittest.TestCase):
|
|||
for (c, t, s) in tests:
|
||||
self.assertAlmostEqual(c.ilength(s), t)
|
||||
|
||||
###############################################################
|
||||
# Arcs
|
||||
def test_ilength_arcs(self):
|
||||
arc1 = Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j)
|
||||
arc2 = Arc(0j, 100 + 50j, 0, 1, 0, 100 + 50j)
|
||||
arc3 = Arc(0j, 100 + 50j, 0, 0, 1, 100 + 50j)
|
||||
|
@ -790,8 +789,7 @@ class Test_ilength(unittest.TestCase):
|
|||
for (c, t, s) in tests:
|
||||
self.assertAlmostEqual(c.ilength(s), t)
|
||||
|
||||
###############################################################
|
||||
# Paths
|
||||
def test_ilength_paths(self):
|
||||
line1 = Line(600 + 350j, 650 + 325j)
|
||||
arc1 = Arc(650 + 325j, 25 + 25j, -30, 0, 1, 700 + 300j)
|
||||
cub1 = CubicBezier(650 + 325j, 25 + 25j, -30, 700 + 300j)
|
||||
|
@ -890,10 +888,10 @@ class Test_ilength(unittest.TestCase):
|
|||
(apath, 1.0, 87.81018330500885)]
|
||||
|
||||
for (c, t, s) in tests:
|
||||
self.assertAlmostEqual(c.ilength(s), t)
|
||||
self.assertAlmostEqual(c.ilength(s), t, msg=str((c, t, s)))
|
||||
|
||||
###############################################################
|
||||
# Exception Cases
|
||||
# Exceptional Cases
|
||||
def test_ilength_exceptions(self):
|
||||
nodalq = QuadraticBezier(1, 1, 1)
|
||||
with self.assertRaises(AssertionError):
|
||||
nodalq.ilength(1)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# External dependencies
|
||||
from __future__ import division, absolute_import, print_function
|
||||
from builtins import range
|
||||
import unittest
|
||||
from numpy import poly1d
|
||||
|
||||
|
@ -57,11 +58,11 @@ class TestPathTools(unittest.TestCase):
|
|||
# Input poly1d object
|
||||
bez = poly2bez(p)
|
||||
bpoints = bez.bpoints()
|
||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
||||
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||
|
||||
# Input list of coefficients
|
||||
bpoints = poly2bez(pcoeffs, return_bpoints=True)
|
||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
||||
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||
|
||||
# Case: Quadratic
|
||||
pcoeffs = [(29.5+15.5j), (-31-19j), (7.5+5.5j)]
|
||||
|
@ -71,11 +72,11 @@ class TestPathTools(unittest.TestCase):
|
|||
# Input poly1d object
|
||||
bez = poly2bez(p)
|
||||
bpoints = bez.bpoints()
|
||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
||||
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||
|
||||
# Input list of coefficients
|
||||
bpoints = poly2bez(pcoeffs, return_bpoints=True)
|
||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
||||
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||
|
||||
# Case: Cubic
|
||||
pcoeffs = [(-18.5-12.5j), (34.5+16.5j), (-18-6j), (6+2j)]
|
||||
|
@ -85,11 +86,11 @@ class TestPathTools(unittest.TestCase):
|
|||
# Input poly1d object
|
||||
bez = poly2bez(p)
|
||||
bpoints = bez.bpoints()
|
||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
||||
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||
|
||||
# Input list of coefficients object
|
||||
bpoints = poly2bez(pcoeffs, return_bpoints=True)
|
||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
||||
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||
|
||||
def test_bpoints2bezier(self):
|
||||
cubic_bpoints = [(6+2j), 0, (5.5+3.5j), (4+0j)]
|
||||
|
|
Loading…
Reference in New Issue