import numpy as np
from scipy.special import comb
import matplotlib.pyplot as plt
%matplotlib inline
# Use this to click points for Bezier curve
# Might have to run this block twice. (?)
%matplotlib osx
plt.ion()
def B(i, N, t):
val = comb(N,i) * t**i * (1.-t)**(N-i)
return val
tt = np.linspace(0, 1, 100)
N = 7
for i in range(N+1):
plt.plot(tt, B(i, N, tt));
def P(t, X):
'''
xx = P(t, X)
Evaluates a Bezier curve for the points in X.
Inputs:
X is a list (or array) or 2D coords
t is a number (or list of numbers) in [0,1] where you want to
evaluate the Bezier curve
Output:
xx is the set of 2D points along the Bezier curve
'''
X = np.array(X)
N,d = np.shape(X) # Number of points, Dimension of points
N = N - 1
xx = np.zeros((len(t), d))
for i in range(N+1):
xx += np.outer(B(i, N, t), X[i])
return xx
plt.figure(2, figsize=[8,8])
plt.clf()
clickable = False
if clickable:
plt.plot([0,1],[0,1],'w.')
plt.axis('equal');
plt.draw()
c = plt.ginput(20, mouse_stop=2) # on macbook, alt-click to stop
plt.draw()
else:
c = [(0.09374999999999989, 0.15297619047619054),
(0.549107142857143, 0.1648809523809524),
(0.7083333333333335, 0.6142857142857144),
(0.5282738095238095, 0.8940476190476193),
(0.24404761904761907, 0.8776785714285716),
(0.15327380952380942, 0.6321428571428573),
(0.580357142857143, 0.08303571428571432),
(0.8839285714285716, 0.28988095238095246)]
X = np.array(c)
tt = np.linspace(0, 1, 200)
xx = P(tt, X)
plt.plot(xx[:,0], xx[:,1])
plt.plot(X[:,0], X[:,1], 'ro');
def DrawBezier(p, n):
x1 = p[0]
y1 = p[1]
x2 = p[2]
y2 = p[3]
x3 = p[4]
y3 = p[5]
x4 = p[6]
y4 = p[7]
t = np.linspace(0,1,n)
xx = P(t, np.reshape(p, (4,2)))
plt.plot([x1, x4], [y1, y4], 'ro') # knot point
plt.plot([x1, x2], [y1, y2], 'r-') # tangent
plt.plot([x3, x4], [y3, y4], 'r-') # tangent
plt.plot(xx[:,0], xx[:,1], '-') # curve
# 5
p = [[149, 597, 149, 597, 149, 597, 345, 597],
[345, 597, 361, 597, 365, 599, 368, 606],
[368, 606, 406, 695, 368, 606, 406, 695],
[406, 695, 397, 702, 406, 695, 397, 702],
[397, 702, 382, 681, 372, 676, 351, 676],
[351, 676, 351, 676, 142, 676, 142, 676],
[142, 676, 33, 439, 142, 676, 33, 439],
[33, 439, 32, 438, 32, 436, 32, 434],
[32, 434, 32, 428, 35, 426, 44, 426],
[44, 426, 74, 426, 109, 420, 149, 408],
[149, 408, 269, 372, 324, 310, 324, 208],
[324, 208, 324, 112, 264, 37, 185, 37],
[185, 37, 165, 37, 149, 44, 119, 66],
[119, 66, 86, 90, 65, 99, 42, 99],
[42, 99, 14, 99, 0, 87, 0, 62],
[0, 62, 0, 24, 46, 0, 121, 0],
[121, 0, 205, 0, 282, 27, 333, 78],
[333, 78, 378, 123, 399, 180, 399, 256],
[399, 256, 399, 327, 381, 372, 333, 422],
[333, 422, 288, 468, 232, 491, 112, 512],
[112, 512, 112, 512, 149, 597, 149, 597]]
plt.figure(3, figsize=[8,8])
plt.clf()
for segment in p:
DrawBezier(segment, 100)
plt.axis('equal');
# T,
p = [[237, 620, 237, 620, 237, 120, 237, 120],
[237, 120, 237, 35, 226, 24, 143, 19],
[143, 19, 143, 19, 143, 0, 143, 0],
[143, 0, 143, 0, 435, 0, 435, 0],
[435, 0, 435, 0, 435, 19, 435, 19],
[435, 19, 353, 23, 339, 36, 339, 109],
[339, 109, 339, 108, 339, 620, 339, 620],
[339, 620, 339, 620, 393, 620, 393, 620],
[393, 620, 507, 620, 529, 602, 552, 492],
[552, 492, 552, 492, 576, 492, 576, 492],
[576, 492, 576, 492, 570, 662, 570, 662],
[570, 662, 570, 662, 6, 662, 6, 662],
[6, 662, 6, 662, 0, 492, 0, 492],
[0, 492, 0, 492, 24, 492, 24, 492],
[24, 492, 48, 602, 71, 620, 183, 620],
[183, 620, 183, 620, 237, 620, 237, 620]]
plt.figure(3, figsize=[8,8])
plt.clf()
for segment in p:
DrawBezier(segment, 100)
plt.axis('equal');
# f
p = [[289, 452, 289, 452, 166, 452, 166, 452],
[166, 452, 166, 452, 166, 568, 166, 568],
[166, 568, 166, 627, 185, 657, 223, 657],
[223, 657, 245, 657, 258, 647, 276, 618],
[276, 618, 292, 589, 304, 580, 321, 580],
#[321, 580, 345, 580, 363, 598, 363, 621],
[321, 580, 345, 580, 363, 598, 363, 621],
[363, 621, 363, 657, 319, 683, 259, 683],
#[259, 683, 196, 683, 144, 656, 118, 611],
#[118, 611, 92, 566, 84, 530, 83, 450],
[259, 683, 196, 683, 126, 666, 100, 621],
[100, 621, 74, 576, 84, 530, 83, 450],
[ 83, 450, 83, 450, 1, 450, 1, 450],
[ 1, 450, 1, 450, 1, 418, 1, 418],
[ 1, 418, 1, 418, 83, 418, 83, 418],
[ 83, 418, 83, 418, 83, 104, 83, 104],
[ 83, 104, 83, 31, 72, 19, 0, 15],
[ 0, 15, 0, 15, 0, 0, 0, 0],
[ 0, 0, 0, 0, 260, 0, 260, 0],
[260, 0, 260, 0, 260, 15, 260, 15],
[260, 15, 178, 18, 167, 29, 167, 104],
[167, 104, 167, 104, 167, 418, 167, 418],
[167, 418, 167, 418, 289, 418, 289, 418],
[289, 418, 289, 418, 289, 452, 289, 452]]
plt.figure(3, figsize=[8,8])
plt.clf()
for segment in p:
DrawBezier(segment, 100)
idx = 5
plt.plot([p[idx][0], p[idx][-2]], [p[idx][1], p[idx][-1]], 'ko')
plt.axis('equal');
p[idx]
p[idx][2] -= 60
p[idx][3] -= 50
plt.figure(4, figsize=[8,8])
plt.clf()
for segment in p:
DrawBezier(segment, 100)
idx = 5
plt.plot([p[idx][0], p[idx][-2]], [p[idx][1], p[idx][-1]], 'ko')
plt.axis('equal');