OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 #include "SkIntersections.h" | 7 #include "SkIntersections.h" |
8 #include "SkPathOpsLine.h" | 8 #include "SkPathOpsLine.h" |
9 #include "SkPathOpsQuad.h" | 9 #include "SkPathOpsQuad.h" |
10 | 10 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 | 82 |
83 Thus, if the slope of the line tends towards vertical, we use: | 83 Thus, if the slope of the line tends towards vertical, we use: |
84 A = ( (a - 2*b + c) - g'*(d - 2*e + f) ) | 84 A = ( (a - 2*b + c) - g'*(d - 2*e + f) ) |
85 B = 2*(-(a - b ) + g'*(d - e ) ) | 85 B = 2*(-(a - b ) + g'*(d - e ) ) |
86 C = ( (a ) - g'*(d ) - h' ) | 86 C = ( (a ) - g'*(d ) - h' ) |
87 */ | 87 */ |
88 | 88 |
89 | 89 |
90 class LineQuadraticIntersections { | 90 class LineQuadraticIntersections { |
91 public: | 91 public: |
| 92 enum PinTPoint { |
| 93 kPointUninitialized, |
| 94 kPointInitialized |
| 95 }; |
| 96 |
92 LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersectio
ns* i) | 97 LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersectio
ns* i) |
93 : quad(q) | 98 : fQuad(q) |
94 , line(l) | 99 , fLine(l) |
95 , intersections(i) | 100 , fIntersections(i) |
96 , fAllowNear(true) { | 101 , fAllowNear(true) { |
97 } | 102 } |
98 | 103 |
99 void allowNear(bool allow) { | 104 void allowNear(bool allow) { |
100 fAllowNear = allow; | 105 fAllowNear = allow; |
101 } | 106 } |
102 | 107 |
103 int intersectRay(double roots[2]) { | 108 int intersectRay(double roots[2]) { |
104 /* | 109 /* |
105 solve by rotating line+quad so line is horizontal, then finding the root
s | 110 solve by rotating line+quad so line is horizontal, then finding the root
s |
106 set up matrix to rotate quad to x-axis | 111 set up matrix to rotate quad to x-axis |
107 |cos(a) -sin(a)| | 112 |cos(a) -sin(a)| |
108 |sin(a) cos(a)| | 113 |sin(a) cos(a)| |
109 note that cos(a) = A(djacent) / Hypoteneuse | 114 note that cos(a) = A(djacent) / Hypoteneuse |
110 sin(a) = O(pposite) / Hypoteneuse | 115 sin(a) = O(pposite) / Hypoteneuse |
111 since we are computing Ts, we can ignore hypoteneuse, the scale factor: | 116 since we are computing Ts, we can ignore hypoteneuse, the scale factor: |
112 | A -O | | 117 | A -O | |
113 | O A | | 118 | O A | |
114 A = line[1].fX - line[0].fX (adjacent side of the right triangle) | 119 A = line[1].fX - line[0].fX (adjacent side of the right triangle) |
115 O = line[1].fY - line[0].fY (opposite side of the right triangle) | 120 O = line[1].fY - line[0].fY (opposite side of the right triangle) |
116 for each of the three points (e.g. n = 0 to 2) | 121 for each of the three points (e.g. n = 0 to 2) |
117 quad[n].fY' = (quad[n].fY - line[0].fY) * A - (quad[n].fX - line[0].fX)
* O | 122 quad[n].fY' = (quad[n].fY - line[0].fY) * A - (quad[n].fX - line[0].fX)
* O |
118 */ | 123 */ |
119 double adj = line[1].fX - line[0].fX; | 124 double adj = fLine[1].fX - fLine[0].fX; |
120 double opp = line[1].fY - line[0].fY; | 125 double opp = fLine[1].fY - fLine[0].fY; |
121 double r[3]; | 126 double r[3]; |
122 for (int n = 0; n < 3; ++n) { | 127 for (int n = 0; n < 3; ++n) { |
123 r[n] = (quad[n].fY - line[0].fY) * adj - (quad[n].fX - line[0].fX) *
opp; | 128 r[n] = (fQuad[n].fY - fLine[0].fY) * adj - (fQuad[n].fX - fLine[0].f
X) * opp; |
124 } | 129 } |
125 double A = r[2]; | 130 double A = r[2]; |
126 double B = r[1]; | 131 double B = r[1]; |
127 double C = r[0]; | 132 double C = r[0]; |
128 A += C - 2 * B; // A = a - 2*b + c | 133 A += C - 2 * B; // A = a - 2*b + c |
129 B -= C; // B = -(b - c) | 134 B -= C; // B = -(b - c) |
130 return SkDQuad::RootsValidT(A, 2 * B, C, roots); | 135 return SkDQuad::RootsValidT(A, 2 * B, C, roots); |
131 } | 136 } |
132 | 137 |
133 int intersect() { | 138 int intersect() { |
134 addExactEndPoints(); | 139 addExactEndPoints(); |
135 double rootVals[2]; | 140 double rootVals[2]; |
136 int roots = intersectRay(rootVals); | 141 int roots = intersectRay(rootVals); |
137 for (int index = 0; index < roots; ++index) { | 142 for (int index = 0; index < roots; ++index) { |
138 double quadT = rootVals[index]; | 143 double quadT = rootVals[index]; |
139 double lineT = findLineT(quadT); | 144 double lineT = findLineT(quadT); |
140 if (PinTs(&quadT, &lineT)) { | 145 SkDPoint pt; |
141 SkDPoint pt = line.xyAtT(lineT); | 146 if (pinTs(&quadT, &lineT, &pt, kPointUninitialized)) { |
142 intersections->insert(quadT, lineT, pt); | 147 fIntersections->insert(quadT, lineT, pt); |
143 } | 148 } |
144 } | 149 } |
145 if (fAllowNear) { | 150 if (fAllowNear) { |
146 addNearEndPoints(); | 151 addNearEndPoints(); |
147 } | 152 } |
148 return intersections->used(); | 153 return fIntersections->used(); |
149 } | 154 } |
150 | 155 |
151 int horizontalIntersect(double axisIntercept, double roots[2]) { | 156 int horizontalIntersect(double axisIntercept, double roots[2]) { |
152 double D = quad[2].fY; // f | 157 double D = fQuad[2].fY; // f |
153 double E = quad[1].fY; // e | 158 double E = fQuad[1].fY; // e |
154 double F = quad[0].fY; // d | 159 double F = fQuad[0].fY; // d |
155 D += F - 2 * E; // D = d - 2*e + f | 160 D += F - 2 * E; // D = d - 2*e + f |
156 E -= F; // E = -(d - e) | 161 E -= F; // E = -(d - e) |
157 F -= axisIntercept; | 162 F -= axisIntercept; |
158 return SkDQuad::RootsValidT(D, 2 * E, F, roots); | 163 return SkDQuad::RootsValidT(D, 2 * E, F, roots); |
159 } | 164 } |
160 | 165 |
161 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { | 166 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { |
162 addExactHorizontalEndPoints(left, right, axisIntercept); | 167 addExactHorizontalEndPoints(left, right, axisIntercept); |
163 double rootVals[2]; | 168 double rootVals[2]; |
164 int roots = horizontalIntersect(axisIntercept, rootVals); | 169 int roots = horizontalIntersect(axisIntercept, rootVals); |
165 for (int index = 0; index < roots; ++index) { | 170 for (int index = 0; index < roots; ++index) { |
166 double quadT = rootVals[index]; | 171 double quadT = rootVals[index]; |
167 SkDPoint pt = quad.xyAtT(quadT); | 172 SkDPoint pt = fQuad.ptAtT(quadT); |
168 double lineT = (pt.fX - left) / (right - left); | 173 double lineT = (pt.fX - left) / (right - left); |
169 if (PinTs(&quadT, &lineT)) { | 174 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { |
170 intersections->insert(quadT, lineT, pt); | 175 fIntersections->insert(quadT, lineT, pt); |
171 } | 176 } |
172 } | 177 } |
173 if (fAllowNear) { | 178 if (fAllowNear) { |
174 addNearHorizontalEndPoints(left, right, axisIntercept); | 179 addNearHorizontalEndPoints(left, right, axisIntercept); |
175 } | 180 } |
176 if (flipped) { | 181 if (flipped) { |
177 intersections->flip(); | 182 fIntersections->flip(); |
178 } | 183 } |
179 return intersections->used(); | 184 return fIntersections->used(); |
180 } | 185 } |
181 | 186 |
182 int verticalIntersect(double axisIntercept, double roots[2]) { | 187 int verticalIntersect(double axisIntercept, double roots[2]) { |
183 double D = quad[2].fX; // f | 188 double D = fQuad[2].fX; // f |
184 double E = quad[1].fX; // e | 189 double E = fQuad[1].fX; // e |
185 double F = quad[0].fX; // d | 190 double F = fQuad[0].fX; // d |
186 D += F - 2 * E; // D = d - 2*e + f | 191 D += F - 2 * E; // D = d - 2*e + f |
187 E -= F; // E = -(d - e) | 192 E -= F; // E = -(d - e) |
188 F -= axisIntercept; | 193 F -= axisIntercept; |
189 return SkDQuad::RootsValidT(D, 2 * E, F, roots); | 194 return SkDQuad::RootsValidT(D, 2 * E, F, roots); |
190 } | 195 } |
191 | 196 |
192 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { | 197 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { |
193 addExactVerticalEndPoints(top, bottom, axisIntercept); | 198 addExactVerticalEndPoints(top, bottom, axisIntercept); |
194 double rootVals[2]; | 199 double rootVals[2]; |
195 int roots = verticalIntersect(axisIntercept, rootVals); | 200 int roots = verticalIntersect(axisIntercept, rootVals); |
196 for (int index = 0; index < roots; ++index) { | 201 for (int index = 0; index < roots; ++index) { |
197 double quadT = rootVals[index]; | 202 double quadT = rootVals[index]; |
198 SkDPoint pt = quad.xyAtT(quadT); | 203 SkDPoint pt = fQuad.ptAtT(quadT); |
199 double lineT = (pt.fY - top) / (bottom - top); | 204 double lineT = (pt.fY - top) / (bottom - top); |
200 if (PinTs(&quadT, &lineT)) { | 205 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { |
201 intersections->insert(quadT, lineT, pt); | 206 fIntersections->insert(quadT, lineT, pt); |
202 } | 207 } |
203 } | 208 } |
204 if (fAllowNear) { | 209 if (fAllowNear) { |
205 addNearVerticalEndPoints(top, bottom, axisIntercept); | 210 addNearVerticalEndPoints(top, bottom, axisIntercept); |
206 } | 211 } |
207 if (flipped) { | 212 if (flipped) { |
208 intersections->flip(); | 213 fIntersections->flip(); |
209 } | 214 } |
210 return intersections->used(); | 215 return fIntersections->used(); |
211 } | 216 } |
212 | 217 |
213 protected: | 218 protected: |
214 // add endpoints first to get zero and one t values exactly | 219 // add endpoints first to get zero and one t values exactly |
215 void addExactEndPoints() { | 220 void addExactEndPoints() { |
216 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 221 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
217 double lineT = line.exactPoint(quad[qIndex]); | 222 double lineT = fLine.exactPoint(fQuad[qIndex]); |
218 if (lineT < 0) { | 223 if (lineT < 0) { |
219 continue; | 224 continue; |
220 } | 225 } |
221 double quadT = (double) (qIndex >> 1); | 226 double quadT = (double) (qIndex >> 1); |
222 intersections->insert(quadT, lineT, quad[qIndex]); | 227 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
223 } | 228 } |
224 } | 229 } |
225 | 230 |
226 void addNearEndPoints() { | 231 void addNearEndPoints() { |
227 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 232 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
228 double quadT = (double) (qIndex >> 1); | 233 double quadT = (double) (qIndex >> 1); |
229 if (intersections->hasT(quadT)) { | 234 if (fIntersections->hasT(quadT)) { |
230 continue; | 235 continue; |
231 } | 236 } |
232 double lineT = line.nearPoint(quad[qIndex]); | 237 double lineT = fLine.nearPoint(fQuad[qIndex]); |
233 if (lineT < 0) { | 238 if (lineT < 0) { |
234 continue; | 239 continue; |
235 } | 240 } |
236 intersections->insert(quadT, lineT, quad[qIndex]); | 241 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
237 } | 242 } |
238 // FIXME: see if line end is nearly on quad | 243 // FIXME: see if line end is nearly on quad |
239 } | 244 } |
240 | 245 |
241 void addExactHorizontalEndPoints(double left, double right, double y) { | 246 void addExactHorizontalEndPoints(double left, double right, double y) { |
242 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 247 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
243 double lineT = SkDLine::ExactPointH(quad[qIndex], left, right, y); | 248 double lineT = SkDLine::ExactPointH(fQuad[qIndex], left, right, y); |
244 if (lineT < 0) { | 249 if (lineT < 0) { |
245 continue; | 250 continue; |
246 } | 251 } |
247 double quadT = (double) (qIndex >> 1); | 252 double quadT = (double) (qIndex >> 1); |
248 intersections->insert(quadT, lineT, quad[qIndex]); | 253 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
249 } | 254 } |
250 } | 255 } |
251 | 256 |
252 void addNearHorizontalEndPoints(double left, double right, double y) { | 257 void addNearHorizontalEndPoints(double left, double right, double y) { |
253 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 258 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
254 double quadT = (double) (qIndex >> 1); | 259 double quadT = (double) (qIndex >> 1); |
255 if (intersections->hasT(quadT)) { | 260 if (fIntersections->hasT(quadT)) { |
256 continue; | 261 continue; |
257 } | 262 } |
258 double lineT = SkDLine::NearPointH(quad[qIndex], left, right, y); | 263 double lineT = SkDLine::NearPointH(fQuad[qIndex], left, right, y); |
259 if (lineT < 0) { | 264 if (lineT < 0) { |
260 continue; | 265 continue; |
261 } | 266 } |
262 intersections->insert(quadT, lineT, quad[qIndex]); | 267 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
263 } | 268 } |
264 // FIXME: see if line end is nearly on quad | 269 // FIXME: see if line end is nearly on quad |
265 } | 270 } |
266 | 271 |
267 void addExactVerticalEndPoints(double top, double bottom, double x) { | 272 void addExactVerticalEndPoints(double top, double bottom, double x) { |
268 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 273 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
269 double lineT = SkDLine::ExactPointV(quad[qIndex], top, bottom, x); | 274 double lineT = SkDLine::ExactPointV(fQuad[qIndex], top, bottom, x); |
270 if (lineT < 0) { | 275 if (lineT < 0) { |
271 continue; | 276 continue; |
272 } | 277 } |
273 double quadT = (double) (qIndex >> 1); | 278 double quadT = (double) (qIndex >> 1); |
274 intersections->insert(quadT, lineT, quad[qIndex]); | 279 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
275 } | 280 } |
276 } | 281 } |
277 | 282 |
278 void addNearVerticalEndPoints(double top, double bottom, double x) { | 283 void addNearVerticalEndPoints(double top, double bottom, double x) { |
279 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 284 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
280 double quadT = (double) (qIndex >> 1); | 285 double quadT = (double) (qIndex >> 1); |
281 if (intersections->hasT(quadT)) { | 286 if (fIntersections->hasT(quadT)) { |
282 continue; | 287 continue; |
283 } | 288 } |
284 double lineT = SkDLine::NearPointV(quad[qIndex], top, bottom, x); | 289 double lineT = SkDLine::NearPointV(fQuad[qIndex], top, bottom, x); |
285 if (lineT < 0) { | 290 if (lineT < 0) { |
286 continue; | 291 continue; |
287 } | 292 } |
288 intersections->insert(quadT, lineT, quad[qIndex]); | 293 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
289 } | 294 } |
290 // FIXME: see if line end is nearly on quad | 295 // FIXME: see if line end is nearly on quad |
291 } | 296 } |
292 | 297 |
293 double findLineT(double t) { | 298 double findLineT(double t) { |
294 SkDPoint xy = quad.xyAtT(t); | 299 SkDPoint xy = fQuad.ptAtT(t); |
295 double dx = line[1].fX - line[0].fX; | 300 double dx = fLine[1].fX - fLine[0].fX; |
296 double dy = line[1].fY - line[0].fY; | 301 double dy = fLine[1].fY - fLine[0].fY; |
297 double dxT = (xy.fX - line[0].fX) / dx; | 302 double dxT = (xy.fX - fLine[0].fX) / dx; |
298 double dyT = (xy.fY - line[0].fY) / dy; | 303 double dyT = (xy.fY - fLine[0].fY) / dy; |
299 if (!between(FLT_EPSILON, dxT, 1 - FLT_EPSILON) && between(0, dyT, 1)) { | 304 if (!between(FLT_EPSILON, dxT, 1 - FLT_EPSILON) && between(0, dyT, 1)) { |
300 return dyT; | 305 return dyT; |
301 } | 306 } |
302 if (!between(FLT_EPSILON, dyT, 1 - FLT_EPSILON) && between(0, dxT, 1)) { | 307 if (!between(FLT_EPSILON, dyT, 1 - FLT_EPSILON) && between(0, dxT, 1)) { |
303 return dxT; | 308 return dxT; |
304 } | 309 } |
305 return fabs(dx) > fabs(dy) ? dxT : dyT; | 310 return fabs(dx) > fabs(dy) ? dxT : dyT; |
306 } | 311 } |
307 | 312 |
308 static bool PinTs(double* quadT, double* lineT) { | 313 bool pinTs(double* quadT, double* lineT, SkDPoint* pt, PinTPoint ptSet) { |
309 if (!approximately_one_or_less(*lineT)) { | 314 if (!approximately_one_or_less(*lineT)) { |
310 return false; | 315 return false; |
311 } | 316 } |
312 if (!approximately_zero_or_more(*lineT)) { | 317 if (!approximately_zero_or_more(*lineT)) { |
313 return false; | 318 return false; |
314 } | 319 } |
315 *quadT = SkPinT(*quadT); | 320 double qT = *quadT = SkPinT(*quadT); |
316 *lineT = SkPinT(*lineT); | 321 double lT = *lineT = SkPinT(*lineT); |
| 322 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && qT != 0 && qT
!= 1)) { |
| 323 *pt = fLine.ptAtT(lT); |
| 324 } else if (ptSet == kPointUninitialized) { |
| 325 *pt = fQuad.ptAtT(qT); |
| 326 } |
317 return true; | 327 return true; |
318 } | 328 } |
319 | 329 |
320 private: | 330 private: |
321 const SkDQuad& quad; | 331 const SkDQuad& fQuad; |
322 const SkDLine& line; | 332 const SkDLine& fLine; |
323 SkIntersections* intersections; | 333 SkIntersections* fIntersections; |
324 bool fAllowNear; | 334 bool fAllowNear; |
325 }; | 335 }; |
326 | 336 |
327 // utility for pairs of coincident quads | 337 // utility for pairs of coincident quads |
328 static double horizontalIntersect(const SkDQuad& quad, const SkDPoint& pt) { | 338 static double horizontalIntersect(const SkDQuad& quad, const SkDPoint& pt) { |
329 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), | 339 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), |
330 static_cast<SkIntersections*>(0)); | 340 static_cast<SkIntersections*>(0)); |
331 double rootVals[2]; | 341 double rootVals[2]; |
332 int roots = q.horizontalIntersect(pt.fY, rootVals); | 342 int roots = q.horizontalIntersect(pt.fY, rootVals); |
333 for (int index = 0; index < roots; ++index) { | 343 for (int index = 0; index < roots; ++index) { |
334 double t = rootVals[index]; | 344 double t = rootVals[index]; |
335 SkDPoint qPt = quad.xyAtT(t); | 345 SkDPoint qPt = quad.ptAtT(t); |
336 if (AlmostEqualUlps(qPt.fX, pt.fX)) { | 346 if (AlmostEqualUlps(qPt.fX, pt.fX)) { |
337 return t; | 347 return t; |
338 } | 348 } |
339 } | 349 } |
340 return -1; | 350 return -1; |
341 } | 351 } |
342 | 352 |
343 static double verticalIntersect(const SkDQuad& quad, const SkDPoint& pt) { | 353 static double verticalIntersect(const SkDQuad& quad, const SkDPoint& pt) { |
344 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), | 354 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), |
345 static_cast<SkIntersections*>(0)); | 355 static_cast<SkIntersections*>(0)); |
346 double rootVals[2]; | 356 double rootVals[2]; |
347 int roots = q.verticalIntersect(pt.fX, rootVals); | 357 int roots = q.verticalIntersect(pt.fX, rootVals); |
348 for (int index = 0; index < roots; ++index) { | 358 for (int index = 0; index < roots; ++index) { |
349 double t = rootVals[index]; | 359 double t = rootVals[index]; |
350 SkDPoint qPt = quad.xyAtT(t); | 360 SkDPoint qPt = quad.ptAtT(t); |
351 if (AlmostEqualUlps(qPt.fY, pt.fY)) { | 361 if (AlmostEqualUlps(qPt.fY, pt.fY)) { |
352 return t; | 362 return t; |
353 } | 363 } |
354 } | 364 } |
355 return -1; | 365 return -1; |
356 } | 366 } |
357 | 367 |
358 double SkIntersections::Axial(const SkDQuad& q1, const SkDPoint& p, bool vertica
l) { | 368 double SkIntersections::Axial(const SkDQuad& q1, const SkDPoint& p, bool vertica
l) { |
359 if (vertical) { | 369 if (vertical) { |
360 return verticalIntersect(q1, p); | 370 return verticalIntersect(q1, p); |
361 } | 371 } |
362 return horizontalIntersect(q1, p); | 372 return horizontalIntersect(q1, p); |
363 } | 373 } |
364 | 374 |
365 int SkIntersections::horizontal(const SkDQuad& quad, double left, double right,
double y, | 375 int SkIntersections::horizontal(const SkDQuad& quad, double left, double right,
double y, |
366 bool flipped) { | 376 bool flipped) { |
367 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), this); | 377 SkDLine line = {{{ left, y }, { right, y }}}; |
| 378 LineQuadraticIntersections q(quad, line, this); |
368 return q.horizontalIntersect(y, left, right, flipped); | 379 return q.horizontalIntersect(y, left, right, flipped); |
369 } | 380 } |
370 | 381 |
371 int SkIntersections::vertical(const SkDQuad& quad, double top, double bottom, do
uble x, | 382 int SkIntersections::vertical(const SkDQuad& quad, double top, double bottom, do
uble x, |
372 bool flipped) { | 383 bool flipped) { |
373 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), this); | 384 SkDLine line = {{{ x, top }, { x, bottom }}}; |
| 385 LineQuadraticIntersections q(quad, line, this); |
374 return q.verticalIntersect(x, top, bottom, flipped); | 386 return q.verticalIntersect(x, top, bottom, flipped); |
375 } | 387 } |
376 | 388 |
377 int SkIntersections::intersect(const SkDQuad& quad, const SkDLine& line) { | 389 int SkIntersections::intersect(const SkDQuad& quad, const SkDLine& line) { |
378 LineQuadraticIntersections q(quad, line, this); | 390 LineQuadraticIntersections q(quad, line, this); |
379 q.allowNear(fAllowNear); | 391 q.allowNear(fAllowNear); |
380 return q.intersect(); | 392 return q.intersect(); |
381 } | 393 } |
382 | 394 |
383 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { | 395 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { |
384 LineQuadraticIntersections q(quad, line, this); | 396 LineQuadraticIntersections q(quad, line, this); |
385 fUsed = q.intersectRay(fT[0]); | 397 fUsed = q.intersectRay(fT[0]); |
386 for (int index = 0; index < fUsed; ++index) { | 398 for (int index = 0; index < fUsed; ++index) { |
387 fPt[index] = quad.xyAtT(fT[0][index]); | 399 fPt[index] = quad.ptAtT(fT[0][index]); |
388 } | 400 } |
389 return fUsed; | 401 return fUsed; |
390 } | 402 } |
OLD | NEW |