| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 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 "SkCurveMeasure.h" | 8 #include "SkCurveMeasure.h" |
| 9 #include "SkGeometry.h" | 9 #include "SkGeometry.h" |
| 10 | 10 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 const Sk8f (&xCoeff)[3], | 70 const Sk8f (&xCoeff)[3], |
| 71 const Sk8f (&yCoeff)[3], | 71 const Sk8f (&yCoeff)[3], |
| 72 const SkSegType segType) { | 72 const SkSegType segType) { |
| 73 Sk8f x; | 73 Sk8f x; |
| 74 Sk8f y; | 74 Sk8f y; |
| 75 switch (segType) { | 75 switch (segType) { |
| 76 case kQuad_SegType: | 76 case kQuad_SegType: |
| 77 x = xCoeff[0]*ts + xCoeff[1]; | 77 x = xCoeff[0]*ts + xCoeff[1]; |
| 78 y = yCoeff[0]*ts + yCoeff[1]; | 78 y = yCoeff[0]*ts + yCoeff[1]; |
| 79 break; | 79 break; |
| 80 case kLine_SegType: | |
| 81 // length of line derivative is constant | |
| 82 // and we precompute it in the constructor | |
| 83 return xCoeff[0]; | |
| 84 case kCubic_SegType: | 80 case kCubic_SegType: |
| 85 x = (xCoeff[0]*ts + xCoeff[1])*ts + xCoeff[2]; | 81 x = (xCoeff[0]*ts + xCoeff[1])*ts + xCoeff[2]; |
| 86 y = (yCoeff[0]*ts + yCoeff[1])*ts + yCoeff[2]; | 82 y = (yCoeff[0]*ts + yCoeff[1])*ts + yCoeff[2]; |
| 87 break; | 83 break; |
| 88 case kConic_SegType: | 84 case kConic_SegType: |
| 89 UNIMPLEMENTED; | 85 UNIMPLEMENTED; |
| 90 break; | 86 break; |
| 91 default: | 87 default: |
| 92 UNIMPLEMENTED; | 88 UNIMPLEMENTED; |
| 93 } | 89 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 110 float Cy = pts[2].y(); | 106 float Cy = pts[2].y(); |
| 111 | 107 |
| 112 // precompute coefficients for derivative | 108 // precompute coefficients for derivative |
| 113 xCoeff[0] = Sk8f(2.0f*(Ax - 2*Bx + Cx)); | 109 xCoeff[0] = Sk8f(2.0f*(Ax - 2*Bx + Cx)); |
| 114 xCoeff[1] = Sk8f(2.0f*(Bx - Ax)); | 110 xCoeff[1] = Sk8f(2.0f*(Bx - Ax)); |
| 115 | 111 |
| 116 yCoeff[0] = Sk8f(2.0f*(Ay - 2*By + Cy)); | 112 yCoeff[0] = Sk8f(2.0f*(Ay - 2*By + Cy)); |
| 117 yCoeff[1] = Sk8f(2.0f*(By - Ay)); | 113 yCoeff[1] = Sk8f(2.0f*(By - Ay)); |
| 118 } | 114 } |
| 119 break; | 115 break; |
| 120 case kLine_SegType: { | |
| 121 // the length of the derivative of a line is constant | |
| 122 // we put in in both coeff arrays for consistency's sake | |
| 123 SkScalar length = (pts[1] - pts[0]).length(); | |
| 124 xCoeff[0] = Sk8f(length); | |
| 125 yCoeff[0] = Sk8f(length); | |
| 126 } | |
| 127 break; | |
| 128 case kCubic_SegType: | 116 case kCubic_SegType: |
| 129 { | 117 { |
| 130 float Ax = pts[0].x(); | 118 float Ax = pts[0].x(); |
| 131 float Bx = pts[1].x(); | 119 float Bx = pts[1].x(); |
| 132 float Cx = pts[2].x(); | 120 float Cx = pts[2].x(); |
| 133 float Dx = pts[3].x(); | 121 float Dx = pts[3].x(); |
| 134 float Ay = pts[0].y(); | 122 float Ay = pts[0].y(); |
| 135 float By = pts[1].y(); | 123 float By = pts[1].y(); |
| 136 float Cy = pts[2].y(); | 124 float Cy = pts[2].y(); |
| 137 float Dy = pts[3].y(); | 125 float Dy = pts[3].y(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 : fSegType(segType) { | 164 : fSegType(segType) { |
| 177 switch (fSegType) { | 165 switch (fSegType) { |
| 178 case SkSegType::kQuad_SegType: | 166 case SkSegType::kQuad_SegType: |
| 179 for (size_t i = 0; i < 3; i++) { | 167 for (size_t i = 0; i < 3; i++) { |
| 180 fPts[i] = pts[i]; | 168 fPts[i] = pts[i]; |
| 181 } | 169 } |
| 182 break; | 170 break; |
| 183 case SkSegType::kLine_SegType: | 171 case SkSegType::kLine_SegType: |
| 184 fPts[0] = pts[0]; | 172 fPts[0] = pts[0]; |
| 185 fPts[1] = pts[1]; | 173 fPts[1] = pts[1]; |
| 174 fLength = (fPts[1] - fPts[0]).length(); |
| 186 break; | 175 break; |
| 187 case SkSegType::kCubic_SegType: | 176 case SkSegType::kCubic_SegType: |
| 188 for (size_t i = 0; i < 4; i++) { | 177 for (size_t i = 0; i < 4; i++) { |
| 189 fPts[i] = pts[i]; | 178 fPts[i] = pts[i]; |
| 190 } | 179 } |
| 191 break; | 180 break; |
| 192 case SkSegType::kConic_SegType: | 181 case SkSegType::kConic_SegType: |
| 193 for (size_t i = 0; i < 4; i++) { | 182 for (size_t i = 0; i < 4; i++) { |
| 194 fPts[i] = pts[i]; | 183 fPts[i] = pts[i]; |
| 195 } | 184 } |
| 196 break; | 185 break; |
| 197 default: | 186 default: |
| 198 UNIMPLEMENTED; | 187 UNIMPLEMENTED; |
| 199 break; | 188 break; |
| 200 } | 189 } |
| 201 fIntegrator = ArcLengthIntegrator(fPts, fSegType); | 190 if (kLine_SegType != segType) { |
| 191 fIntegrator = ArcLengthIntegrator(fPts, fSegType); |
| 192 } |
| 202 } | 193 } |
| 203 | 194 |
| 204 SkScalar SkCurveMeasure::getLength() { | 195 SkScalar SkCurveMeasure::getLength() { |
| 205 if (-1.0f == fLength) { | 196 if (-1.0f == fLength) { |
| 206 fLength = fIntegrator.computeLength(1.0f); | 197 fLength = fIntegrator.computeLength(1.0f); |
| 207 } | 198 } |
| 208 return fLength; | 199 return fLength; |
| 209 } | 200 } |
| 210 | 201 |
| 211 // Given an arc length targetLength, we want to determine what t | 202 // Given an arc length targetLength, we want to determine what t |
| 212 // gives us the corresponding arc length along the curve. | 203 // gives us the corresponding arc length along the curve. |
| 213 // We do this by letting the arc length integral := f(t) and | 204 // We do this by letting the arc length integral := f(t) and |
| 214 // solving for the root of the equation f(t) - targetLength = 0 | 205 // solving for the root of the equation f(t) - targetLength = 0 |
| 215 // using Newton's method and lerp-bisection. | 206 // using Newton's method and lerp-bisection. |
| 216 // The computationally expensive parts are the integral approximation | 207 // The computationally expensive parts are the integral approximation |
| 217 // at each step, and computing the derivative of the arc length integral, | 208 // at each step, and computing the derivative of the arc length integral, |
| 218 // which is equal to the length of the tangent (so we have to do a sqrt). | 209 // which is equal to the length of the tangent (so we have to do a sqrt). |
| 219 | 210 |
| 220 SkScalar SkCurveMeasure::getTime(SkScalar targetLength) { | 211 SkScalar SkCurveMeasure::getTime(SkScalar targetLength) { |
| 221 if (targetLength == 0.0f) { | 212 if (targetLength == 0.0f) { |
| 222 return 0.0f; | 213 return 0.0f; |
| 223 } | 214 } |
| 224 | 215 |
| 225 SkScalar currentLength = getLength(); | 216 SkScalar currentLength = getLength(); |
| 226 | 217 |
| 227 if (SkScalarNearlyEqual(targetLength, currentLength)) { | 218 if (SkScalarNearlyEqual(targetLength, currentLength)) { |
| 228 return 1.0f; | 219 return 1.0f; |
| 229 } | 220 } |
| 221 if (kLine_SegType == fSegType) { |
| 222 return targetLength / currentLength; |
| 223 } |
| 230 | 224 |
| 231 // initial estimate of t is percentage of total length | 225 // initial estimate of t is percentage of total length |
| 232 SkScalar currentT = targetLength / currentLength; | 226 SkScalar currentT = targetLength / currentLength; |
| 233 SkScalar prevT = -1.0f; | 227 SkScalar prevT = -1.0f; |
| 234 SkScalar newT; | 228 SkScalar newT; |
| 235 | 229 |
| 236 SkScalar minT = 0.0f; | 230 SkScalar minT = 0.0f; |
| 237 SkScalar maxT = 1.0f; | 231 SkScalar maxT = 1.0f; |
| 238 | 232 |
| 239 int iterations = 0; | 233 int iterations = 0; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 if (time) { | 301 if (time) { |
| 308 *time = t; | 302 *time = t; |
| 309 } | 303 } |
| 310 if (pos) { | 304 if (pos) { |
| 311 *pos = evaluate(fPts, fSegType, t); | 305 *pos = evaluate(fPts, fSegType, t); |
| 312 } | 306 } |
| 313 if (tan) { | 307 if (tan) { |
| 314 *tan = evaluateDerivative(fPts, fSegType, t); | 308 *tan = evaluateDerivative(fPts, fSegType, t); |
| 315 } | 309 } |
| 316 } | 310 } |
| OLD | NEW |