Skip to content

Instantly share code, notes, and snippets.

@carlos-adir
Created July 21, 2023 19:13
Show Gist options
  • Save carlos-adir/7289d97b7faf6392f2551c2bbf05cc13 to your computer and use it in GitHub Desktop.
Save carlos-adir/7289d97b7faf6392f2551c2bbf05cc13 to your computer and use it in GitHub Desktop.
Transforms a polynomial in canonical basis into bezier basis and vice-versa
from typing import Tuple
import sympy as sp
import numpy as np
def Bezier2Canonical(degree: int) -> np.ndarray:
"""
Returns a transformation matrix between the basis
Bezier -> Canonical
"""
matrix = np.zeros((degree+1, degree+1), dtype="object")
matrix = sp.Matrix(matrix)
for i in range(degree+1):
coef0 = sp.binomial(degree, i)
for j in range(degree+1-i):
coef1 = sp.binomial(degree-i, j)
value = coef0 * coef1
matrix[degree-i, i+j] = -value if j%2 else value
matrix = np.array(matrix, dtype="object")
return matrix
def extract_canon_coefs(poly, var: sp.Symbol, degree: int) -> Tuple:
"""
Given a poly like: 1 + 3*x + 4*x^2 + 0*x^3 + 2*x^4 + 0*x^5
Then, this function returns
[1, 3, 4, 0, 2, 0]
For specified degree
"""
coefs = sp.Poly(poly, var).all_coeffs()[::-1]
coefs += [0]*(degree+1-len(coefs))
return tuple(coefs)
if __name__ == "__main__":
degree = 4
bezier2canonical = Bezier2Canonical(degree)
canonical2bezier = sp.Matrix(bezier2canonical).inv()
canonical2bezier = np.array(canonical2bezier, dtype="object")
u = sp.symbols("u", real=True)
expr = -2*u # (1+u**2)**2
can_coefs = extract_canon_coefs(expr, u, degree)
print("can_coefs = ")
print(can_coefs)
bez_coefs = canonical2bezier @ can_coefs
print("bez_coefs = ")
print(bez_coefs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment