Hong-Phuc Bui
9 days ago e2c0c968eecec4a90ea5a432e1db1ba4a50df93e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
""""
Module related to bezier curve
"""
def make_cubic_bezier(control_points: [(float, float)], n: int = 10) -> [(float, float)]:
    r""""
    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