Index: src/core/SkGeometry.cpp |
diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp |
index 11d52b594e303495a73523090f30d33a01216679..f07ca2a10190fe99591c682d92a4fc6b31af1e7f 100644 |
--- a/src/core/SkGeometry.cpp |
+++ b/src/core/SkGeometry.cpp |
@@ -799,8 +799,6 @@ template <typename T> void bubble_sort(T array[], int count) |
} |
} |
-#include "SkFP.h" |
- |
// newton refinement |
#if 0 |
static SkScalar refine_cubic_root(const SkFP coeff[4], SkScalar root) |
@@ -897,6 +895,10 @@ static void test_collaps_duplicates() { |
#pragma warning ( disable : 4702 ) |
#endif |
+static SkScalar SkScalarCubeRoot(SkScalar x) { |
+ return sk_float_pow(x, 0.3333333f); |
+} |
caryclark
2013/12/16 13:39:31
Here's what I came up with for float in my experim
|
+ |
/* Solve coeff(t) == 0, returning the number of roots that |
lie withing 0 < t < 1. |
coeff[0]t^3 + coeff[1]t^2 + coeff[2]t + coeff[3] |
@@ -904,44 +906,35 @@ static void test_collaps_duplicates() { |
Eliminates repeated roots (so that all tValues are distinct, and are always |
in increasing order. |
*/ |
-static int solve_cubic_polynomial(const SkFP coeff[4], SkScalar tValues[3]) |
+static int solve_cubic_polynomial(const SkScalar coeff[4], SkScalar tValues[3]) |
{ |
-#ifndef SK_SCALAR_IS_FLOAT |
- return 0; // this is not yet implemented for software float |
-#endif |
- |
if (SkScalarNearlyZero(coeff[0])) // we're just a quadratic |
{ |
return SkFindUnitQuadRoots(coeff[1], coeff[2], coeff[3], tValues); |
} |
- SkFP a, b, c, Q, R; |
+ SkScalar a, b, c, Q, R; |
{ |
SkASSERT(coeff[0] != 0); |
- SkFP inva = SkFPInvert(coeff[0]); |
- a = SkFPMul(coeff[1], inva); |
- b = SkFPMul(coeff[2], inva); |
- c = SkFPMul(coeff[3], inva); |
+ SkScalar inva = SkScalarInvert(coeff[0]); |
+ a = coeff[1] * inva; |
+ b = coeff[2] * inva; |
+ c = coeff[3] * inva; |
} |
- Q = SkFPDivInt(SkFPSub(SkFPMul(a,a), SkFPMulInt(b, 3)), 9); |
-// R = (2*a*a*a - 9*a*b + 27*c) / 54; |
- R = SkFPMulInt(SkFPMul(SkFPMul(a, a), a), 2); |
- R = SkFPSub(R, SkFPMulInt(SkFPMul(a, b), 9)); |
- R = SkFPAdd(R, SkFPMulInt(c, 27)); |
- R = SkFPDivInt(R, 54); |
+ Q = (a*a - b*3) / 9; |
+ R = (2*a*a*a - 9*a*b + 27*c) / 54; |
- SkFP Q3 = SkFPMul(SkFPMul(Q, Q), Q); |
- SkFP R2MinusQ3 = SkFPSub(SkFPMul(R,R), Q3); |
- SkFP adiv3 = SkFPDivInt(a, 3); |
+ SkScalar Q3 = Q * Q * Q; |
+ SkScalar R2MinusQ3 = R * R - Q3; |
+ SkScalar adiv3 = a / 3; |
SkScalar* roots = tValues; |
SkScalar r; |
- if (SkFPLT(R2MinusQ3, 0)) // we have 3 real roots |
+ if (R2MinusQ3 < 0) // we have 3 real roots |
{ |
-#ifdef SK_SCALAR_IS_FLOAT |
float theta = sk_float_acos(R / sk_float_sqrt(Q3)); |
float neg2RootQ = -2 * sk_float_sqrt(Q); |
@@ -965,18 +958,17 @@ static int solve_cubic_polynomial(const SkFP coeff[4], SkScalar tValues[3]) |
bubble_sort(tValues, count); |
count = collaps_duplicates(tValues, count); |
roots = tValues + count; // so we compute the proper count below |
-#endif |
} |
else // we have 1 real root |
{ |
- SkFP A = SkFPAdd(SkFPAbs(R), SkFPSqrt(R2MinusQ3)); |
- A = SkFPCubeRoot(A); |
- if (SkFPGT(R, 0)) |
- A = SkFPNeg(A); |
+ SkScalar A = SkScalarAbs(R) + SkScalarSqrt(R2MinusQ3); |
+ A = SkScalarCubeRoot(A); |
+ if (R > 0) |
+ A = -A; |
if (A != 0) |
- A = SkFPAdd(A, SkFPDiv(Q, A)); |
- r = SkFPToScalar(SkFPSub(A, adiv3)); |
+ A += Q / A; |
+ r = A - adiv3; |
if (is_unit_interval(r)) |
*roots++ = r; |
} |
@@ -995,21 +987,16 @@ static int solve_cubic_polynomial(const SkFP coeff[4], SkScalar tValues[3]) |
F' dot F'' -> CCt^3 + 3BCt^2 + (2BB + CA)t + AB |
*/ |
-static void formulate_F1DotF2(const SkScalar src[], SkFP coeff[4]) |
+static void formulate_F1DotF2(const SkScalar src[], SkScalar coeff[4]) |
{ |
SkScalar a = src[2] - src[0]; |
SkScalar b = src[4] - 2 * src[2] + src[0]; |
SkScalar c = src[6] + 3 * (src[2] - src[4]) - src[0]; |
- SkFP A = SkScalarToFP(a); |
- SkFP B = SkScalarToFP(b); |
- SkFP C = SkScalarToFP(c); |
- |
- coeff[0] = SkFPMul(C, C); |
- coeff[1] = SkFPMulInt(SkFPMul(B, C), 3); |
- coeff[2] = SkFPMulInt(SkFPMul(B, B), 2); |
- coeff[2] = SkFPAdd(coeff[2], SkFPMul(C, A)); |
- coeff[3] = SkFPMul(A, B); |
+ coeff[0] = c * c; |
+ coeff[1] = 3 * b * c; |
+ coeff[2] = 2 * b * b + c * a; |
+ coeff[3] = a * b; |
} |
// EXPERIMENTAL: can set this to zero to accept all t-values 0 < t < 1 |
@@ -1029,14 +1016,14 @@ static void formulate_F1DotF2(const SkScalar src[], SkFP coeff[4]) |
*/ |
int SkFindCubicMaxCurvature(const SkPoint src[4], SkScalar tValues[3]) |
{ |
- SkFP coeffX[4], coeffY[4]; |
- int i; |
+ SkScalar coeffX[4], coeffY[4]; |
+ int i; |
formulate_F1DotF2(&src[0].fX, coeffX); |
formulate_F1DotF2(&src[0].fY, coeffY); |
for (i = 0; i < 4; i++) |
- coeffX[i] = SkFPAdd(coeffX[i],coeffY[i]); |
+ coeffX[i] += coeffY[i]; |
SkScalar t[3]; |
int count = solve_cubic_polynomial(coeffX, t); |