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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 for (int n = 0; n < 4; ++n) { | 100 for (int n = 0; n < 4; ++n) { |
101 r[n].fX = (fCubic[n].fY - fLine[0].fY) * adj - (fCubic[n].fX - fLine
[0].fX) * opp; | 101 r[n].fX = (fCubic[n].fY - fLine[0].fY) * adj - (fCubic[n].fX - fLine
[0].fX) * opp; |
102 } | 102 } |
103 double A, B, C, D; | 103 double A, B, C, D; |
104 SkDCubic::Coefficients(&r[0].fX, &A, &B, &C, &D); | 104 SkDCubic::Coefficients(&r[0].fX, &A, &B, &C, &D); |
105 return SkDCubic::RootsValidT(A, B, C, D, roots); | 105 return SkDCubic::RootsValidT(A, B, C, D, roots); |
106 } | 106 } |
107 | 107 |
108 int intersect() { | 108 int intersect() { |
109 addExactEndPoints(); | 109 addExactEndPoints(); |
| 110 if (fAllowNear) { |
| 111 addNearEndPoints(); |
| 112 } |
110 double rootVals[3]; | 113 double rootVals[3]; |
111 int roots = intersectRay(rootVals); | 114 int roots = intersectRay(rootVals); |
112 for (int index = 0; index < roots; ++index) { | 115 for (int index = 0; index < roots; ++index) { |
113 double cubicT = rootVals[index]; | 116 double cubicT = rootVals[index]; |
114 double lineT = findLineT(cubicT); | 117 double lineT = findLineT(cubicT); |
115 SkDPoint pt; | 118 SkDPoint pt; |
116 if (pinTs(&cubicT, &lineT, &pt, kPointUninitialized)) { | 119 if (pinTs(&cubicT, &lineT, &pt, kPointUninitialized)) { |
117 #if ONE_OFF_DEBUG | 120 #if ONE_OFF_DEBUG |
118 SkDPoint cPt = fCubic.ptAtT(cubicT); | 121 SkDPoint cPt = fCubic.ptAtT(cubicT); |
119 SkDebugf("%s pt=(%1.9g,%1.9g) cPt=(%1.9g,%1.9g)\n", __FUNCTION__
, pt.fX, pt.fY, | 122 SkDebugf("%s pt=(%1.9g,%1.9g) cPt=(%1.9g,%1.9g)\n", __FUNCTION__
, pt.fX, pt.fY, |
120 cPt.fX, cPt.fY); | 123 cPt.fX, cPt.fY); |
121 #endif | 124 #endif |
122 fIntersections->insert(cubicT, lineT, pt); | 125 fIntersections->insert(cubicT, lineT, pt); |
123 } | 126 } |
124 } | 127 } |
125 if (fAllowNear) { | |
126 addNearEndPoints(); | |
127 } | |
128 return fIntersections->used(); | 128 return fIntersections->used(); |
129 } | 129 } |
130 | 130 |
131 int horizontalIntersect(double axisIntercept, double roots[3]) { | 131 int horizontalIntersect(double axisIntercept, double roots[3]) { |
132 double A, B, C, D; | 132 double A, B, C, D; |
133 SkDCubic::Coefficients(&fCubic[0].fY, &A, &B, &C, &D); | 133 SkDCubic::Coefficients(&fCubic[0].fY, &A, &B, &C, &D); |
134 D -= axisIntercept; | 134 D -= axisIntercept; |
135 return SkDCubic::RootsValidT(A, B, C, D, roots); | 135 return SkDCubic::RootsValidT(A, B, C, D, roots); |
136 } | 136 } |
137 | 137 |
138 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { | 138 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { |
139 addExactHorizontalEndPoints(left, right, axisIntercept); | 139 addExactHorizontalEndPoints(left, right, axisIntercept); |
| 140 if (fAllowNear) { |
| 141 addNearHorizontalEndPoints(left, right, axisIntercept); |
| 142 } |
140 double rootVals[3]; | 143 double rootVals[3]; |
141 int roots = horizontalIntersect(axisIntercept, rootVals); | 144 int roots = horizontalIntersect(axisIntercept, rootVals); |
142 for (int index = 0; index < roots; ++index) { | 145 for (int index = 0; index < roots; ++index) { |
143 double cubicT = rootVals[index]; | 146 double cubicT = rootVals[index]; |
144 SkDPoint pt = fCubic.ptAtT(cubicT); | 147 SkDPoint pt = fCubic.ptAtT(cubicT); |
145 double lineT = (pt.fX - left) / (right - left); | 148 double lineT = (pt.fX - left) / (right - left); |
146 if (pinTs(&cubicT, &lineT, &pt, kPointInitialized)) { | 149 if (pinTs(&cubicT, &lineT, &pt, kPointInitialized)) { |
147 fIntersections->insert(cubicT, lineT, pt); | 150 fIntersections->insert(cubicT, lineT, pt); |
148 } | 151 } |
149 } | 152 } |
150 if (fAllowNear) { | |
151 addNearHorizontalEndPoints(left, right, axisIntercept); | |
152 } | |
153 if (flipped) { | 153 if (flipped) { |
154 fIntersections->flip(); | 154 fIntersections->flip(); |
155 } | 155 } |
156 return fIntersections->used(); | 156 return fIntersections->used(); |
157 } | 157 } |
158 | 158 |
159 int verticalIntersect(double axisIntercept, double roots[3]) { | 159 int verticalIntersect(double axisIntercept, double roots[3]) { |
160 double A, B, C, D; | 160 double A, B, C, D; |
161 SkDCubic::Coefficients(&fCubic[0].fX, &A, &B, &C, &D); | 161 SkDCubic::Coefficients(&fCubic[0].fX, &A, &B, &C, &D); |
162 D -= axisIntercept; | 162 D -= axisIntercept; |
163 return SkDCubic::RootsValidT(A, B, C, D, roots); | 163 return SkDCubic::RootsValidT(A, B, C, D, roots); |
164 } | 164 } |
165 | 165 |
166 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { | 166 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { |
167 addExactVerticalEndPoints(top, bottom, axisIntercept); | 167 addExactVerticalEndPoints(top, bottom, axisIntercept); |
| 168 if (fAllowNear) { |
| 169 addNearVerticalEndPoints(top, bottom, axisIntercept); |
| 170 } |
168 double rootVals[3]; | 171 double rootVals[3]; |
169 int roots = verticalIntersect(axisIntercept, rootVals); | 172 int roots = verticalIntersect(axisIntercept, rootVals); |
170 for (int index = 0; index < roots; ++index) { | 173 for (int index = 0; index < roots; ++index) { |
171 double cubicT = rootVals[index]; | 174 double cubicT = rootVals[index]; |
172 SkDPoint pt = fCubic.ptAtT(cubicT); | 175 SkDPoint pt = fCubic.ptAtT(cubicT); |
173 double lineT = (pt.fY - top) / (bottom - top); | 176 double lineT = (pt.fY - top) / (bottom - top); |
174 if (pinTs(&cubicT, &lineT, &pt, kPointInitialized)) { | 177 if (pinTs(&cubicT, &lineT, &pt, kPointInitialized)) { |
175 fIntersections->insert(cubicT, lineT, pt); | 178 fIntersections->insert(cubicT, lineT, pt); |
176 } | 179 } |
177 } | 180 } |
178 if (fAllowNear) { | |
179 addNearVerticalEndPoints(top, bottom, 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 protected: | 187 protected: |
188 | 188 |
189 void addExactEndPoints() { | 189 void addExactEndPoints() { |
190 for (int cIndex = 0; cIndex < 4; cIndex += 3) { | 190 for (int cIndex = 0; cIndex < 4; cIndex += 3) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 if (!approximately_zero_or_more(*lineT)) { | 280 if (!approximately_zero_or_more(*lineT)) { |
281 return false; | 281 return false; |
282 } | 282 } |
283 double cT = *cubicT = SkPinT(*cubicT); | 283 double cT = *cubicT = SkPinT(*cubicT); |
284 double lT = *lineT = SkPinT(*lineT); | 284 double lT = *lineT = SkPinT(*lineT); |
285 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && cT != 0 && cT
!= 1)) { | 285 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && cT != 0 && cT
!= 1)) { |
286 *pt = fLine.ptAtT(lT); | 286 *pt = fLine.ptAtT(lT); |
287 } else if (ptSet == kPointUninitialized) { | 287 } else if (ptSet == kPointUninitialized) { |
288 *pt = fCubic.ptAtT(cT); | 288 *pt = fCubic.ptAtT(cT); |
289 } | 289 } |
| 290 SkPoint gridPt = pt->asSkPoint(); |
| 291 if (gridPt == fLine[0].asSkPoint()) { |
| 292 *lineT = 0; |
| 293 } else if (gridPt == fLine[1].asSkPoint()) { |
| 294 *lineT = 1; |
| 295 } |
| 296 if (gridPt == fCubic[0].asSkPoint() && approximately_equal(*cubicT, 0))
{ |
| 297 *cubicT = 0; |
| 298 } else if (gridPt == fCubic[3].asSkPoint() && approximately_equal(*cubic
T, 1)) { |
| 299 *cubicT = 1; |
| 300 } |
290 return true; | 301 return true; |
291 } | 302 } |
292 | 303 |
293 private: | 304 private: |
294 const SkDCubic& fCubic; | 305 const SkDCubic& fCubic; |
295 const SkDLine& fLine; | 306 const SkDLine& fLine; |
296 SkIntersections* fIntersections; | 307 SkIntersections* fIntersections; |
297 bool fAllowNear; | 308 bool fAllowNear; |
298 }; | 309 }; |
299 | 310 |
(...skipping 18 matching lines...) Expand all Loading... |
318 } | 329 } |
319 | 330 |
320 int SkIntersections::intersectRay(const SkDCubic& cubic, const SkDLine& line) { | 331 int SkIntersections::intersectRay(const SkDCubic& cubic, const SkDLine& line) { |
321 LineCubicIntersections c(cubic, line, this); | 332 LineCubicIntersections c(cubic, line, this); |
322 fUsed = c.intersectRay(fT[0]); | 333 fUsed = c.intersectRay(fT[0]); |
323 for (int index = 0; index < fUsed; ++index) { | 334 for (int index = 0; index < fUsed; ++index) { |
324 fPt[index] = cubic.ptAtT(fT[0][index]); | 335 fPt[index] = cubic.ptAtT(fT[0][index]); |
325 } | 336 } |
326 return fUsed; | 337 return fUsed; |
327 } | 338 } |
OLD | NEW |