Kevin L
Initial commit
5fd3fc6
Raw History Blame Contribute Delete
2.94 kB
from __future__ import absolute_import, division
import numpy as np
from scipy.special import comb
def bezier_curve(points, nb_points=1000):
""" Given a list of points compute a bezier curve from it.
# Arguments
points: ndarray. Array of points with shape (N, 2) with N being the
number of points and the second dimension representing the
(x, y) coordinates.
nb_points: Integer. Number of points to sample from the bezier curve.
This value must be larger than the number of points given in
`points`. Maximum value 10000.
# Returns
ndarray: Array of shape (1000, 2) with the bezier curve of the
given path of points.
"""
nb_points = min(nb_points, 1000)
points = np.asarray(points, dtype=np.float)
if points.ndim != 2 or points.shape[1] != 2:
raise ValueError(
'`points` should be two dimensional and have shape: (N, 2)')
n_points = len(points)
if n_points > nb_points:
# We are downsampling points
return points
t = np.linspace(0., 1., nb_points).reshape(1, -1)
# Compute the Bernstein polynomial of n, i as a function of t
i = np.arange(n_points).reshape(-1, 1)
n = n_points - 1
polynomial_array = comb(n, i) * (t**(n - i)) * (1 - t)**i
bezier_curve_points = polynomial_array.T.dot(points)
return bezier_curve_points
def bresenham(points):
""" Apply Bresenham algorithm for a list points.
More info: https://en.wikipedia.org/wiki/Bresenham's_line_algorithm
# Arguments
points: ndarray. Array of points with shape (N, 2) with N being the number
if points and the second coordinate representing the (x, y)
coordinates.
# Returns
ndarray: Array of points after having applied the bresenham algorithm.
"""
points = np.asarray(points, dtype=np.int)
def line(x0, y0, x1, y1):
""" Bresenham line algorithm.
"""
d_x = x1 - x0
d_y = y1 - y0
x_sign = 1 if d_x > 0 else -1
y_sign = 1 if d_y > 0 else -1
d_x = np.abs(d_x)
d_y = np.abs(d_y)
if d_x > d_y:
xx, xy, yx, yy = x_sign, 0, 0, y_sign
else:
d_x, d_y = d_y, d_x
xx, xy, yx, yy = 0, y_sign, x_sign, 0
D = 2 * d_y - d_x
y = 0
line = np.empty((d_x + 1, 2), dtype=points.dtype)
for x in range(d_x + 1):
line[x] = [x0 + x * xx + y * yx, y0 + x * xy + y * yy]
if D >= 0:
y += 1
D -= 2 * d_x
D += 2 * d_y
return line
nb_points = len(points)
if nb_points < 2:
return points
new_points = []
for i in range(nb_points - 1):
p = points[i:i + 2].ravel().tolist()
new_points.append(line(*p))
new_points = np.concatenate(new_points, axis=0)
return new_points