fixed higher order Bezier to polynomial conversion

pull/12/merge
Andy 2017-02-28 20:41:35 -08:00
parent 0cf57d4276
commit f697a91190
2 changed files with 61 additions and 23 deletions

View File

@ -83,12 +83,13 @@ def bezier2polynomial(p, numpy_ordering=True, return_poly1d=False):
coeffs = p coeffs = p
else: else:
# https://en.wikipedia.org/wiki/Bezier_curve#Polynomial_form # https://en.wikipedia.org/wiki/Bezier_curve#Polynomial_form
n = len(p) + 1 n = len(p) - 1
coeffs = [fac(n)//fac(n-j) * sum( coeffs = [fac(n)//fac(n-j) * sum(
(-1)**(i+j) * p[i] / (fac(i) * fac(j-i)) for i in xrange(j+1)) (-1)**(i+j) * p[i] / (fac(i) * fac(j-i)) for i in range(j+1))
for j in range(n+1)] for j in range(n+1)]
if not numpy_ordering:
coeffs.reverse() coeffs.reverse()
if not numpy_ordering:
coeffs = coeffs[::-1] # can't use .reverse() as might be tuple
if return_poly1d: if return_poly1d:
return poly1d(coeffs) return poly1d(coeffs)
return coeffs return coeffs

View File

@ -1,21 +1,58 @@
from __future__ import division, absolute_import, print_function from __future__ import division, absolute_import, print_function
# import unittest import numpy as np
# try: import unittest
# from ..bezier import * from svgpathtools.bezier import *
# except ValueError: from svgpathtools.path import bpoints2bezier
# from svgpathtools.bezier import *
#
# class HigherOrderBezier:
# class Test_bezier(unittest.TestCase): def __init__(self, bpoints):
# def test_bernstein(self): self.bpts = bpoints
# self.fail()
# def bpoints(self):
# def test_bezier_point(self): return self.bpts
# self.fail()
# def point(self, t):
# def test_split_bezier(self): return bezier_point(self.bpoints(), t)
# self.fail()
# def __repr__(self):
# return str(self.bpts)
# if __name__ == '__main__':
# unittest.main()
def random_polynomial(degree):
return np.poly1d(np.random.rand(degree + 1))
def random_bezier(degree):
if degree <= 3:
return bpoints2bezier(polynomial2bezier(np.random.rand(degree + 1)))
else:
return HigherOrderBezier(np.random.rand(degree + 1))
class TestBezier2Polynomial(unittest.TestCase):
def test_bezier2polynomial(self):
tvals = np.linspace(0, 1, 10)
for d in range(1, 10):
b = random_bezier(d)
p = np.poly1d(bezier2polynomial(b.bpoints()))
for t in tvals:
msg = ("degree {}\nt = {}\nb(t) = {}\n = {}\np(t) = \n{}\n = {}"
"".format(d, t, b, b.point(t), p, p(t)))
self.assertAlmostEqual(b.point(t), p(t), msg=msg)
class TestPolynomial2Bezier(unittest.TestCase):
def test_polynomial2bezier(self):
tvals = np.linspace(0, 1, 10)
for d in range(1, 3):
p = random_polynomial(d)
b = HigherOrderBezier(polynomial2bezier(p))
for t in tvals:
msg = ("degree {}\nt = {}\nb(t) = {}\n = {}\np(t) = \n{}\n = {}"
"".format(d, t, b, b.point(t), p, p(t)))
self.assertAlmostEqual(b.point(t), p(t), msg=msg)
if __name__ == '__main__':
unittest.main()