ベジェ曲線の分割
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/