| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkGeometry.h" | 8 #include "SkGeometry.h" |
| 9 #include "SkMatrix.h" | 9 #include "SkMatrix.h" |
| 10 #include "SkNx.h" | 10 #include "SkNx.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 SkScalar A = src[4] - 2 * src[2] + C; | 123 SkScalar A = src[4] - 2 * src[2] + C; |
| 124 SkScalar B = 2 * (src[2] - C); | 124 SkScalar B = 2 * (src[2] - C); |
| 125 return SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C); | 125 return SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C); |
| 126 #else | 126 #else |
| 127 SkScalar ab = SkScalarInterp(src[0], src[2], t); | 127 SkScalar ab = SkScalarInterp(src[0], src[2], t); |
| 128 SkScalar bc = SkScalarInterp(src[2], src[4], t); | 128 SkScalar bc = SkScalarInterp(src[2], src[4], t); |
| 129 return SkScalarInterp(ab, bc, t); | 129 return SkScalarInterp(ab, bc, t); |
| 130 #endif | 130 #endif |
| 131 } | 131 } |
| 132 | 132 |
| 133 static SkScalar eval_quad_derivative(const SkScalar src[], SkScalar t) { | |
| 134 SkScalar A = src[4] - 2 * src[2] + src[0]; | |
| 135 SkScalar B = src[2] - src[0]; | |
| 136 | |
| 137 return 2 * SkScalarMulAdd(A, t, B); | |
| 138 } | |
| 139 | |
| 140 void SkQuadToCoeff(const SkPoint pts[3], SkPoint coeff[3]) { | 133 void SkQuadToCoeff(const SkPoint pts[3], SkPoint coeff[3]) { |
| 141 Sk2s p0 = from_point(pts[0]); | 134 Sk2s p0 = from_point(pts[0]); |
| 142 Sk2s p1 = from_point(pts[1]); | 135 Sk2s p1 = from_point(pts[1]); |
| 143 Sk2s p2 = from_point(pts[2]); | 136 Sk2s p2 = from_point(pts[2]); |
| 144 | 137 |
| 145 Sk2s p1minus2 = p1 - p0; | 138 Sk2s p1minus2 = p1 - p0; |
| 146 | 139 |
| 147 coeff[0] = to_point(p2 - p1 - p1 + p0); // A * t^2 | 140 coeff[0] = to_point(p2 - p1 - p1 + p0); // A * t^2 |
| 148 coeff[1] = to_point(p1minus2 + p1minus2); // B * t | 141 coeff[1] = to_point(p1minus2 + p1minus2); // B * t |
| 149 coeff[2] = pts[0]; // C | 142 coeff[2] = pts[0]; // C |
| 150 } | 143 } |
| 151 | 144 |
| 152 void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tange
nt) { | 145 void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tange
nt) { |
| 153 SkASSERT(src); | 146 SkASSERT(src); |
| 154 SkASSERT(t >= 0 && t <= SK_Scalar1); | 147 SkASSERT(t >= 0 && t <= SK_Scalar1); |
| 155 | 148 |
| 156 if (pt) { | 149 if (pt) { |
| 157 pt->set(eval_quad(&src[0].fX, t), eval_quad(&src[0].fY, t)); | 150 pt->set(eval_quad(&src[0].fX, t), eval_quad(&src[0].fY, t)); |
| 158 } | 151 } |
| 159 if (tangent) { | 152 if (tangent) { |
| 160 tangent->set(eval_quad_derivative(&src[0].fX, t), | 153 *tangent = SkEvalQuadTangentAt(src, t); |
| 161 eval_quad_derivative(&src[0].fY, t)); | |
| 162 } | 154 } |
| 163 } | 155 } |
| 164 | 156 |
| 165 SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t) { | 157 SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t) { |
| 166 SkASSERT(src); | 158 SkASSERT(src); |
| 167 SkASSERT(t >= 0 && t <= SK_Scalar1); | 159 SkASSERT(t >= 0 && t <= SK_Scalar1); |
| 168 | 160 |
| 169 const Sk2s t2(t); | 161 const Sk2s t2(t); |
| 170 | 162 |
| 171 Sk2s P0 = from_point(src[0]); | 163 Sk2s P0 = from_point(src[0]); |
| 172 Sk2s P1 = from_point(src[1]); | 164 Sk2s P1 = from_point(src[1]); |
| 173 Sk2s P2 = from_point(src[2]); | 165 Sk2s P2 = from_point(src[2]); |
| 174 | 166 |
| 175 Sk2s B = P1 - P0; | 167 Sk2s B = P1 - P0; |
| 176 Sk2s A = P2 - P1 - B; | 168 Sk2s A = P2 - P1 - B; |
| 177 | 169 |
| 178 return to_point((A * t2 + B+B) * t2 + P0); | 170 return to_point((A * t2 + B+B) * t2 + P0); |
| 179 } | 171 } |
| 180 | 172 |
| 181 SkVector SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t) { | 173 SkVector SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t) { |
| 174 // The derivative equation is 2(b - a +(a - 2b +c)t). This returns a |
| 175 // zero tangent vector when t is 0 or 1, and the control point is equal |
| 176 // to the end point. In this case, use the quad end points to compute the ta
ngent. |
| 177 if ((t == 0 && src[0] == src[1]) || (t == 1 && src[1] == src[2])) { |
| 178 return src[2] - src[0]; |
| 179 } |
| 182 SkASSERT(src); | 180 SkASSERT(src); |
| 183 SkASSERT(t >= 0 && t <= SK_Scalar1); | 181 SkASSERT(t >= 0 && t <= SK_Scalar1); |
| 184 | 182 |
| 185 Sk2s P0 = from_point(src[0]); | 183 Sk2s P0 = from_point(src[0]); |
| 186 Sk2s P1 = from_point(src[1]); | 184 Sk2s P1 = from_point(src[1]); |
| 187 Sk2s P2 = from_point(src[2]); | 185 Sk2s P2 = from_point(src[2]); |
| 188 | 186 |
| 189 Sk2s B = P1 - P0; | 187 Sk2s B = P1 - P0; |
| 190 Sk2s A = P2 - P1 - B; | 188 Sk2s A = P2 - P1 - B; |
| 191 Sk2s T = A * Sk2s(t) + B; | 189 Sk2s T = A * Sk2s(t) + B; |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 | 389 |
| 392 void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* loc, | 390 void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* loc, |
| 393 SkVector* tangent, SkVector* curvature) { | 391 SkVector* tangent, SkVector* curvature) { |
| 394 SkASSERT(src); | 392 SkASSERT(src); |
| 395 SkASSERT(t >= 0 && t <= SK_Scalar1); | 393 SkASSERT(t >= 0 && t <= SK_Scalar1); |
| 396 | 394 |
| 397 if (loc) { | 395 if (loc) { |
| 398 loc->set(eval_cubic(&src[0].fX, t), eval_cubic(&src[0].fY, t)); | 396 loc->set(eval_cubic(&src[0].fX, t), eval_cubic(&src[0].fY, t)); |
| 399 } | 397 } |
| 400 if (tangent) { | 398 if (tangent) { |
| 401 tangent->set(eval_cubic_derivative(&src[0].fX, t), | 399 // The derivative equation returns a zero tangent vector when t is 0 or
1, and the |
| 402 eval_cubic_derivative(&src[0].fY, t)); | 400 // adjacent control point is equal to the end point. In this case, use t
he |
| 401 // next control point or the end points to compute the tangent. |
| 402 if ((t == 0 && src[0] == src[1]) || (t == 1 && src[2] == src[3])) { |
| 403 if (t == 0) { |
| 404 *tangent = src[2] - src[0]; |
| 405 } else { |
| 406 *tangent = src[3] - src[1]; |
| 407 } |
| 408 if (!tangent->fX && !tangent->fY) { |
| 409 *tangent = src[3] - src[0]; |
| 410 } |
| 411 } else { |
| 412 tangent->set(eval_cubic_derivative(&src[0].fX, t), |
| 413 eval_cubic_derivative(&src[0].fY, t)); |
| 414 } |
| 403 } | 415 } |
| 404 if (curvature) { | 416 if (curvature) { |
| 405 curvature->set(eval_cubic_2ndDerivative(&src[0].fX, t), | 417 curvature->set(eval_cubic_2ndDerivative(&src[0].fX, t), |
| 406 eval_cubic_2ndDerivative(&src[0].fY, t)); | 418 eval_cubic_2ndDerivative(&src[0].fY, t)); |
| 407 } | 419 } |
| 408 } | 420 } |
| 409 | 421 |
| 410 /** Cubic'(t) = At^2 + Bt + C, where | 422 /** Cubic'(t) = At^2 + Bt + C, where |
| 411 A = 3(-a + 3(b - c) + d) | 423 A = 3(-a + 3(b - c) + d) |
| 412 B = 6(a - 2b + c) | 424 B = 6(a - 2b + c) |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 SkScalar w, | 1181 SkScalar w, |
| 1170 SkScalar coeff[3]) { | 1182 SkScalar coeff[3]) { |
| 1171 const SkScalar P20 = src[4] - src[0]; | 1183 const SkScalar P20 = src[4] - src[0]; |
| 1172 const SkScalar P10 = src[2] - src[0]; | 1184 const SkScalar P10 = src[2] - src[0]; |
| 1173 const SkScalar wP10 = w * P10; | 1185 const SkScalar wP10 = w * P10; |
| 1174 coeff[0] = w * P20 - P20; | 1186 coeff[0] = w * P20 - P20; |
| 1175 coeff[1] = P20 - 2 * wP10; | 1187 coeff[1] = P20 - 2 * wP10; |
| 1176 coeff[2] = wP10; | 1188 coeff[2] = wP10; |
| 1177 } | 1189 } |
| 1178 | 1190 |
| 1179 static SkScalar conic_eval_tan(const SkScalar coord[], SkScalar w, SkScalar t) { | |
| 1180 SkScalar coeff[3]; | |
| 1181 conic_deriv_coeff(coord, w, coeff); | |
| 1182 return t * (t * coeff[0] + coeff[1]) + coeff[2]; | |
| 1183 } | |
| 1184 | |
| 1185 static bool conic_find_extrema(const SkScalar src[], SkScalar w, SkScalar* t) { | 1191 static bool conic_find_extrema(const SkScalar src[], SkScalar w, SkScalar* t) { |
| 1186 SkScalar coeff[3]; | 1192 SkScalar coeff[3]; |
| 1187 conic_deriv_coeff(src, w, coeff); | 1193 conic_deriv_coeff(src, w, coeff); |
| 1188 | 1194 |
| 1189 SkScalar tValues[2]; | 1195 SkScalar tValues[2]; |
| 1190 int roots = SkFindUnitQuadRoots(coeff[0], coeff[1], coeff[2], tValues); | 1196 int roots = SkFindUnitQuadRoots(coeff[0], coeff[1], coeff[2], tValues); |
| 1191 SkASSERT(0 == roots || 1 == roots); | 1197 SkASSERT(0 == roots || 1 == roots); |
| 1192 | 1198 |
| 1193 if (1 == roots) { | 1199 if (1 == roots) { |
| 1194 *t = tValues[0]; | 1200 *t = tValues[0]; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1225 } | 1231 } |
| 1226 | 1232 |
| 1227 void SkConic::evalAt(SkScalar t, SkPoint* pt, SkVector* tangent) const { | 1233 void SkConic::evalAt(SkScalar t, SkPoint* pt, SkVector* tangent) const { |
| 1228 SkASSERT(t >= 0 && t <= SK_Scalar1); | 1234 SkASSERT(t >= 0 && t <= SK_Scalar1); |
| 1229 | 1235 |
| 1230 if (pt) { | 1236 if (pt) { |
| 1231 pt->set(conic_eval_pos(&fPts[0].fX, fW, t), | 1237 pt->set(conic_eval_pos(&fPts[0].fX, fW, t), |
| 1232 conic_eval_pos(&fPts[0].fY, fW, t)); | 1238 conic_eval_pos(&fPts[0].fY, fW, t)); |
| 1233 } | 1239 } |
| 1234 if (tangent) { | 1240 if (tangent) { |
| 1235 tangent->set(conic_eval_tan(&fPts[0].fX, fW, t), | 1241 *tangent = evalTangentAt(t); |
| 1236 conic_eval_tan(&fPts[0].fY, fW, t)); | |
| 1237 } | 1242 } |
| 1238 } | 1243 } |
| 1239 | 1244 |
| 1240 void SkConic::chopAt(SkScalar t, SkConic dst[2]) const { | 1245 void SkConic::chopAt(SkScalar t, SkConic dst[2]) const { |
| 1241 SkP3D tmp[3], tmp2[3]; | 1246 SkP3D tmp[3], tmp2[3]; |
| 1242 | 1247 |
| 1243 ratquad_mapTo3D(fPts, fW, tmp); | 1248 ratquad_mapTo3D(fPts, fW, tmp); |
| 1244 | 1249 |
| 1245 p3d_interp(&tmp[0].fX, &tmp2[0].fX, t); | 1250 p3d_interp(&tmp[0].fX, &tmp2[0].fX, t); |
| 1246 p3d_interp(&tmp[0].fY, &tmp2[0].fY, t); | 1251 p3d_interp(&tmp[0].fY, &tmp2[0].fY, t); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1284 Sk2s numer = quad_poly_eval(A, B, C, tt); | 1289 Sk2s numer = quad_poly_eval(A, B, C, tt); |
| 1285 | 1290 |
| 1286 B = times_2(ww - one); | 1291 B = times_2(ww - one); |
| 1287 A = Sk2s(0)-B; | 1292 A = Sk2s(0)-B; |
| 1288 Sk2s denom = quad_poly_eval(A, B, one, tt); | 1293 Sk2s denom = quad_poly_eval(A, B, one, tt); |
| 1289 | 1294 |
| 1290 return to_point(numer / denom); | 1295 return to_point(numer / denom); |
| 1291 } | 1296 } |
| 1292 | 1297 |
| 1293 SkVector SkConic::evalTangentAt(SkScalar t) const { | 1298 SkVector SkConic::evalTangentAt(SkScalar t) const { |
| 1299 // The derivative equation returns a zero tangent vector when t is 0 or 1, |
| 1300 // and the control point is equal to the end point. |
| 1301 // In this case, use the conic endpoints to compute the tangent. |
| 1302 if ((t == 0 && fPts[0] == fPts[1]) || (t == 1 && fPts[1] == fPts[2])) { |
| 1303 return fPts[2] - fPts[0]; |
| 1304 } |
| 1294 Sk2s p0 = from_point(fPts[0]); | 1305 Sk2s p0 = from_point(fPts[0]); |
| 1295 Sk2s p1 = from_point(fPts[1]); | 1306 Sk2s p1 = from_point(fPts[1]); |
| 1296 Sk2s p2 = from_point(fPts[2]); | 1307 Sk2s p2 = from_point(fPts[2]); |
| 1297 Sk2s ww(fW); | 1308 Sk2s ww(fW); |
| 1298 | 1309 |
| 1299 Sk2s p20 = p2 - p0; | 1310 Sk2s p20 = p2 - p0; |
| 1300 Sk2s p10 = p1 - p0; | 1311 Sk2s p10 = p1 - p0; |
| 1301 | 1312 |
| 1302 Sk2s C = ww * p10; | 1313 Sk2s C = ww * p10; |
| 1303 Sk2s A = ww * p20 - p20; | 1314 Sk2s A = ww * p20 - p20; |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 matrix.preScale(SK_Scalar1, -SK_Scalar1); | 1590 matrix.preScale(SK_Scalar1, -SK_Scalar1); |
| 1580 } | 1591 } |
| 1581 if (userMatrix) { | 1592 if (userMatrix) { |
| 1582 matrix.postConcat(*userMatrix); | 1593 matrix.postConcat(*userMatrix); |
| 1583 } | 1594 } |
| 1584 for (int i = 0; i < conicCount; ++i) { | 1595 for (int i = 0; i < conicCount; ++i) { |
| 1585 matrix.mapPoints(dst[i].fPts, 3); | 1596 matrix.mapPoints(dst[i].fPts, 3); |
| 1586 } | 1597 } |
| 1587 return conicCount; | 1598 return conicCount; |
| 1588 } | 1599 } |
| OLD | NEW |