OLD | NEW |
| (Empty) |
1 | |
2 /* | |
3 * Copyright 2011 Google Inc. | |
4 * | |
5 * Use of this source code is governed by a BSD-style license that can be | |
6 * found in the LICENSE file. | |
7 */ | |
8 #include "SkCubicInterval.h" | |
9 | |
10 static SkScalar eval_cubic(SkScalar c1, SkScalar c2, SkScalar c3, | |
11 SkScalar t) { | |
12 return SkScalarMul(SkScalarMul(SkScalarMul(c3, t) + c2, t) + c1, t); | |
13 } | |
14 | |
15 static SkScalar find_cubic_t(SkScalar c1, SkScalar c2, SkScalar c3, | |
16 SkScalar targetX) { | |
17 SkScalar minT = 0; | |
18 SkScalar maxT = SK_Scalar1; | |
19 SkScalar t; | |
20 | |
21 for (;;) { | |
22 t = SkScalarAve(minT, maxT); | |
23 SkScalar x = eval_cubic(c1, c2, c3, t); | |
24 if (SkScalarNearlyZero(x - targetX)) { | |
25 break; | |
26 } | |
27 // subdivide the range and try again | |
28 if (x < targetX) { | |
29 minT = t; | |
30 } else { | |
31 maxT = t; | |
32 } | |
33 } | |
34 return t; | |
35 } | |
36 | |
37 /* | |
38 a(1-t)^3 + 3bt(1-t)^2 + 3ct^2(1-t) + dt^3 | |
39 a: [0, 0] | |
40 d: [1, 1] | |
41 | |
42 3bt - 6bt^2 + 3bt^3 + 3ct^2 - 3ct^3 + t^3 | |
43 C1 = t^1: 3b | |
44 C2 = t^2: 3c - 6b | |
45 C3 = t^3: 3b - 3c + 1 | |
46 | |
47 ((C3*t + C2)*t + C1)*t | |
48 */ | |
49 SkScalar SkEvalCubicInterval(SkScalar x1, SkScalar y1, | |
50 SkScalar x2, SkScalar y2, | |
51 SkScalar unitX) { | |
52 x1 = SkScalarPin(x1, 0, SK_Scalar1); | |
53 x2 = SkScalarPin(x2, 0, SK_Scalar1); | |
54 unitX = SkScalarPin(unitX, 0, SK_Scalar1); | |
55 | |
56 // First compute our coefficients in X | |
57 x1 *= 3; | |
58 x2 *= 3; | |
59 | |
60 // now search for t given unitX | |
61 SkScalar t = find_cubic_t(x1, x2 - 2*x1, x1 - x2 + SK_Scalar1, unitX); | |
62 | |
63 // now evaluate the cubic in Y | |
64 y1 *= 3; | |
65 y2 *= 3; | |
66 return eval_cubic(y1, y2 - 2*y1, y1 - y2 + SK_Scalar1, t); | |
67 } | |
OLD | NEW |