| 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 |