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 "SkPathOpsCubic.h" | 8 #include "SkPathOpsCubic.h" |
9 #include "SkPathOpsLine.h" | 9 #include "SkPathOpsLine.h" |
10 | 10 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 } | 90 } |
91 | 91 |
92 void allowNear(bool allow) { | 92 void allowNear(bool allow) { |
93 fAllowNear = allow; | 93 fAllowNear = allow; |
94 } | 94 } |
95 | 95 |
96 // see parallel routine in line quadratic intersections | 96 // see parallel routine in line quadratic intersections |
97 int intersectRay(double roots[3]) { | 97 int intersectRay(double roots[3]) { |
98 double adj = fLine[1].fX - fLine[0].fX; | 98 double adj = fLine[1].fX - fLine[0].fX; |
99 double opp = fLine[1].fY - fLine[0].fY; | 99 double opp = fLine[1].fY - fLine[0].fY; |
100 SkDCubic r; | 100 SkDCubic c; |
101 for (int n = 0; n < 4; ++n) { | 101 for (int n = 0; n < 4; ++n) { |
102 r[n].fX = (fCubic[n].fY - fLine[0].fY) * adj - (fCubic[n].fX - fLine
[0].fX) * opp; | 102 c[n].fX = (fCubic[n].fY - fLine[0].fY) * adj - (fCubic[n].fX - fLine
[0].fX) * opp; |
103 } | 103 } |
104 double A, B, C, D; | 104 double A, B, C, D; |
105 SkDCubic::Coefficients(&r[0].fX, &A, &B, &C, &D); | 105 SkDCubic::Coefficients(&c[0].fX, &A, &B, &C, &D); |
106 return SkDCubic::RootsValidT(A, B, C, D, roots); | 106 int count = SkDCubic::RootsValidT(A, B, C, D, roots); |
| 107 for (int index = 0; index < count; ++index) { |
| 108 SkDPoint calcPt = c.ptAtT(roots[index]); |
| 109 if (!approximately_zero(calcPt.fX)) { |
| 110 for (int n = 0; n < 4; ++n) { |
| 111 c[n].fY = (fCubic[n].fY - fLine[0].fY) * opp |
| 112 + (fCubic[n].fX - fLine[0].fX) * adj; |
| 113 } |
| 114 double extremeTs[6]; |
| 115 int extrema = SkDCubic::FindExtrema(c[0].fX, c[1].fX, c[2].fX, c
[3].fX, extremeTs); |
| 116 count = c.searchRoots(extremeTs, extrema, 0, SkDCubic::kXAxis, r
oots); |
| 117 break; |
| 118 } |
| 119 } |
| 120 return count; |
107 } | 121 } |
108 | 122 |
109 int intersect() { | 123 int intersect() { |
110 addExactEndPoints(); | 124 addExactEndPoints(); |
111 if (fAllowNear) { | 125 if (fAllowNear) { |
112 addNearEndPoints(); | 126 addNearEndPoints(); |
113 } | 127 } |
114 double rootVals[3]; | 128 double rootVals[3]; |
115 int roots = intersectRay(rootVals); | 129 int roots = intersectRay(rootVals); |
116 for (int index = 0; index < roots; ++index) { | 130 for (int index = 0; index < roots; ++index) { |
(...skipping 22 matching lines...) Expand all Loading... |
139 } | 153 } |
140 } | 154 } |
141 fIntersections->insert(cubicT, lineT, pt); | 155 fIntersections->insert(cubicT, lineT, pt); |
142 skipInsert: | 156 skipInsert: |
143 ; | 157 ; |
144 } | 158 } |
145 } | 159 } |
146 return fIntersections->used(); | 160 return fIntersections->used(); |
147 } | 161 } |
148 | 162 |
149 int horizontalIntersect(double axisIntercept, double roots[3]) { | 163 static int HorizontalIntersect(const SkDCubic& c, double axisIntercept, doub
le roots[3]) { |
150 double A, B, C, D; | 164 double A, B, C, D; |
151 SkDCubic::Coefficients(&fCubic[0].fY, &A, &B, &C, &D); | 165 SkDCubic::Coefficients(&c[0].fY, &A, &B, &C, &D); |
152 D -= axisIntercept; | 166 D -= axisIntercept; |
153 return SkDCubic::RootsValidT(A, B, C, D, roots); | 167 int count = SkDCubic::RootsValidT(A, B, C, D, roots); |
| 168 for (int index = 0; index < count; ++index) { |
| 169 SkDPoint calcPt = c.ptAtT(roots[index]); |
| 170 if (!approximately_equal(calcPt.fY, axisIntercept)) { |
| 171 double extremeTs[6]; |
| 172 int extrema = SkDCubic::FindExtrema(c[0].fY, c[1].fY, c[2].fY, c
[3].fY, extremeTs); |
| 173 count = c.searchRoots(extremeTs, extrema, axisIntercept, SkDCubi
c::kYAxis, roots); |
| 174 break; |
| 175 } |
| 176 } |
| 177 return count; |
154 } | 178 } |
155 | 179 |
156 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { | 180 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { |
157 addExactHorizontalEndPoints(left, right, axisIntercept); | 181 addExactHorizontalEndPoints(left, right, axisIntercept); |
158 if (fAllowNear) { | 182 if (fAllowNear) { |
159 addNearHorizontalEndPoints(left, right, axisIntercept); | 183 addNearHorizontalEndPoints(left, right, axisIntercept); |
160 } | 184 } |
161 double rootVals[3]; | 185 double roots[3]; |
162 int roots = horizontalIntersect(axisIntercept, rootVals); | 186 int count = HorizontalIntersect(fCubic, axisIntercept, roots); |
163 for (int index = 0; index < roots; ++index) { | 187 for (int index = 0; index < count; ++index) { |
164 double cubicT = rootVals[index]; | 188 double cubicT = roots[index]; |
165 SkDPoint pt = fCubic.ptAtT(cubicT); | 189 SkDPoint pt; |
| 190 pt.fX = fCubic.ptAtT(cubicT).fX; |
| 191 pt.fY = axisIntercept; |
166 double lineT = (pt.fX - left) / (right - left); | 192 double lineT = (pt.fX - left) / (right - left); |
167 if (pinTs(&cubicT, &lineT, &pt, kPointInitialized)) { | 193 if (pinTs(&cubicT, &lineT, &pt, kPointInitialized)) { |
168 fIntersections->insert(cubicT, lineT, pt); | 194 fIntersections->insert(cubicT, lineT, pt); |
169 } | 195 } |
170 } | 196 } |
171 if (flipped) { | 197 if (flipped) { |
172 fIntersections->flip(); | 198 fIntersections->flip(); |
173 } | 199 } |
174 return fIntersections->used(); | 200 return fIntersections->used(); |
175 } | 201 } |
176 | 202 |
177 int verticalIntersect(double axisIntercept, double roots[3]) { | 203 static int VerticalIntersect(const SkDCubic& c, double axisIntercept, double
roots[3]) { |
178 double A, B, C, D; | 204 double A, B, C, D; |
179 SkDCubic::Coefficients(&fCubic[0].fX, &A, &B, &C, &D); | 205 SkDCubic::Coefficients(&c[0].fX, &A, &B, &C, &D); |
180 D -= axisIntercept; | 206 D -= axisIntercept; |
181 return SkDCubic::RootsValidT(A, B, C, D, roots); | 207 int count = SkDCubic::RootsValidT(A, B, C, D, roots); |
| 208 for (int index = 0; index < count; ++index) { |
| 209 SkDPoint calcPt = c.ptAtT(roots[index]); |
| 210 if (!approximately_equal(calcPt.fX, axisIntercept)) { |
| 211 double extremeTs[6]; |
| 212 int extrema = SkDCubic::FindExtrema(c[0].fX, c[1].fX, c[2].fX, c
[3].fX, extremeTs); |
| 213 count = c.searchRoots(extremeTs, extrema, axisIntercept, SkDCubi
c::kXAxis, roots); |
| 214 break; |
| 215 } |
| 216 } |
| 217 return count; |
182 } | 218 } |
183 | 219 |
184 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { | 220 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { |
185 addExactVerticalEndPoints(top, bottom, axisIntercept); | 221 addExactVerticalEndPoints(top, bottom, axisIntercept); |
186 if (fAllowNear) { | 222 if (fAllowNear) { |
187 addNearVerticalEndPoints(top, bottom, axisIntercept); | 223 addNearVerticalEndPoints(top, bottom, axisIntercept); |
188 } | 224 } |
189 double rootVals[3]; | 225 double roots[3]; |
190 int roots = verticalIntersect(axisIntercept, rootVals); | 226 int count = VerticalIntersect(fCubic, axisIntercept, roots); |
191 for (int index = 0; index < roots; ++index) { | 227 for (int index = 0; index < count; ++index) { |
192 double cubicT = rootVals[index]; | 228 double cubicT = roots[index]; |
193 SkDPoint pt = fCubic.ptAtT(cubicT); | 229 SkDPoint pt; |
| 230 pt.fX = axisIntercept; |
| 231 pt.fY = fCubic.ptAtT(cubicT).fY; |
194 double lineT = (pt.fY - top) / (bottom - top); | 232 double lineT = (pt.fY - top) / (bottom - top); |
195 if (pinTs(&cubicT, &lineT, &pt, kPointInitialized)) { | 233 if (pinTs(&cubicT, &lineT, &pt, kPointInitialized)) { |
196 fIntersections->insert(cubicT, lineT, pt); | 234 fIntersections->insert(cubicT, lineT, pt); |
197 } | 235 } |
198 } | 236 } |
199 if (flipped) { | 237 if (flipped) { |
200 fIntersections->flip(); | 238 fIntersections->flip(); |
201 } | 239 } |
202 return fIntersections->used(); | 240 return fIntersections->used(); |
203 } | 241 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 } | 394 } |
357 | 395 |
358 int SkIntersections::intersectRay(const SkDCubic& cubic, const SkDLine& line) { | 396 int SkIntersections::intersectRay(const SkDCubic& cubic, const SkDLine& line) { |
359 LineCubicIntersections c(cubic, line, this); | 397 LineCubicIntersections c(cubic, line, this); |
360 fUsed = c.intersectRay(fT[0]); | 398 fUsed = c.intersectRay(fT[0]); |
361 for (int index = 0; index < fUsed; ++index) { | 399 for (int index = 0; index < fUsed; ++index) { |
362 fPt[index] = cubic.ptAtT(fT[0][index]); | 400 fPt[index] = cubic.ptAtT(fT[0][index]); |
363 } | 401 } |
364 return fUsed; | 402 return fUsed; |
365 } | 403 } |
OLD | NEW |