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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 double A = r[2]; | 130 double A = r[2]; |
131 double B = r[1]; | 131 double B = r[1]; |
132 double C = r[0]; | 132 double C = r[0]; |
133 A += C - 2 * B; // A = a - 2*b + c | 133 A += C - 2 * B; // A = a - 2*b + c |
134 B -= C; // B = -(b - c) | 134 B -= C; // B = -(b - c) |
135 return SkDQuad::RootsValidT(A, 2 * B, C, roots); | 135 return SkDQuad::RootsValidT(A, 2 * B, C, roots); |
136 } | 136 } |
137 | 137 |
138 int intersect() { | 138 int intersect() { |
139 addExactEndPoints(); | 139 addExactEndPoints(); |
| 140 if (fAllowNear) { |
| 141 addNearEndPoints(); |
| 142 } |
140 double rootVals[2]; | 143 double rootVals[2]; |
141 int roots = intersectRay(rootVals); | 144 int roots = intersectRay(rootVals); |
142 for (int index = 0; index < roots; ++index) { | 145 for (int index = 0; index < roots; ++index) { |
143 double quadT = rootVals[index]; | 146 double quadT = rootVals[index]; |
144 double lineT = findLineT(quadT); | 147 double lineT = findLineT(quadT); |
145 SkDPoint pt; | 148 SkDPoint pt; |
146 if (pinTs(&quadT, &lineT, &pt, kPointUninitialized)) { | 149 if (pinTs(&quadT, &lineT, &pt, kPointUninitialized)) { |
147 fIntersections->insert(quadT, lineT, pt); | 150 fIntersections->insert(quadT, lineT, pt); |
148 } | 151 } |
149 } | 152 } |
150 if (fAllowNear) { | |
151 addNearEndPoints(); | |
152 } | |
153 return fIntersections->used(); | 153 return fIntersections->used(); |
154 } | 154 } |
155 | 155 |
156 int horizontalIntersect(double axisIntercept, double roots[2]) { | 156 int horizontalIntersect(double axisIntercept, double roots[2]) { |
157 double D = fQuad[2].fY; // f | 157 double D = fQuad[2].fY; // f |
158 double E = fQuad[1].fY; // e | 158 double E = fQuad[1].fY; // e |
159 double F = fQuad[0].fY; // d | 159 double F = fQuad[0].fY; // d |
160 D += F - 2 * E; // D = d - 2*e + f | 160 D += F - 2 * E; // D = d - 2*e + f |
161 E -= F; // E = -(d - e) | 161 E -= F; // E = -(d - e) |
162 F -= axisIntercept; | 162 F -= axisIntercept; |
163 return SkDQuad::RootsValidT(D, 2 * E, F, roots); | 163 return SkDQuad::RootsValidT(D, 2 * E, F, roots); |
164 } | 164 } |
165 | 165 |
166 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { | 166 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { |
167 addExactHorizontalEndPoints(left, right, axisIntercept); | 167 addExactHorizontalEndPoints(left, right, axisIntercept); |
| 168 if (fAllowNear) { |
| 169 addNearHorizontalEndPoints(left, right, axisIntercept); |
| 170 } |
168 double rootVals[2]; | 171 double rootVals[2]; |
169 int roots = horizontalIntersect(axisIntercept, rootVals); | 172 int roots = horizontalIntersect(axisIntercept, rootVals); |
170 for (int index = 0; index < roots; ++index) { | 173 for (int index = 0; index < roots; ++index) { |
171 double quadT = rootVals[index]; | 174 double quadT = rootVals[index]; |
172 SkDPoint pt = fQuad.ptAtT(quadT); | 175 SkDPoint pt = fQuad.ptAtT(quadT); |
173 double lineT = (pt.fX - left) / (right - left); | 176 double lineT = (pt.fX - left) / (right - left); |
174 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { | 177 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { |
175 fIntersections->insert(quadT, lineT, pt); | 178 fIntersections->insert(quadT, lineT, pt); |
176 } | 179 } |
177 } | 180 } |
178 if (fAllowNear) { | |
179 addNearHorizontalEndPoints(left, right, axisIntercept); | |
180 } | |
181 if (flipped) { | 181 if (flipped) { |
182 fIntersections->flip(); | 182 fIntersections->flip(); |
183 } | 183 } |
184 return fIntersections->used(); | 184 return fIntersections->used(); |
185 } | 185 } |
186 | 186 |
187 int verticalIntersect(double axisIntercept, double roots[2]) { | 187 int verticalIntersect(double axisIntercept, double roots[2]) { |
188 double D = fQuad[2].fX; // f | 188 double D = fQuad[2].fX; // f |
189 double E = fQuad[1].fX; // e | 189 double E = fQuad[1].fX; // e |
190 double F = fQuad[0].fX; // d | 190 double F = fQuad[0].fX; // d |
191 D += F - 2 * E; // D = d - 2*e + f | 191 D += F - 2 * E; // D = d - 2*e + f |
192 E -= F; // E = -(d - e) | 192 E -= F; // E = -(d - e) |
193 F -= axisIntercept; | 193 F -= axisIntercept; |
194 return SkDQuad::RootsValidT(D, 2 * E, F, roots); | 194 return SkDQuad::RootsValidT(D, 2 * E, F, roots); |
195 } | 195 } |
196 | 196 |
197 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { | 197 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { |
198 addExactVerticalEndPoints(top, bottom, axisIntercept); | 198 addExactVerticalEndPoints(top, bottom, axisIntercept); |
| 199 if (fAllowNear) { |
| 200 addNearVerticalEndPoints(top, bottom, axisIntercept); |
| 201 } |
199 double rootVals[2]; | 202 double rootVals[2]; |
200 int roots = verticalIntersect(axisIntercept, rootVals); | 203 int roots = verticalIntersect(axisIntercept, rootVals); |
201 for (int index = 0; index < roots; ++index) { | 204 for (int index = 0; index < roots; ++index) { |
202 double quadT = rootVals[index]; | 205 double quadT = rootVals[index]; |
203 SkDPoint pt = fQuad.ptAtT(quadT); | 206 SkDPoint pt = fQuad.ptAtT(quadT); |
204 double lineT = (pt.fY - top) / (bottom - top); | 207 double lineT = (pt.fY - top) / (bottom - top); |
205 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { | 208 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { |
206 fIntersections->insert(quadT, lineT, pt); | 209 fIntersections->insert(quadT, lineT, pt); |
207 } | 210 } |
208 } | 211 } |
209 if (fAllowNear) { | |
210 addNearVerticalEndPoints(top, bottom, axisIntercept); | |
211 } | |
212 if (flipped) { | 212 if (flipped) { |
213 fIntersections->flip(); | 213 fIntersections->flip(); |
214 } | 214 } |
215 return fIntersections->used(); | 215 return fIntersections->used(); |
216 } | 216 } |
217 | 217 |
218 protected: | 218 protected: |
219 // add endpoints first to get zero and one t values exactly | 219 // add endpoints first to get zero and one t values exactly |
220 void addExactEndPoints() { | 220 void addExactEndPoints() { |
221 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 221 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 if (!approximately_zero_or_more(*lineT)) { | 317 if (!approximately_zero_or_more(*lineT)) { |
318 return false; | 318 return false; |
319 } | 319 } |
320 double qT = *quadT = SkPinT(*quadT); | 320 double qT = *quadT = SkPinT(*quadT); |
321 double lT = *lineT = SkPinT(*lineT); | 321 double lT = *lineT = SkPinT(*lineT); |
322 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && qT != 0 && qT
!= 1)) { | 322 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && qT != 0 && qT
!= 1)) { |
323 *pt = fLine.ptAtT(lT); | 323 *pt = fLine.ptAtT(lT); |
324 } else if (ptSet == kPointUninitialized) { | 324 } else if (ptSet == kPointUninitialized) { |
325 *pt = fQuad.ptAtT(qT); | 325 *pt = fQuad.ptAtT(qT); |
326 } | 326 } |
| 327 SkPoint gridPt = pt->asSkPoint(); |
| 328 if (gridPt == fLine[0].asSkPoint()) { |
| 329 *lineT = 0; |
| 330 } else if (gridPt == fLine[1].asSkPoint()) { |
| 331 *lineT = 1; |
| 332 } |
| 333 if (gridPt == fQuad[0].asSkPoint()) { |
| 334 *quadT = 0; |
| 335 } else if (gridPt == fQuad[2].asSkPoint()) { |
| 336 *quadT = 1; |
| 337 } |
327 return true; | 338 return true; |
328 } | 339 } |
329 | 340 |
330 private: | 341 private: |
331 const SkDQuad& fQuad; | 342 const SkDQuad& fQuad; |
332 const SkDLine& fLine; | 343 const SkDLine& fLine; |
333 SkIntersections* fIntersections; | 344 SkIntersections* fIntersections; |
334 bool fAllowNear; | 345 bool fAllowNear; |
335 }; | 346 }; |
336 | 347 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 } | 404 } |
394 | 405 |
395 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { | 406 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { |
396 LineQuadraticIntersections q(quad, line, this); | 407 LineQuadraticIntersections q(quad, line, this); |
397 fUsed = q.intersectRay(fT[0]); | 408 fUsed = q.intersectRay(fT[0]); |
398 for (int index = 0; index < fUsed; ++index) { | 409 for (int index = 0; index < fUsed; ++index) { |
399 fPt[index] = quad.ptAtT(fT[0][index]); | 410 fPt[index] = quad.ptAtT(fT[0][index]); |
400 } | 411 } |
401 return fUsed; | 412 return fUsed; |
402 } | 413 } |
OLD | NEW |