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

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

Issue 853223002: new files for pathops geometric intersection (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: remove visualizer tool so cl contains only pure adds Created 5 years, 11 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
« no previous file with comments | « src/pathops/SkOpCoincidence.h ('k') | src/pathops/SkOpTAllocator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7 #include "SkPathOpsCubic.h"
8
9 static bool rotate(const SkDCubic& cubic, int zero, int index, SkDCubic& rotPath ) {
10 double dy = cubic[index].fY - cubic[zero].fY;
11 double dx = cubic[index].fX - cubic[zero].fX;
12 if (approximately_zero(dy)) {
13 if (approximately_zero(dx)) {
14 return false;
15 }
16 rotPath = cubic;
17 return true;
18 }
19 for (int index = 0; index < 4; ++index) {
20 rotPath[index].fX = cubic[index].fX * dx + cubic[index].fY * dy;
21 rotPath[index].fY = cubic[index].fY * dx - cubic[index].fX * dy;
22 }
23 return true;
24 }
25
26
27 // Returns 0 if negative, 1 if zero, 2 if positive
28 static int side(double x) {
29 return (x > 0) + (x >= 0);
30 }
31
32 /* Given a cubic, find the convex hull described by the end and control points.
33 The hull may have 3 or 4 points. Cubics that degenerate into a point or line
34 are not considered.
35
36 The hull is computed by assuming that three points, if unique and non-linear,
37 form a triangle. The fourth point may replace one of the first three, may be
38 discarded if in the triangle or on an edge, or may be inserted between any of
39 the three to form a convex quadralateral.
40
41 The indices returned in order describe the convex hull.
42 */
43 int SkDCubic::convexHull(char order[4]) const {
44 size_t index;
45 // find top point
46 size_t yMin = 0;
47 for (index = 1; index < 4; ++index) {
48 if (fPts[yMin].fY > fPts[index].fY || (fPts[yMin].fY == fPts[index].fY
49 && fPts[yMin].fX > fPts[index].fX)) {
50 yMin = index;
51 }
52 }
53 order[0] = yMin;
54 int midX = -1;
55 int backupYMin = -1;
56 for (int pass = 0; pass < 2; ++pass) {
57 for (index = 0; index < 4; ++index) {
58 if (index == yMin) {
59 continue;
60 }
61 // rotate line from (yMin, index) to axis
62 // see if remaining two points are both above or below
63 // use this to find mid
64 int mask = other_two(yMin, index);
65 int side1 = yMin ^ mask;
66 int side2 = index ^ mask;
67 SkDCubic rotPath;
68 if (!rotate(*this, yMin, index, rotPath)) { // ! if cbc[yMin]==cbc[i dx]
69 order[1] = side1;
70 order[2] = side2;
71 return 3;
72 }
73 int sides = side(rotPath[side1].fY - rotPath[yMin].fY);
74 sides ^= side(rotPath[side2].fY - rotPath[yMin].fY);
75 if (sides == 2) { // '2' means one remaining point <0, one >0
76 if (midX >= 0) {
77 // one of the control points is equal to an end point
78 order[0] = 0;
79 order[1] = 3;
80 if (fPts[1] == fPts[0] || fPts[1] == fPts[3]) {
81 order[2] = 2;
82 return 3;
83 }
84 SkASSERT(fPts[2] == fPts[0] || fPts[2] == fPts[3]);
85 order[2] = 1;
86 return 3;
87 }
88 midX = index;
89 } else if (sides == 0) { // '0' means both to one side or the other
90 backupYMin = index;
91 }
92 }
93 if (midX >= 0) {
94 break;
95 }
96 if (backupYMin < 0) {
97 break;
98 }
99 yMin = backupYMin;
100 backupYMin = -1;
101 }
102 if (midX < 0) {
103 midX = yMin ^ 3; // choose any other point
104 }
105 int mask = other_two(yMin, midX);
106 int least = yMin ^ mask;
107 int most = midX ^ mask;
108 order[0] = yMin;
109 order[1] = least;
110
111 // see if mid value is on same side of line (least, most) as yMin
112 SkDCubic midPath;
113 if (!rotate(*this, least, most, midPath)) { // ! if cbc[least]==cbc[most]
114 order[2] = midX;
115 return 3;
116 }
117 int midSides = side(midPath[yMin].fY - midPath[least].fY);
118 midSides ^= side(midPath[midX].fY - midPath[least].fY);
119 if (midSides != 2) { // if mid point is not between
120 order[2] = most;
121 return 3; // result is a triangle
122 }
123 order[2] = midX;
124 order[3] = most;
125 return 4; // result is a quadralateral
126 }
OLDNEW
« no previous file with comments | « src/pathops/SkOpCoincidence.h ('k') | src/pathops/SkOpTAllocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698