def fitBezier(pts,tangent0=None,tangent3=None):
    if len(pts < 4):
        pts = subdivideLineSegment(pts)
    T = [np.linalg.norm(pts[i]-pts[i-1]) for i in range(1,len(pts))]
    tsum = np.sum(T)
    T = [0] + T
    T = [np.sum(T[0:i+1])/tsum for i in range(len(pts))]
    T = [[t**3, t**2, t, 1] for t in T]
    T = np.array(T)
    M = np.array([[-1,  3, -3, 1],
                  [ 3, -6,  3, 0],
                  [-3,  3,  0, 0],
                  [ 1,  0,  0, 0]])
    T = T.dot(M)
    n = len(pts)
    pout = pts.copy()
    pout[:,0] -= (T[:,0] * pts[0,0]) + (T[:,3] * pts[-1,0])
    pout[:,1] -= (T[:,0] * pts[0,1]) + (T[:,3] * pts[-1,1])

    TT = np.zeros((n*2,4))
    for i in range(n):
        for j in range(2):
            TT[i*2,j*2] = T[i,j+1]
            TT[i*2+1,j*2+1] = T[i,j+1]
    pout = pout.reshape((n*2,1),order="C")

    if tangent0 != None and tangent3 != None:
        tangentConstraintsT = np.array([
                [tangent0[1], -tangent0[0], 0, 0],
                [0, 0, tangent3[1], -tangent3[0]]
            ])
        tangentConstraintsP = np.array([
                                [pts[0][1]  * -tangent0[0] + pts[0][0]  * tangent0[1]],
                                [pts[-1][1] * -tangent3[0] + pts[-1][0] * tangent3[1]]
                            ])
        TT = np.concatenate((TT, tangentConstraintsT * 1000))
        pout = np.concatenate((pout, tangentConstraintsP * 1000))
    C = np.linalg.lstsq(TT,pout)[0].reshape((2,2))
    return np.array([pts[0], C[0], C[1], pts[-1]])
dataset/ETHPy150Open google/roboto/scripts/lib/fontbuild/curveFitPen.py/fitBezier/original