fixed higher order Bezier to polynomial conversion
parent
0cf57d4276
commit
f697a91190
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue