ベジェ曲線の分割

2019/01/13

Python2.7.8

# -*- coding: utf-8 -*-

def bezier_split(points,t):
    if not 0 < t < 1:
        print('Error bezier_split(): t must be 0<t<1.')
        return

    pn = len(points)
    result = [[],[]]
    result[0] = [[0.0,0.0] for i in range(pn)]
    result[1] = [[0.0,0.0] for i in range(pn)]

    #stでくぎられる点を見つける
    #分割前の P0, Pn が分割後の L0, Rn になる
    result[0][0] = points[0]
    result[1][pn-1] = points[pn-1]

    prev = points
    for i in range(1,pn):
        tmp = [[0.0,0.0] for k in range(pn-i)]
        for j in range(pn-i):
            #tmp[j] - tmp[j+1] の間を st で区切る
            tmp[j][0] = prev[j][0] + (prev[j+1][0]-prev[j][0]) * t
            tmp[j][1] = prev[j][1] + (prev[j+1][1]-prev[j][1]) * t

        result[0][i][0] = tmp[0][0]
        result[0][i][1] = tmp[0][1]
        result[1][pn-i-1][0] = tmp[len(tmp)-1][0]
        result[1][pn-i-1][1] = tmp[len(tmp)-1][1]

        prev = tmp

    return result

def bezier_curve(p0,p1,p2,p3,n=20):
    p0_x,p0_y = p0
    p1_x,p1_y = p1
    p2_x,p2_y = p2
    p3_x,p3_y = p3
    points = []
    for i in range(n+1):
        t = i/float(n)
        p_x = (1-t)**3*p0_x + 3*(1-t)**2*t*p1_x + 3*(1-t)*t**2*p2_x + t**3*p3_x
        p_y = (1-t)**3*p0_y + 3*(1-t)**2*t*p1_y + 3*(1-t)*t**2*p2_y + t**3*p3_y
        points.append([p_x,p_y])
    return points

def main():
    import Tkinter
    window = Tkinter.Tk()
    canvas = Tkinter.Canvas(window,width=300,height=200)
    canvas.pack()

    points = [[20,50],[160,20],[80,190],[290,150]]
    p0,p1 = bezier_split(points,0.5)

    r = 3
    for p in [points,p0,p1]:
        for i in range(4):
            canvas.create_oval(p[i][0]-r,p[i][1]-r,
                               p[i][0]+r,p[i][1]+r)
        canvas.create_line(p[0][0],p[0][1],p[1][0],p[1][1])
        canvas.create_line(p[1][0],p[1][1],p[2][0],p[2][1])
        canvas.create_line(p[2][0],p[2][1],p[3][0],p[3][1])

    #canvas.create_line(bezier_curve(*points)) 
    canvas.create_line(bezier_curve(*p0),fill='red')   
    canvas.create_line(bezier_curve(*p1),fill='blue') 

    window.mainloop()

if __name__ == '__main__':
    main()

C#でベジェ曲線 7:ベジェ曲線の分割 https://pgcity.jp/2010/09/05/141/