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 |
11 // for abs | 11 // for abs |
12 #include <cmath> | 12 #include <cmath> |
13 | 13 |
14 #define UNIMPLEMENTED SkDEBUGF(("%s:%d unimplemented\n", __FILE__, __LINE__)) | 14 #define UNIMPLEMENTED SkDEBUGF(("%s:%d unimplemented\n", __FILE__, __LINE__)) |
caryclark
2016/08/15 19:13:04
Make this an assert.
Harry Stern
2016/08/15 20:55:16
Done, depends on https://codereview.chromium.org/2
| |
15 | 15 |
16 /// Used inside SkCurveMeasure::getTime's Newton's iteration | 16 /// Used inside SkCurveMeasure::getTime's Newton's iteration |
17 static inline SkPoint evaluate(const SkPoint pts[4], SkSegType segType, | 17 static inline SkPoint evaluate(const SkPoint pts[4], SkSegType segType, |
18 SkScalar t) { | 18 SkScalar t) { |
19 SkPoint pos; | 19 SkPoint pos; |
20 switch (segType) { | 20 switch (segType) { |
21 case kQuad_SegType: | 21 case kQuad_SegType: |
22 pos = SkEvalQuadAt(pts, t); | 22 pos = SkEvalQuadAt(pts, t); |
23 break; | 23 break; |
24 case kLine_SegType: | 24 case kLine_SegType: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
62 default: | 62 default: |
63 UNIMPLEMENTED; | 63 UNIMPLEMENTED; |
64 } | 64 } |
65 | 65 |
66 return tan; | 66 return tan; |
67 } | 67 } |
68 /// Used in ArcLengthIntegrator::computeLength | 68 /// Used in ArcLengthIntegrator::computeLength |
69 static inline Sk8f evaluateDerivativeLength(const Sk8f& ts, | 69 static inline Sk8f evaluateDerivativeLength(const Sk8f& ts, |
70 const Sk8f (&xCoeff)[3], | 70 const Sk8f (&xCoeff)[3], |
71 const Sk8f (&yCoeff)[3], | 71 const Sk8f (&yCoeff)[3], |
72 const SkScalar w, | |
72 const SkSegType segType) { | 73 const SkSegType segType) { |
73 Sk8f x; | 74 Sk8f x; |
74 Sk8f y; | 75 Sk8f y; |
75 switch (segType) { | 76 switch (segType) { |
76 case kQuad_SegType: | 77 case kQuad_SegType: |
77 x = xCoeff[0]*ts + xCoeff[1]; | 78 x = xCoeff[0]*ts + xCoeff[1]; |
78 y = yCoeff[0]*ts + yCoeff[1]; | 79 y = yCoeff[0]*ts + yCoeff[1]; |
79 break; | 80 break; |
80 case kCubic_SegType: | 81 case kCubic_SegType: |
81 x = (xCoeff[0]*ts + xCoeff[1])*ts + xCoeff[2]; | 82 x = (xCoeff[0]*ts + xCoeff[1])*ts + xCoeff[2]; |
82 y = (yCoeff[0]*ts + yCoeff[1])*ts + yCoeff[2]; | 83 y = (yCoeff[0]*ts + yCoeff[1])*ts + yCoeff[2]; |
83 break; | 84 break; |
84 case kConic_SegType: | 85 case kConic_SegType: { |
85 UNIMPLEMENTED; | 86 Sk8f xnum = (xCoeff[0]*ts + xCoeff[1])*ts + xCoeff[2]; |
87 Sk8f ynum = (yCoeff[0]*ts + yCoeff[1])*ts + yCoeff[2]; | |
88 | |
89 Sk8f denom = ts*(-4 + 4*w + ts*(8 - 12*w + 4*w*w + ts*(-8 + 16*w - | |
90 8*w*w + ts*(4 - 8*w + 4*w*w)))) + 1; | |
caryclark
2016/08/15 19:13:04
Where did this come from? That is, please document
Harry Stern
2016/08/15 20:55:16
I took out those terms. I honestly didn't notice t
Harry Stern
2016/08/17 02:48:46
Also, I have added the mathematica commands used t
| |
91 | |
92 x = xnum / denom; | |
93 y = ynum / denom; | |
caryclark
2016/08/15 19:13:04
Is there a unit test for this?
Harry Stern
2016/08/15 20:55:16
It's on my todo by tomorrow.
| |
94 } | |
86 break; | 95 break; |
87 default: | 96 default: |
88 UNIMPLEMENTED; | 97 UNIMPLEMENTED; |
89 } | 98 } |
90 | 99 |
91 x = x * x; | 100 x = x * x; |
92 y = y * y; | 101 y = y * y; |
93 | 102 |
94 return (x + y).sqrt(); | 103 return (x + y).sqrt(); |
95 } | 104 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 // precompute coefficients for derivative | 136 // precompute coefficients for derivative |
128 xCoeff[0] = Sk8f(3.0f*(-Ax + 3.0f*(Bx - Cx) + Dx)); | 137 xCoeff[0] = Sk8f(3.0f*(-Ax + 3.0f*(Bx - Cx) + Dx)); |
129 xCoeff[1] = Sk8f(3.0f*(2.0f*(Ax - 2.0f*Bx + Cx))); | 138 xCoeff[1] = Sk8f(3.0f*(2.0f*(Ax - 2.0f*Bx + Cx))); |
130 xCoeff[2] = Sk8f(3.0f*(-Ax + Bx)); | 139 xCoeff[2] = Sk8f(3.0f*(-Ax + Bx)); |
131 | 140 |
132 yCoeff[0] = Sk8f(3.0f*(-Ay + 3.0f*(By - Cy) + Dy)); | 141 yCoeff[0] = Sk8f(3.0f*(-Ay + 3.0f*(By - Cy) + Dy)); |
133 yCoeff[1] = Sk8f(3.0f*(2.0f*(Ay - 2.0f*By + Cy))); | 142 yCoeff[1] = Sk8f(3.0f*(2.0f*(Ay - 2.0f*By + Cy))); |
134 yCoeff[2] = Sk8f(3.0f*(-Ay + By)); | 143 yCoeff[2] = Sk8f(3.0f*(-Ay + By)); |
135 } | 144 } |
136 break; | 145 break; |
137 case kConic_SegType: | 146 case kConic_SegType: { |
138 UNIMPLEMENTED; | 147 float Ax = pts[0].x(); |
148 float Bx = pts[1].x(); | |
149 float Cx = pts[2].x(); | |
150 float Ay = pts[0].y(); | |
151 float By = pts[1].y(); | |
152 float Cy = pts[2].y(); | |
153 | |
154 fConicW = pts[3].x(); | |
Harry Stern
2016/08/15 18:01:21
fConicW gets set here
| |
155 | |
156 SkScalar w = fConicW; | |
157 | |
158 // precompute coefficients for derivative | |
159 xCoeff[0] = Sk8f(2*(Ax - Cx - Ax*w + Cx*w)); | |
160 xCoeff[1] = Sk8f(-2*(Ax + Cx + 2*(Ax*w - Bx*w))); | |
161 xCoeff[2] = Sk8f(-2*(Ax*w + Bx*w)); | |
162 | |
163 yCoeff[0] = Sk8f(2*(Ay - Cy - Ay*w + Cy*w)); | |
164 yCoeff[1] = Sk8f(-2*(Ay + Cy + 2*(Ay*w - By*w))); | |
165 yCoeff[2] = Sk8f(-2*(Ay*w + By*w)); | |
166 } | |
139 break; | 167 break; |
140 default: | 168 default: |
141 UNIMPLEMENTED; | 169 UNIMPLEMENTED; |
142 } | 170 } |
143 } | 171 } |
144 | 172 |
145 // We use Gaussian quadrature | 173 // We use Gaussian quadrature |
146 // (https://en.wikipedia.org/wiki/Gaussian_quadrature) | 174 // (https://en.wikipedia.org/wiki/Gaussian_quadrature) |
147 // to approximate the arc length integral here, because it is amenable to SIMD. | 175 // to approximate the arc length integral here, because it is amenable to SIMD. |
148 SkScalar ArcLengthIntegrator::computeLength(SkScalar t) { | 176 SkScalar ArcLengthIntegrator::computeLength(SkScalar t) { |
149 SkScalar length = 0.0f; | 177 SkScalar length = 0.0f; |
150 | 178 |
151 Sk8f lengths = evaluateDerivativeLength(absc*t, xCoeff, yCoeff, fSegType); | 179 Sk8f lengths = evaluateDerivativeLength(absc*t, xCoeff, yCoeff, fConicW, fSe gType); |
152 lengths = weights*lengths; | 180 lengths = weights*lengths; |
153 // is it faster or more accurate to sum and then multiply or vice versa? | 181 // is it faster or more accurate to sum and then multiply or vice versa? |
154 lengths = lengths*(t*0.5f); | 182 lengths = lengths*(t*0.5f); |
155 | 183 |
156 // Why does SkNx index with ints? does negative index mean something? | 184 // Why does SkNx index with ints? does negative index mean something? |
157 for (int i = 0; i < 8; i++) { | 185 for (int i = 0; i < 8; i++) { |
158 length += lengths[i]; | 186 length += lengths[i]; |
159 } | 187 } |
160 return length; | 188 return length; |
161 } | 189 } |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
301 if (time) { | 329 if (time) { |
302 *time = t; | 330 *time = t; |
303 } | 331 } |
304 if (pos) { | 332 if (pos) { |
305 *pos = evaluate(fPts, fSegType, t); | 333 *pos = evaluate(fPts, fSegType, t); |
306 } | 334 } |
307 if (tan) { | 335 if (tan) { |
308 *tan = evaluateDerivative(fPts, fSegType, t); | 336 *tan = evaluateDerivative(fPts, fSegType, t); |
309 } | 337 } |
310 } | 338 } |
OLD | NEW |