Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(874)

Side by Side Diff: src/pathops/SkDLineIntersection.cpp

Issue 23542056: path ops work in progress (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: verbose + mutex around file number access Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/pathops/SkDCubicLineIntersection.cpp ('k') | src/pathops/SkDQuadImplicit.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 9
10 /* Determine the intersection point of two lines. This assumes the lines are not parallel, 10 /* Determine the intersection point of two lines. This assumes the lines are not parallel,
11 and that that the lines are infinite. 11 and that that the lines are infinite.
12 From http://en.wikipedia.org/wiki/Line-line_intersection 12 From http://en.wikipedia.org/wiki/Line-line_intersection
13 */ 13 */
14 SkDPoint SkIntersections::Line(const SkDLine& a, const SkDLine& b) { 14 SkDPoint SkIntersections::Line(const SkDLine& a, const SkDLine& b) {
15 double axLen = a[1].fX - a[0].fX; 15 double axLen = a[1].fX - a[0].fX;
16 double ayLen = a[1].fY - a[0].fY; 16 double ayLen = a[1].fY - a[0].fY;
17 double bxLen = b[1].fX - b[0].fX; 17 double bxLen = b[1].fX - b[0].fX;
18 double byLen = b[1].fY - b[0].fY; 18 double byLen = b[1].fY - b[0].fY;
19 double denom = byLen * axLen - ayLen * bxLen; 19 double denom = byLen * axLen - ayLen * bxLen;
20 SkASSERT(denom); 20 SkASSERT(denom);
21 double term1 = a[1].fX * a[0].fY - a[1].fY * a[0].fX; 21 double term1 = a[1].fX * a[0].fY - a[1].fY * a[0].fX;
22 double term2 = b[1].fX * b[0].fY - b[1].fY * b[0].fX; 22 double term2 = b[1].fX * b[0].fY - b[1].fY * b[0].fX;
23 SkDPoint p; 23 SkDPoint p;
24 p.fX = (term1 * bxLen - axLen * term2) / denom; 24 p.fX = (term1 * bxLen - axLen * term2) / denom;
25 p.fY = (term1 * byLen - ayLen * term2) / denom; 25 p.fY = (term1 * byLen - ayLen * term2) / denom;
26 return p; 26 return p;
27 } 27 }
28 28
29 int SkIntersections::computePoints(const SkDLine& line, int used) { 29 void SkIntersections::cleanUpCoincidence() {
30 SkASSERT(fUsed == 2);
31 // both t values are good
32 bool startMatch = fT[0][0] == 0 && (fT[1][0] == 0 || fT[1][0] == 1);
33 bool endMatch = fT[0][1] == 1 && (fT[1][1] == 0 || fT[1][1] == 1);
34 if (startMatch || endMatch) {
35 removeOne(startMatch);
36 return;
37 }
38 // either t value is good
39 bool pStartMatch = fT[0][0] == 0 || fT[1][0] == 0 || fT[1][0] == 1;
40 bool pEndMatch = fT[0][1] == 1 || fT[1][1] == 0 || fT[1][1] == 1;
41 removeOne(pStartMatch || !pEndMatch);
42 }
43
44 void SkIntersections::cleanUpParallelLines(bool parallel) {
45 while (fUsed > 2) {
46 removeOne(1);
47 }
48 if (fUsed == 2 && !parallel) {
49 bool startMatch = fT[0][0] == 0 || fT[1][0] == 0 || fT[1][0] == 1;
50 bool endMatch = fT[0][1] == 1 || fT[1][1] == 0 || fT[1][1] == 1;
51 if ((!startMatch && !endMatch) || approximately_equal(fT[0][0], fT[0][1] )) {
52 SkASSERT(startMatch || endMatch);
53 removeOne(endMatch);
54 }
55 }
56 }
57
58 void SkIntersections::computePoints(const SkDLine& line, int used) {
30 fPt[0] = line.ptAtT(fT[0][0]); 59 fPt[0] = line.ptAtT(fT[0][0]);
31 if ((fUsed = used) == 2) { 60 if ((fUsed = used) == 2) {
32 fPt[1] = line.ptAtT(fT[0][1]); 61 fPt[1] = line.ptAtT(fT[0][1]);
33 } 62 }
34 return fUsed;
35 } 63 }
36 64
37 int SkIntersections::intersectRay(const SkDLine& a, const SkDLine& b) { 65 int SkIntersections::intersectRay(const SkDLine& a, const SkDLine& b) {
66 fMax = 2;
38 SkDVector aLen = a[1] - a[0]; 67 SkDVector aLen = a[1] - a[0];
39 SkDVector bLen = b[1] - b[0]; 68 SkDVector bLen = b[1] - b[0];
40 /* Slopes match when denom goes to zero: 69 /* Slopes match when denom goes to zero:
41 axLen / ayLen == bxLen / byLen 70 axLen / ayLen == bxLen / byLen
42 (ayLen * byLen) * axLen / ayLen == (ayLen * byLen) * bxLen / byLen 71 (ayLen * byLen) * axLen / ayLen == (ayLen * byLen) * bxLen / byLen
43 byLen * axLen == ayLen * bxLen 72 byLen * axLen == ayLen * bxLen
44 byLen * axLen - ayLen * bxLen == 0 ( == denom ) 73 byLen * axLen - ayLen * bxLen == 0 ( == denom )
45 */ 74 */
46 double denom = bLen.fY * aLen.fX - aLen.fY * bLen.fX; 75 double denom = bLen.fY * aLen.fX - aLen.fY * bLen.fX;
47 SkDVector ab0 = a[0] - b[0]; 76 SkDVector ab0 = a[0] - b[0];
(...skipping 14 matching lines...) Expand all
62 */ 91 */
63 if (!AlmostEqualUlps(aLen.fX * a[0].fY - aLen.fY * a[0].fX, 92 if (!AlmostEqualUlps(aLen.fX * a[0].fY - aLen.fY * a[0].fX,
64 aLen.fX * b[0].fY - aLen.fY * b[0].fX)) { 93 aLen.fX * b[0].fY - aLen.fY * b[0].fX)) {
65 return fUsed = 0; 94 return fUsed = 0;
66 } 95 }
67 // there's no great answer for intersection points for coincident rays, but return something 96 // there's no great answer for intersection points for coincident rays, but return something
68 fT[0][0] = fT[1][0] = 0; 97 fT[0][0] = fT[1][0] = 0;
69 fT[1][0] = fT[1][1] = 1; 98 fT[1][0] = fT[1][1] = 1;
70 used = 2; 99 used = 2;
71 } 100 }
72 return computePoints(a, used); 101 computePoints(a, used);
102 return fUsed;
73 } 103 }
74 104
75 // note that this only works if both lines are neither horizontal nor vertical 105 // note that this only works if both lines are neither horizontal nor vertical
76 int SkIntersections::intersect(const SkDLine& a, const SkDLine& b) { 106 int SkIntersections::intersect(const SkDLine& a, const SkDLine& b) {
107 fMax = 3; // note that we clean up so that there is no more than two in the end
77 // see if end points intersect the opposite line 108 // see if end points intersect the opposite line
78 double t; 109 double t;
79 for (int iA = 0; iA < 2; ++iA) { 110 for (int iA = 0; iA < 2; ++iA) {
80 if ((t = b.exactPoint(a[iA])) >= 0) { 111 if ((t = b.exactPoint(a[iA])) >= 0) {
81 insert(iA, t, a[iA]); 112 insert(iA, t, a[iA]);
82 } 113 }
83 } 114 }
84 for (int iB = 0; iB < 2; ++iB) { 115 for (int iB = 0; iB < 2; ++iB) {
85 if ((t = a.exactPoint(b[iB])) >= 0) { 116 if ((t = a.exactPoint(b[iB])) >= 0) {
86 insert(t, iB, b[iB]); 117 insert(t, iB, b[iB]);
87 } 118 }
88 } 119 }
89 /* Determine the intersection point of two line segments 120 /* Determine the intersection point of two line segments
90 Return FALSE if the lines don't intersect 121 Return FALSE if the lines don't intersect
91 from: http://paulbourke.net/geometry/lineline2d/ */ 122 from: http://paulbourke.net/geometry/lineline2d/ */
92 double axLen = a[1].fX - a[0].fX; 123 double axLen = a[1].fX - a[0].fX;
93 double ayLen = a[1].fY - a[0].fY; 124 double ayLen = a[1].fY - a[0].fY;
94 double bxLen = b[1].fX - b[0].fX; 125 double bxLen = b[1].fX - b[0].fX;
95 double byLen = b[1].fY - b[0].fY; 126 double byLen = b[1].fY - b[0].fY;
96 /* Slopes match when denom goes to zero: 127 /* Slopes match when denom goes to zero:
97 axLen / ayLen == bxLen / byLen 128 axLen / ayLen == bxLen / byLen
98 (ayLen * byLen) * axLen / ayLen == (ayLen * byLen) * bxLen / byLen 129 (ayLen * byLen) * axLen / ayLen == (ayLen * byLen) * bxLen / byLen
99 byLen * axLen == ayLen * bxLen 130 byLen * axLen == ayLen * bxLen
100 byLen * axLen - ayLen * bxLen == 0 ( == denom ) 131 byLen * axLen - ayLen * bxLen == 0 ( == denom )
101 */ 132 */
102 double axByLen = axLen * byLen; 133 double axByLen = axLen * byLen;
103 double ayBxLen = ayLen * bxLen; 134 double ayBxLen = ayLen * bxLen;
104 // detect parallel lines the same way here and in SkOpAngle operator < 135 // detect parallel lines the same way here and in SkOpAngle operator <
105 // so that non-parallel means they are also sortable 136 // so that non-parallel means they are also sortable
106 bool unparallel = NotAlmostEqualUlps(axByLen, ayBxLen); 137 bool unparallel = fAllowNear ? NotAlmostEqualUlps(axByLen, ayBxLen)
107 if (unparallel) { 138 : NotAlmostDequalUlps(axByLen, ayBxLen);
139 if (unparallel && fUsed == 0) {
108 double ab0y = a[0].fY - b[0].fY; 140 double ab0y = a[0].fY - b[0].fY;
109 double ab0x = a[0].fX - b[0].fX; 141 double ab0x = a[0].fX - b[0].fX;
110 double numerA = ab0y * bxLen - byLen * ab0x; 142 double numerA = ab0y * bxLen - byLen * ab0x;
111 double numerB = ab0y * axLen - ayLen * ab0x; 143 double numerB = ab0y * axLen - ayLen * ab0x;
112 double denom = axByLen - ayBxLen; 144 double denom = axByLen - ayBxLen;
113 if (between(0, numerA, denom) && between(0, numerB, denom)) { 145 if (between(0, numerA, denom) && between(0, numerB, denom)) {
114 fT[0][0] = numerA / denom; 146 fT[0][0] = numerA / denom;
115 fT[1][0] = numerB / denom; 147 fT[1][0] = numerB / denom;
116 computePoints(a, 1); 148 computePoints(a, 1);
117 } 149 }
118 } 150 }
119 if (fAllowNear || !unparallel) { 151 if (fAllowNear || !unparallel) {
120 for (int iA = 0; iA < 2; ++iA) { 152 for (int iA = 0; iA < 2; ++iA) {
121 if ((t = b.nearPoint(a[iA])) >= 0) { 153 if ((t = b.nearPoint(a[iA])) >= 0) {
122 insert(iA, t, a[iA]); 154 insert(iA, t, a[iA]);
123 } 155 }
124 } 156 }
125 for (int iB = 0; iB < 2; ++iB) { 157 for (int iB = 0; iB < 2; ++iB) {
126 if ((t = a.nearPoint(b[iB])) >= 0) { 158 if ((t = a.nearPoint(b[iB])) >= 0) {
127 insert(t, iB, b[iB]); 159 insert(t, iB, b[iB]);
128 } 160 }
129 } 161 }
130 } 162 }
131 while (fUsed > 2) { 163 cleanUpParallelLines(!unparallel);
132 removeOne(1); 164 SkASSERT(fUsed <= 2);
133 }
134 if (fUsed == 2 && unparallel) {
135 bool startMatch = fT[0][0] == 0 || fT[1][0] == 0 || fT[1][0] == 1;
136 bool endMatch = fT[0][1] == 1 || fT[1][1] == 0 || fT[1][1] == 1;
137 if (!startMatch && !endMatch) {
138 SkASSERT(startMatch || endMatch);
139 removeOne(endMatch);
140 }
141 }
142 return fUsed; 165 return fUsed;
143 } 166 }
144 167
145 static int horizontal_coincident(const SkDLine& line, double y) { 168 static int horizontal_coincident(const SkDLine& line, double y) {
146 double min = line[0].fY; 169 double min = line[0].fY;
147 double max = line[1].fY; 170 double max = line[1].fY;
148 if (min > max) { 171 if (min > max) {
149 SkTSwap(min, max); 172 SkTSwap(min, max);
150 } 173 }
151 if (min > y || max < y) { 174 if (min > y || max < y) {
152 return 0; 175 return 0;
153 } 176 }
154 if (AlmostEqualUlps(min, max) && max - min < fabs(line[0].fX - line[1].fX)) { 177 if (AlmostEqualUlps(min, max) && max - min < fabs(line[0].fX - line[1].fX)) {
155 return 2; 178 return 2;
156 } 179 }
157 return 1; 180 return 1;
158 } 181 }
159 182
160 static double horizontal_intercept(const SkDLine& line, double y) { 183 static double horizontal_intercept(const SkDLine& line, double y) {
161 return (y - line[0].fY) / (line[1].fY - line[0].fY); 184 return (y - line[0].fY) / (line[1].fY - line[0].fY);
162 } 185 }
163 186
164 int SkIntersections::horizontal(const SkDLine& line, double y) { 187 int SkIntersections::horizontal(const SkDLine& line, double y) {
188 fMax = 2;
165 int horizontalType = horizontal_coincident(line, y); 189 int horizontalType = horizontal_coincident(line, y);
166 if (horizontalType == 1) { 190 if (horizontalType == 1) {
167 fT[0][0] = horizontal_intercept(line, y); 191 fT[0][0] = horizontal_intercept(line, y);
168 } else if (horizontalType == 2) { 192 } else if (horizontalType == 2) {
169 fT[0][0] = 0; 193 fT[0][0] = 0;
170 fT[0][1] = 1; 194 fT[0][1] = 1;
171 } 195 }
172 return fUsed = horizontalType; 196 return fUsed = horizontalType;
173 } 197 }
174 198
175 int SkIntersections::horizontal(const SkDLine& line, double left, double right, 199 int SkIntersections::horizontal(const SkDLine& line, double left, double right,
176 double y, bool flipped) { 200 double y, bool flipped) {
201 fMax = 2;
177 // see if end points intersect the opposite line 202 // see if end points intersect the opposite line
178 double t; 203 double t;
179 const SkDPoint leftPt = { left, y }; 204 const SkDPoint leftPt = { left, y };
180 if ((t = line.exactPoint(leftPt)) >= 0) { 205 if ((t = line.exactPoint(leftPt)) >= 0) {
181 insert(t, (double) flipped, leftPt); 206 insert(t, (double) flipped, leftPt);
182 } 207 }
183 if (left != right) { 208 if (left != right) {
184 const SkDPoint rightPt = { right, y }; 209 const SkDPoint rightPt = { right, y };
185 if ((t = line.exactPoint(rightPt)) >= 0) { 210 if ((t = line.exactPoint(rightPt)) >= 0) {
186 insert(t, (double) !flipped, rightPt); 211 insert(t, (double) !flipped, rightPt);
187 } 212 }
188 for (int index = 0; index < 2; ++index) { 213 for (int index = 0; index < 2; ++index) {
189 if ((t = SkDLine::ExactPointH(line[index], left, right, y)) >= 0) { 214 if ((t = SkDLine::ExactPointH(line[index], left, right, y)) >= 0) {
190 insert((double) index, flipped ? 1 - t : t, line[index]); 215 insert((double) index, flipped ? 1 - t : t, line[index]);
191 } 216 }
192 } 217 }
193 } 218 }
194 int result = horizontal_coincident(line, y); 219 int result = horizontal_coincident(line, y);
195 if (result == 1 && fUsed == 0) { 220 if (result == 1 && fUsed == 0) {
196 fT[0][0] = horizontal_intercept(line, y); 221 fT[0][0] = horizontal_intercept(line, y);
197 double xIntercept = line[0].fX + fT[0][0] * (line[1].fX - line[0].fX); 222 double xIntercept = line[0].fX + fT[0][0] * (line[1].fX - line[0].fX);
198 if (between(left, xIntercept, right)) { 223 if (between(left, xIntercept, right)) {
199 fT[1][0] = (xIntercept - left) / (right - left); 224 fT[1][0] = (xIntercept - left) / (right - left);
200 if (flipped) { 225 if (flipped) {
201 // OPTIMIZATION: ? instead of swapping, pass original line, use [1].fX - [0].fX 226 // OPTIMIZATION: ? instead of swapping, pass original line, use [1].fX - [0].fX
202 for (int index = 0; index < result; ++index) { 227 for (int index = 0; index < result; ++index) {
203 fT[1][index] = 1 - fT[1][index]; 228 fT[1][index] = 1 - fT[1][index];
204 } 229 }
205 } 230 }
206 return computePoints(line, result); 231 computePoints(line, result);
207 } 232 }
208 } 233 }
209 if (!fAllowNear && result != 2) { 234 if (fAllowNear || result == 2) {
210 return fUsed; 235 if ((t = line.nearPoint(leftPt)) >= 0) {
211 } 236 insert(t, (double) flipped, leftPt);
212 if ((t = line.nearPoint(leftPt)) >= 0) {
213 insert(t, (double) flipped, leftPt);
214 }
215 if (left != right) {
216 const SkDPoint rightPt = { right, y };
217 if ((t = line.nearPoint(rightPt)) >= 0) {
218 insert(t, (double) !flipped, rightPt);
219 } 237 }
220 for (int index = 0; index < 2; ++index) { 238 if (left != right) {
221 if ((t = SkDLine::NearPointH(line[index], left, right, y)) >= 0) { 239 const SkDPoint rightPt = { right, y };
222 insert((double) index, flipped ? 1 - t : t, line[index]); 240 if ((t = line.nearPoint(rightPt)) >= 0) {
241 insert(t, (double) !flipped, rightPt);
242 }
243 for (int index = 0; index < 2; ++index) {
244 if ((t = SkDLine::NearPointH(line[index], left, right, y)) >= 0) {
245 insert((double) index, flipped ? 1 - t : t, line[index]);
246 }
223 } 247 }
224 } 248 }
225 } 249 }
250 cleanUpParallelLines(result == 2);
226 return fUsed; 251 return fUsed;
227 } 252 }
228 253
229 static int vertical_coincident(const SkDLine& line, double x) { 254 static int vertical_coincident(const SkDLine& line, double x) {
230 double min = line[0].fX; 255 double min = line[0].fX;
231 double max = line[1].fX; 256 double max = line[1].fX;
232 if (min > max) { 257 if (min > max) {
233 SkTSwap(min, max); 258 SkTSwap(min, max);
234 } 259 }
235 if (!precisely_between(min, x, max)) { 260 if (!precisely_between(min, x, max)) {
236 return 0; 261 return 0;
237 } 262 }
238 if (AlmostEqualUlps(min, max)) { 263 if (AlmostEqualUlps(min, max)) {
239 return 2; 264 return 2;
240 } 265 }
241 return 1; 266 return 1;
242 } 267 }
243 268
244 static double vertical_intercept(const SkDLine& line, double x) { 269 static double vertical_intercept(const SkDLine& line, double x) {
245 return (x - line[0].fX) / (line[1].fX - line[0].fX); 270 return (x - line[0].fX) / (line[1].fX - line[0].fX);
246 } 271 }
247 272
248 int SkIntersections::vertical(const SkDLine& line, double x) { 273 int SkIntersections::vertical(const SkDLine& line, double x) {
274 fMax = 2;
249 int verticalType = vertical_coincident(line, x); 275 int verticalType = vertical_coincident(line, x);
250 if (verticalType == 1) { 276 if (verticalType == 1) {
251 fT[0][0] = vertical_intercept(line, x); 277 fT[0][0] = vertical_intercept(line, x);
252 } else if (verticalType == 2) { 278 } else if (verticalType == 2) {
253 fT[0][0] = 0; 279 fT[0][0] = 0;
254 fT[0][1] = 1; 280 fT[0][1] = 1;
255 } 281 }
256 return fUsed = verticalType; 282 return fUsed = verticalType;
257 } 283 }
258 284
259 int SkIntersections::vertical(const SkDLine& line, double top, double bottom, 285 int SkIntersections::vertical(const SkDLine& line, double top, double bottom,
260 double x, bool flipped) { 286 double x, bool flipped) {
287 fMax = 2;
261 // see if end points intersect the opposite line 288 // see if end points intersect the opposite line
262 double t; 289 double t;
263 SkDPoint topPt = { x, top }; 290 SkDPoint topPt = { x, top };
264 if ((t = line.exactPoint(topPt)) >= 0) { 291 if ((t = line.exactPoint(topPt)) >= 0) {
265 insert(t, (double) flipped, topPt); 292 insert(t, (double) flipped, topPt);
266 } 293 }
267 if (top != bottom) { 294 if (top != bottom) {
268 SkDPoint bottomPt = { x, bottom }; 295 SkDPoint bottomPt = { x, bottom };
269 if ((t = line.exactPoint(bottomPt)) >= 0) { 296 if ((t = line.exactPoint(bottomPt)) >= 0) {
270 insert(t, (double) !flipped, bottomPt); 297 insert(t, (double) !flipped, bottomPt);
271 } 298 }
272 for (int index = 0; index < 2; ++index) { 299 for (int index = 0; index < 2; ++index) {
273 if ((t = SkDLine::ExactPointV(line[index], top, bottom, x)) >= 0) { 300 if ((t = SkDLine::ExactPointV(line[index], top, bottom, x)) >= 0) {
274 insert((double) index, flipped ? 1 - t : t, line[index]); 301 insert((double) index, flipped ? 1 - t : t, line[index]);
275 } 302 }
276 } 303 }
277 } 304 }
278 int result = vertical_coincident(line, x); 305 int result = vertical_coincident(line, x);
279 if (result == 1 && fUsed == 0) { 306 if (result == 1 && fUsed == 0) {
280 fT[0][0] = vertical_intercept(line, x); 307 fT[0][0] = vertical_intercept(line, x);
281 double yIntercept = line[0].fY + fT[0][0] * (line[1].fY - line[0].fY); 308 double yIntercept = line[0].fY + fT[0][0] * (line[1].fY - line[0].fY);
282 if (between(top, yIntercept, bottom)) { 309 if (between(top, yIntercept, bottom)) {
283 fT[1][0] = (yIntercept - top) / (bottom - top); 310 fT[1][0] = (yIntercept - top) / (bottom - top);
284 if (flipped) { 311 if (flipped) {
285 // OPTIMIZATION: instead of swapping, pass original line, use [1 ].fY - [0].fY 312 // OPTIMIZATION: instead of swapping, pass original line, use [1 ].fY - [0].fY
286 for (int index = 0; index < result; ++index) { 313 for (int index = 0; index < result; ++index) {
287 fT[1][index] = 1 - fT[1][index]; 314 fT[1][index] = 1 - fT[1][index];
288 } 315 }
289 } 316 }
290 return computePoints(line, result); 317 computePoints(line, result);
291 } 318 }
292 } 319 }
293 if (!fAllowNear && result != 2) { 320 if (fAllowNear || result == 2) {
294 return fUsed; 321 if ((t = line.nearPoint(topPt)) >= 0) {
295 } 322 insert(t, (double) flipped, topPt);
296 if ((t = line.nearPoint(topPt)) >= 0) {
297 insert(t, (double) flipped, topPt);
298 }
299 if (top != bottom) {
300 SkDPoint bottomPt = { x, bottom };
301 if ((t = line.nearPoint(bottomPt)) >= 0) {
302 insert(t, (double) !flipped, bottomPt);
303 } 323 }
304 for (int index = 0; index < 2; ++index) { 324 if (top != bottom) {
305 if ((t = SkDLine::NearPointV(line[index], top, bottom, x)) >= 0) { 325 SkDPoint bottomPt = { x, bottom };
306 insert((double) index, flipped ? 1 - t : t, line[index]); 326 if ((t = line.nearPoint(bottomPt)) >= 0) {
327 insert(t, (double) !flipped, bottomPt);
328 }
329 for (int index = 0; index < 2; ++index) {
330 if ((t = SkDLine::NearPointV(line[index], top, bottom, x)) >= 0) {
331 insert((double) index, flipped ? 1 - t : t, line[index]);
332 }
307 } 333 }
308 } 334 }
309 } 335 }
336 cleanUpParallelLines(result == 2);
310 return fUsed; 337 return fUsed;
311 } 338 }
312 339
313 // from http://www.bryceboe.com/wordpress/wp-content/uploads/2006/10/intersect.p y 340 // from http://www.bryceboe.com/wordpress/wp-content/uploads/2006/10/intersect.p y
314 // 4 subs, 2 muls, 1 cmp 341 // 4 subs, 2 muls, 1 cmp
315 static bool ccw(const SkDPoint& A, const SkDPoint& B, const SkDPoint& C) { 342 static bool ccw(const SkDPoint& A, const SkDPoint& B, const SkDPoint& C) {
316 return (C.fY - A.fY) * (B.fX - A.fX) > (B.fY - A.fY) * (C.fX - A.fX); 343 return (C.fY - A.fY) * (B.fX - A.fX) > (B.fY - A.fY) * (C.fX - A.fX);
317 } 344 }
318 345
319 // 16 subs, 8 muls, 6 cmps 346 // 16 subs, 8 muls, 6 cmps
320 bool SkIntersections::Test(const SkDLine& a, const SkDLine& b) { 347 bool SkIntersections::Test(const SkDLine& a, const SkDLine& b) {
321 return ccw(a[0], b[0], b[1]) != ccw(a[1], b[0], b[1]) 348 return ccw(a[0], b[0], b[1]) != ccw(a[1], b[0], b[1])
322 && ccw(a[0], a[1], b[0]) != ccw(a[0], a[1], b[1]); 349 && ccw(a[0], a[1], b[0]) != ccw(a[0], a[1], b[1]);
323 } 350 }
OLDNEW
« no previous file with comments | « src/pathops/SkDCubicLineIntersection.cpp ('k') | src/pathops/SkDQuadImplicit.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698