sketchingpy.bezier_util

Utility to build bezier curves.

License:

BSD

 1"""Utility to build bezier curves.
 2
 3License:
 4    BSD
 5"""
 6import typing
 7
 8
 9class BezierMaker:
10    """Builds points along a bezier curve of arbitrary degree."""
11
12    def __init__(self):
13        """Create a new curve with no points."""
14        self._points: typing.List[typing.Tuple[float, float]] = []
15
16    def add_point(self, x: float, y: float):
17        """Add a point to this curve.
18
19        Add a point to this curve. If it is the first or last point, it is start and destination
20        respectively. Otherwise, it is a control point.
21
22        Args:
23            x: The x position of the point.
24            y: The y position of the point.
25        """
26        self._points.append((x, y))
27
28    def get_points(self, num_points: int) -> typing.List[typing.Tuple[float, float]]:
29        """Get a series of points within the curve.
30
31        Args:
32            num_points: The number of points to return.
33
34        Returns:
35            List of coordinates along curve.
36        """
37        if len(self._points) == 0:
38            raise RuntimeError('Curve without points.')
39
40        input_point_ids = range(0, num_points)
41        input_fracs = map(lambda x: x / (num_points - 1.0), input_point_ids)
42        return [self._evaluate(frac) for frac in input_fracs]
43
44    def _evaluate(self, t: float) -> typing.Tuple[float, float]:
45        """Evaluate the bezier curve at a single parameter value.
46
47        Uses the De Casteljau algorithm, repeatedly interpolating between
48        neighboring points until a single point remains. Works for a curve of
49        any degree (any number of control points).
50
51        Args:
52            t: Parameter along the curve from 0 (start) to 1 (destination).
53
54        Returns:
55            The (x, y) coordinate on the curve at t.
56        """
57        current = self._points
58        while len(current) > 1:
59            current = [
60                (
61                    (1 - t) * current[i][0] + t * current[i + 1][0],
62                    (1 - t) * current[i][1] + t * current[i + 1][1]
63                )
64                for i in range(len(current) - 1)
65            ]
66
67        return (float(current[0][0]), float(current[0][1]))
class BezierMaker:
10class BezierMaker:
11    """Builds points along a bezier curve of arbitrary degree."""
12
13    def __init__(self):
14        """Create a new curve with no points."""
15        self._points: typing.List[typing.Tuple[float, float]] = []
16
17    def add_point(self, x: float, y: float):
18        """Add a point to this curve.
19
20        Add a point to this curve. If it is the first or last point, it is start and destination
21        respectively. Otherwise, it is a control point.
22
23        Args:
24            x: The x position of the point.
25            y: The y position of the point.
26        """
27        self._points.append((x, y))
28
29    def get_points(self, num_points: int) -> typing.List[typing.Tuple[float, float]]:
30        """Get a series of points within the curve.
31
32        Args:
33            num_points: The number of points to return.
34
35        Returns:
36            List of coordinates along curve.
37        """
38        if len(self._points) == 0:
39            raise RuntimeError('Curve without points.')
40
41        input_point_ids = range(0, num_points)
42        input_fracs = map(lambda x: x / (num_points - 1.0), input_point_ids)
43        return [self._evaluate(frac) for frac in input_fracs]
44
45    def _evaluate(self, t: float) -> typing.Tuple[float, float]:
46        """Evaluate the bezier curve at a single parameter value.
47
48        Uses the De Casteljau algorithm, repeatedly interpolating between
49        neighboring points until a single point remains. Works for a curve of
50        any degree (any number of control points).
51
52        Args:
53            t: Parameter along the curve from 0 (start) to 1 (destination).
54
55        Returns:
56            The (x, y) coordinate on the curve at t.
57        """
58        current = self._points
59        while len(current) > 1:
60            current = [
61                (
62                    (1 - t) * current[i][0] + t * current[i + 1][0],
63                    (1 - t) * current[i][1] + t * current[i + 1][1]
64                )
65                for i in range(len(current) - 1)
66            ]
67
68        return (float(current[0][0]), float(current[0][1]))

Builds points along a bezier curve of arbitrary degree.

BezierMaker()
13    def __init__(self):
14        """Create a new curve with no points."""
15        self._points: typing.List[typing.Tuple[float, float]] = []

Create a new curve with no points.

def add_point(self, x: float, y: float):
17    def add_point(self, x: float, y: float):
18        """Add a point to this curve.
19
20        Add a point to this curve. If it is the first or last point, it is start and destination
21        respectively. Otherwise, it is a control point.
22
23        Args:
24            x: The x position of the point.
25            y: The y position of the point.
26        """
27        self._points.append((x, y))

Add a point to this curve.

Add a point to this curve. If it is the first or last point, it is start and destination respectively. Otherwise, it is a control point.

Arguments:
  • x: The x position of the point.
  • y: The y position of the point.
def get_points(self, num_points: int) -> List[Tuple[float, float]]:
29    def get_points(self, num_points: int) -> typing.List[typing.Tuple[float, float]]:
30        """Get a series of points within the curve.
31
32        Args:
33            num_points: The number of points to return.
34
35        Returns:
36            List of coordinates along curve.
37        """
38        if len(self._points) == 0:
39            raise RuntimeError('Curve without points.')
40
41        input_point_ids = range(0, num_points)
42        input_fracs = map(lambda x: x / (num_points - 1.0), input_point_ids)
43        return [self._evaluate(frac) for frac in input_fracs]

Get a series of points within the curve.

Arguments:
  • num_points: The number of points to return.
Returns:

List of coordinates along curve.