""""
|
Module related to bezier curve
|
"""
|
def make_cubic_bezier(control_points: [(float, float)], n: int = 10) -> [(float, float)]:
|
""""
|
Interpolate a Bezier-curve by split it into segments of lines (=polyline).
|
A Bezier-Curve is defined by
|
|
\[
|
B(P_0, P_1, P_2, P_3:t) = (1-t)^3*P_0 + 3(1-t)^2*t*P_1 + 3(1-t)*t^2*P_2 + t^3*P_3
|
\]
|
|
for $t \in \[0, 1\]$
|
|
:param control_points
|
:param n number of segments
|
:return a list of points on the Bezier-Curve.
|
"""
|
|
p0x = control_points[0][0]
|
p0y = control_points[0][1]
|
p1x = control_points[1][0]
|
p1y = control_points[1][1]
|
p2x = control_points[2][0]
|
p2y = control_points[2][1]
|
p3x = control_points[3][0]
|
p3y = control_points[3][1]
|
points = [(p0x, p0y)]
|
for i in range(1, n):
|
t = i / n
|
u = 1 - t
|
x = p0x * u**3 + 3 * p1x * t* u**2 + 3 * p2x * t**2 * u + p3x * t**3
|
y = p0y * u**3 + 3 * p1y * t* u**2 + 3 * p2y * t**2 * u + p3y * t**3
|
points.append( (x,y) )
|
points.append((p3x, p3y))
|
return points
|
|
|
def make_svg_polyline(points) -> str:
|
line = map(lambda p: f"{p[0]},{p[1]}", points)
|
svg = f'<polyline points="{" ".join(line)}" fill="none" stroke="gray" stroke-width="3" />'
|
return svg
|