|
1 | 1 | from . import LinearRegression |
2 | 2 |
|
| 3 | +linear_min_r2 = 0.9 |
| 4 | + |
3 | 5 |
|
4 | 6 | class Curve: |
5 | 7 | def __init__(self, start, end, cb): |
| 8 | + """Takes complex numbers for start, end, and list of 4 Bezier control points""" |
6 | 9 | super(Curve, self).__init__() |
7 | 10 | self.start = start |
8 | 11 | self.end = end |
| 12 | + assert cb is None or len(cb) == 4 |
9 | 13 | self.cb = cb |
10 | 14 |
|
11 | 15 | def __str__(self): |
12 | 16 | control = "[" + (str(self.cb) if self.cb is not None else "None") + "]" |
13 | 17 | return str(self.start) + ", " + control + ", " + str(self.end) |
14 | 18 |
|
15 | 19 | @staticmethod |
16 | | - def is_linear(points): |
| 20 | + def is_linear(points, threshold=linear_min_r2): |
| 21 | + """ |
| 22 | + Returns a boolean indicating whether a list of complex points is linear. |
| 23 | +
|
| 24 | + Takes a list of complex points and optional minimum R**2 threshold for linear regression. |
| 25 | + """ |
17 | 26 | r2 = LinearRegression.coefficients(points)[2] |
18 | | - return r2 > 0.9 |
| 27 | + return r2 > threshold |
19 | 28 |
|
20 | 29 | def cubic_bezier_coordinates(self, t): |
21 | | - x = Curve.cubic_bezier( |
22 | | - [self.cb[0].real, self.cb[1].real, self.cb[2].real, self.cb[3].real], t |
23 | | - ) |
24 | | - y = Curve.cubic_bezier( |
25 | | - [self.cb[0].imag, self.cb[1].imag, self.cb[2].imag, self.cb[3].imag], t |
26 | | - ) |
| 30 | + """ |
| 31 | + Returns a complex number representing the point along the cubic bezier curve. |
| 32 | +
|
| 33 | + Takes parametric parameter t where 0 <= t <= 1 |
| 34 | + """ |
| 35 | + x = Curve._cubic_bezier(self._cb("real"), t) |
| 36 | + y = Curve._cubic_bezier(self._cb("imag"), t) |
27 | 37 | return complex(x, y) |
28 | 38 |
|
| 39 | + def _cb(self, prop): |
| 40 | + return [getattr(x, prop) for x in self.cb] |
| 41 | + |
29 | 42 | @staticmethod |
30 | | - def cubic_bezier(p, t): |
| 43 | + def _cubic_bezier(p, t): |
| 44 | + """ |
| 45 | + Returns a float representing the point along the cubic bezier curve in the given dimension. |
| 46 | +
|
| 47 | + Takes ordered list of 4 control points [P0, P1, P2, P3] and parametric parameter t where 0 <= t <= 1 |
| 48 | +
|
| 49 | + implements explicit form of https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B%C3%A9zier_curves |
| 50 | + """ |
| 51 | + assert 0 <= t <= 1 |
31 | 52 | return ( |
32 | 53 | (((1.0 - t) ** 3) * p[0]) |
33 | | - + (3 * t * ((1.0 - t) ** 2) * p[1]) |
| 54 | + + (3.0 * t * ((1.0 - t) ** 2) * p[1]) |
34 | 55 | + (3.0 * (t ** 2) * (1.0 - t) * p[2]) |
35 | 56 | + ((t ** 3) * p[3]) |
36 | 57 | ) |
0 commit comments