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
|
import os
|
||||||
|
|
||||||
|
|
||||||
VERSION = '1.2.6'
|
VERSION = '1.3'
|
||||||
AUTHOR_NAME = 'Andy Port'
|
AUTHOR_NAME = 'Andy Port'
|
||||||
AUTHOR_EMAIL = 'AndyAPort@gmail.com'
|
AUTHOR_EMAIL = 'AndyAPort@gmail.com'
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ points given by their standard representation."""
|
||||||
|
|
||||||
# External dependencies:
|
# External dependencies:
|
||||||
from __future__ import division, absolute_import, print_function
|
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 math import factorial as fac, ceil, log, sqrt
|
||||||
from numpy import poly1d
|
from numpy import poly1d
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ aren't specific to SVGs or related mathematical objects."""
|
||||||
|
|
||||||
# External dependencies:
|
# External dependencies:
|
||||||
from __future__ import division, absolute_import, print_function
|
from __future__ import division, absolute_import, print_function
|
||||||
|
from builtins import range
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
|
|
@ -4,6 +4,10 @@ Arc."""
|
||||||
|
|
||||||
# External dependencies
|
# External dependencies
|
||||||
from __future__ import division, absolute_import, print_function
|
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 math import sqrt, cos, sin, acos, degrees, radians, log, pi
|
||||||
from cmath import exp, sqrt as csqrt, phase
|
from cmath import exp, sqrt as csqrt, phase
|
||||||
from collections import MutableSequence
|
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.
|
if curve is a Path object, then seg is a segment in curve.
|
||||||
error - used to compute lengths of cubics and arcs
|
error - used to compute lengths of cubics and arcs
|
||||||
min_depth - 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)
|
curve_length = curve.length(error=error, min_depth=min_depth)
|
||||||
assert curve_length > 0
|
assert curve_length > 0
|
||||||
|
@ -1514,7 +1519,7 @@ class Arc(object):
|
||||||
u1poly_mag2 = real(u1poly)**2 + imag(u1poly)**2
|
u1poly_mag2 = real(u1poly)**2 + imag(u1poly)**2
|
||||||
t2s = polyroots01(u1poly_mag2 - 1)
|
t2s = polyroots01(u1poly_mag2 - 1)
|
||||||
t1s = [self.phase2t(phase(u1poly(t2))) for t2 in t2s]
|
t1s = [self.phase2t(phase(u1poly(t2))) for t2 in t2s]
|
||||||
return zip(t1s, t2s)
|
return list(zip(t1s, t2s))
|
||||||
elif isinstance(other_seg, Arc):
|
elif isinstance(other_seg, Arc):
|
||||||
assert other_seg != self
|
assert other_seg != self
|
||||||
# This could be made explicit to increase efficiency
|
# 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
|
"""returns a bounding box for the input Path object in the form
|
||||||
(xmin, xmax, ymin, ymax)."""
|
(xmin, xmax, ymin, ymax)."""
|
||||||
bbs = [seg.bbox() for seg in self._segments]
|
bbs = [seg.bbox() for seg in self._segments]
|
||||||
xmins, xmaxs, ymins, ymaxs = zip(*bbs)
|
xmins, xmaxs, ymins, ymaxs = list(zip(*bbs))
|
||||||
xmin = min(xmins)
|
xmin = min(xmins)
|
||||||
xmax = max(xmaxs)
|
xmax = max(xmaxs)
|
||||||
ymin = min(ymins)
|
ymin = min(ymins)
|
||||||
|
|
|
@ -3,6 +3,8 @@ segments."""
|
||||||
|
|
||||||
# External dependencies:
|
# External dependencies:
|
||||||
from __future__ import division, absolute_import, print_function
|
from __future__ import division, absolute_import, print_function
|
||||||
|
from builtins import zip
|
||||||
|
from builtins import str
|
||||||
from math import ceil
|
from math import ceil
|
||||||
from os import getcwd, path as os_path, makedirs
|
from os import getcwd, path as os_path, makedirs
|
||||||
from xml.dom.minidom import parse as md_xml_parse
|
from xml.dom.minidom import parse as md_xml_parse
|
||||||
|
@ -74,7 +76,7 @@ def big_bounding_box(paths_n_stuff):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"paths_n_stuff can only contains Path, CubicBezier, "
|
"paths_n_stuff can only contains Path, CubicBezier, "
|
||||||
"QuadraticBezier, Line, and complex objects.")
|
"QuadraticBezier, Line, and complex objects.")
|
||||||
xmins, xmaxs, ymins, ymaxs = zip(*bbs)
|
xmins, xmaxs, ymins, ymaxs = list(zip(*bbs))
|
||||||
xmin = min(xmins)
|
xmin = min(xmins)
|
||||||
xmax = max(xmaxs)
|
xmax = max(xmaxs)
|
||||||
ymin = min(ymins)
|
ymin = min(ymins)
|
||||||
|
|
|
@ -5,6 +5,7 @@ curves."""
|
||||||
from __future__ import division, absolute_import, print_function
|
from __future__ import division, absolute_import, print_function
|
||||||
|
|
||||||
# Internal Dependencies
|
# Internal Dependencies
|
||||||
|
from builtins import range
|
||||||
from .path import Path, CubicBezier, Line
|
from .path import Path, CubicBezier, Line
|
||||||
from .misctools import isclose
|
from .misctools import isclose
|
||||||
from .paths2svg import disvg
|
from .paths2svg import disvg
|
||||||
|
|
|
@ -3,6 +3,7 @@ The main tool being the svg2paths() function."""
|
||||||
|
|
||||||
# External dependencies
|
# External dependencies
|
||||||
from __future__ import division, absolute_import, print_function
|
from __future__ import division, absolute_import, print_function
|
||||||
|
from builtins import zip
|
||||||
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
|
from shutil import copyfile
|
||||||
|
@ -64,9 +65,9 @@ def svg2paths(svg_file_location,
|
||||||
|
|
||||||
def dom2dict(element):
|
def dom2dict(element):
|
||||||
"""Converts DOM elements to dictionaries of attributes."""
|
"""Converts DOM elements to dictionaries of attributes."""
|
||||||
keys = element.attributes.keys()
|
keys = list(element.attributes.keys())
|
||||||
values = [val.value for val in element.attributes.values()]
|
values = [val.value for val in list(element.attributes.values())]
|
||||||
return dict(zip(keys, values))
|
return dict(list(zip(keys, values)))
|
||||||
|
|
||||||
# Use minidom to extract path strings from input SVG
|
# Use minidom to extract path strings from input SVG
|
||||||
paths = [dom2dict(el) for el in doc.getElementsByTagName('path')]
|
paths = [dom2dict(el) for el in doc.getElementsByTagName('path')]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from __future__ import division, absolute_import, print_function
|
from __future__ import division, absolute_import, print_function
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from builtins import range
|
||||||
import unittest
|
import unittest
|
||||||
from svgpathtools.bezier import *
|
from svgpathtools.bezier import *
|
||||||
from svgpathtools.path import bpoints2bezier
|
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)
|
# 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 __future__ import division, absolute_import, print_function
|
||||||
|
from builtins import zip
|
||||||
import unittest
|
import unittest
|
||||||
from svgpathtools import *
|
from svgpathtools import *
|
||||||
|
|
||||||
|
|
||||||
class TestGeneration(unittest.TestCase):
|
class TestGeneration(unittest.TestCase):
|
||||||
|
|
||||||
def test_svg_examples(self):
|
def test_path_parsing(self):
|
||||||
"""Examples from the SVG spec"""
|
"""Examples from the SVG spec"""
|
||||||
paths = [
|
paths = [
|
||||||
'M 100,100 L 300,100 L 200,300 Z',
|
'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 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',
|
'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 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 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',
|
'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 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 -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 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):
|
for path, flpath in zip(paths[::-1], float_paths[::-1]):
|
||||||
self.assertTrue(parse_path(path).d() in (path, pathsf[k]))
|
# 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):
|
def test_normalizing(self):
|
||||||
# Relative paths will be made absolute, subpaths merged if they can,
|
# 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'
|
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'
|
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))
|
self.assertTrue(parse_path(path).d() in (ps, psf))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
# External dependencies
|
# External dependencies
|
||||||
from __future__ import division, absolute_import, print_function
|
from __future__ import division, absolute_import, print_function
|
||||||
|
from builtins import zip
|
||||||
|
from builtins import str
|
||||||
import unittest
|
import unittest
|
||||||
from math import sqrt, pi
|
from math import sqrt, pi
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
@ -661,11 +663,11 @@ class TestPath(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class Test_ilength(unittest.TestCase):
|
class Test_ilength(unittest.TestCase):
|
||||||
def test_ilength(self):
|
# See svgpathtools.notes.inv_arclength.py for information on how these
|
||||||
# See svgpathtools.notes.inv_arclength.py for information on how these
|
# test values were generated (using the .length() method).
|
||||||
# test values were generated (using the .length() method).
|
##############################################################
|
||||||
##############################################################
|
|
||||||
# Lines
|
def test_ilength_lines(self):
|
||||||
l = Line(1, 3-1j)
|
l = Line(1, 3-1j)
|
||||||
nodall = Line(1+1j, 1+1j)
|
nodall = Line(1+1j, 1+1j)
|
||||||
|
|
||||||
|
@ -678,8 +680,7 @@ class Test_ilength(unittest.TestCase):
|
||||||
for (l, t, s) in tests:
|
for (l, t, s) in tests:
|
||||||
self.assertAlmostEqual(l.ilength(s), t)
|
self.assertAlmostEqual(l.ilength(s), t)
|
||||||
|
|
||||||
###############################################################
|
def test_ilength_quadratics(self):
|
||||||
# Quadratics
|
|
||||||
q1 = QuadraticBezier(200 + 300j, 400 + 50j, 600 + 300j)
|
q1 = QuadraticBezier(200 + 300j, 400 + 50j, 600 + 300j)
|
||||||
q2 = QuadraticBezier(200 + 300j, 400 + 50j, 500 + 200j)
|
q2 = QuadraticBezier(200 + 300j, 400 + 50j, 500 + 200j)
|
||||||
closedq = QuadraticBezier(6 + 2j, 5 - 1j, 6 + 2j)
|
closedq = QuadraticBezier(6 + 2j, 5 - 1j, 6 + 2j)
|
||||||
|
@ -716,8 +717,7 @@ class Test_ilength(unittest.TestCase):
|
||||||
print(t)
|
print(t)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
###############################################################
|
def test_ilength_cubics(self):
|
||||||
# Cubics
|
|
||||||
c1 = CubicBezier(200 + 300j, 400 + 50j, 600+100j, -200)
|
c1 = CubicBezier(200 + 300j, 400 + 50j, 600+100j, -200)
|
||||||
symc = CubicBezier(1-2j, 10-1j, 10+1j, 1+2j)
|
symc = CubicBezier(1-2j, 10-1j, 10+1j, 1+2j)
|
||||||
closedc = 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:
|
for (c, t, s) in tests:
|
||||||
self.assertAlmostEqual(c.ilength(s), t)
|
self.assertAlmostEqual(c.ilength(s), t)
|
||||||
|
|
||||||
###############################################################
|
def test_ilength_arcs(self):
|
||||||
# Arcs
|
|
||||||
arc1 = Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j)
|
arc1 = Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j)
|
||||||
arc2 = Arc(0j, 100 + 50j, 0, 1, 0, 100 + 50j)
|
arc2 = Arc(0j, 100 + 50j, 0, 1, 0, 100 + 50j)
|
||||||
arc3 = Arc(0j, 100 + 50j, 0, 0, 1, 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:
|
for (c, t, s) in tests:
|
||||||
self.assertAlmostEqual(c.ilength(s), t)
|
self.assertAlmostEqual(c.ilength(s), t)
|
||||||
|
|
||||||
###############################################################
|
def test_ilength_paths(self):
|
||||||
# Paths
|
|
||||||
line1 = Line(600 + 350j, 650 + 325j)
|
line1 = Line(600 + 350j, 650 + 325j)
|
||||||
arc1 = Arc(650 + 325j, 25 + 25j, -30, 0, 1, 700 + 300j)
|
arc1 = Arc(650 + 325j, 25 + 25j, -30, 0, 1, 700 + 300j)
|
||||||
cub1 = CubicBezier(650 + 325j, 25 + 25j, -30, 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)]
|
(apath, 1.0, 87.81018330500885)]
|
||||||
|
|
||||||
for (c, t, s) in tests:
|
for (c, t, s) in tests:
|
||||||
self.assertAlmostEqual(c.ilength(s), t)
|
self.assertAlmostEqual(c.ilength(s), t, msg=str((c, t, s)))
|
||||||
|
|
||||||
###############################################################
|
# Exceptional Cases
|
||||||
# Exception Cases
|
def test_ilength_exceptions(self):
|
||||||
nodalq = QuadraticBezier(1, 1, 1)
|
nodalq = QuadraticBezier(1, 1, 1)
|
||||||
with self.assertRaises(AssertionError):
|
with self.assertRaises(AssertionError):
|
||||||
nodalq.ilength(1)
|
nodalq.ilength(1)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# External dependencies
|
# External dependencies
|
||||||
from __future__ import division, absolute_import, print_function
|
from __future__ import division, absolute_import, print_function
|
||||||
|
from builtins import range
|
||||||
import unittest
|
import unittest
|
||||||
from numpy import poly1d
|
from numpy import poly1d
|
||||||
|
|
||||||
|
@ -57,11 +58,11 @@ class TestPathTools(unittest.TestCase):
|
||||||
# Input poly1d object
|
# Input poly1d object
|
||||||
bez = poly2bez(p)
|
bez = poly2bez(p)
|
||||||
bpoints = bez.bpoints()
|
bpoints = bez.bpoints()
|
||||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||||
|
|
||||||
# Input list of coefficients
|
# Input list of coefficients
|
||||||
bpoints = poly2bez(pcoeffs, return_bpoints=True)
|
bpoints = poly2bez(pcoeffs, return_bpoints=True)
|
||||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||||
|
|
||||||
# Case: Quadratic
|
# Case: Quadratic
|
||||||
pcoeffs = [(29.5+15.5j), (-31-19j), (7.5+5.5j)]
|
pcoeffs = [(29.5+15.5j), (-31-19j), (7.5+5.5j)]
|
||||||
|
@ -71,11 +72,11 @@ class TestPathTools(unittest.TestCase):
|
||||||
# Input poly1d object
|
# Input poly1d object
|
||||||
bez = poly2bez(p)
|
bez = poly2bez(p)
|
||||||
bpoints = bez.bpoints()
|
bpoints = bez.bpoints()
|
||||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||||
|
|
||||||
# Input list of coefficients
|
# Input list of coefficients
|
||||||
bpoints = poly2bez(pcoeffs, return_bpoints=True)
|
bpoints = poly2bez(pcoeffs, return_bpoints=True)
|
||||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||||
|
|
||||||
# Case: Cubic
|
# Case: Cubic
|
||||||
pcoeffs = [(-18.5-12.5j), (34.5+16.5j), (-18-6j), (6+2j)]
|
pcoeffs = [(-18.5-12.5j), (34.5+16.5j), (-18-6j), (6+2j)]
|
||||||
|
@ -85,11 +86,11 @@ class TestPathTools(unittest.TestCase):
|
||||||
# Input poly1d object
|
# Input poly1d object
|
||||||
bez = poly2bez(p)
|
bez = poly2bez(p)
|
||||||
bpoints = bez.bpoints()
|
bpoints = bez.bpoints()
|
||||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||||
|
|
||||||
# Input list of coefficients object
|
# Input list of coefficients object
|
||||||
bpoints = poly2bez(pcoeffs, return_bpoints=True)
|
bpoints = poly2bez(pcoeffs, return_bpoints=True)
|
||||||
self.assertAlmostEquals(distfcn(bpoints, correct_bpoints), 0)
|
self.assertAlmostEqual(distfcn(bpoints, correct_bpoints), 0)
|
||||||
|
|
||||||
def test_bpoints2bezier(self):
|
def test_bpoints2bezier(self):
|
||||||
cubic_bpoints = [(6+2j), 0, (5.5+3.5j), (4+0j)]
|
cubic_bpoints = [(6+2j), 0, (5.5+3.5j), (4+0j)]
|
||||||
|
|
Loading…
Reference in New Issue