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

Side by Side Diff: src/pathops/SkLineParameters.h

Issue 131103009: update pathops to circle sort (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: disable old test that still fails on linux 32 release Created 6 years, 8 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/SkIntersections.cpp ('k') | src/pathops/SkOpAngle.h » ('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 "SkPathOpsCubic.h" 7 #include "SkPathOpsCubic.h"
8 #include "SkPathOpsLine.h" 8 #include "SkPathOpsLine.h"
9 #include "SkPathOpsQuad.h" 9 #include "SkPathOpsQuad.h"
10 10
11 // Sources 11 // Sources
12 // computer-aided design - volume 22 number 9 november 1990 pp 538 - 549 12 // computer-aided design - volume 22 number 9 november 1990 pp 538 - 549
13 // online at http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf 13 // online at http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf
14 14
15 // This turns a line segment into a parameterized line, of the form 15 // This turns a line segment into a parameterized line, of the form
16 // ax + by + c = 0 16 // ax + by + c = 0
17 // When a^2 + b^2 == 1, the line is normalized. 17 // When a^2 + b^2 == 1, the line is normalized.
18 // The distance to the line for (x, y) is d(x,y) = ax + by + c 18 // The distance to the line for (x, y) is d(x,y) = ax + by + c
19 // 19 //
20 // Note that the distances below are not necessarily normalized. To get the true 20 // Note that the distances below are not necessarily normalized. To get the true
21 // distance, it's necessary to either call normalize() after xxxEndPoints(), or 21 // distance, it's necessary to either call normalize() after xxxEndPoints(), or
22 // divide the result of xxxDistance() by sqrt(normalSquared()) 22 // divide the result of xxxDistance() by sqrt(normalSquared())
23 23
24 class SkLineParameters { 24 class SkLineParameters {
25 public: 25 public:
26 26
27 void cubicEndPoints(const SkDCubic& pts) { 27 bool cubicEndPoints(const SkDCubic& pts) {
28 int endIndex = 1; 28 int endIndex = 1;
29 cubicEndPoints(pts, 0, endIndex); 29 cubicEndPoints(pts, 0, endIndex);
30 if (dy() != 0) { 30 if (dy() != 0) {
31 return; 31 return true;
32 } 32 }
33 if (dx() == 0) { 33 if (dx() == 0) {
34 cubicEndPoints(pts, 0, ++endIndex); 34 cubicEndPoints(pts, 0, ++endIndex);
35 SkASSERT(endIndex == 2); 35 SkASSERT(endIndex == 2);
36 if (dy() != 0) { 36 if (dy() != 0) {
37 return; 37 return true;
38 } 38 }
39 if (dx() == 0) { 39 if (dx() == 0) {
40 cubicEndPoints(pts, 0, ++endIndex); // line 40 cubicEndPoints(pts, 0, ++endIndex); // line
41 SkASSERT(endIndex == 3); 41 SkASSERT(endIndex == 3);
42 return; 42 return false;
43 } 43 }
44 } 44 }
45 // FIXME: after switching to round sort, remove bumping fA
45 if (dx() < 0) { // only worry about y bias when breaking cw/ccw tie 46 if (dx() < 0) { // only worry about y bias when breaking cw/ccw tie
46 return; 47 return true;
47 } 48 }
48 // if cubic tangent is on x axis, look at next control point to break ti e 49 // if cubic tangent is on x axis, look at next control point to break ti e
49 // control point may be approximate, so it must move significantly to ac count for error 50 // control point may be approximate, so it must move significantly to ac count for error
50 if (NotAlmostEqualUlps(pts[0].fY, pts[++endIndex].fY)) { 51 if (NotAlmostEqualUlps(pts[0].fY, pts[++endIndex].fY)) {
51 if (pts[0].fY > pts[endIndex].fY) { 52 if (pts[0].fY > pts[endIndex].fY) {
52 a = DBL_EPSILON; // push it from 0 to slightly negative (y() ret urns -a) 53 fA = DBL_EPSILON; // push it from 0 to slightly negative (y() re turns -a)
53 } 54 }
54 return; 55 return true;
55 } 56 }
56 if (endIndex == 3) { 57 if (endIndex == 3) {
57 return; 58 return true;
58 } 59 }
59 SkASSERT(endIndex == 2); 60 SkASSERT(endIndex == 2);
60 if (pts[0].fY > pts[3].fY) { 61 if (pts[0].fY > pts[3].fY) {
61 a = DBL_EPSILON; // push it from 0 to slightly negative (y() returns -a) 62 fA = DBL_EPSILON; // push it from 0 to slightly negative (y() return s -a)
62 } 63 }
64 return true;
63 } 65 }
64 66
65 void cubicEndPoints(const SkDCubic& pts, int s, int e) { 67 void cubicEndPoints(const SkDCubic& pts, int s, int e) {
66 a = pts[s].fY - pts[e].fY; 68 fA = pts[s].fY - pts[e].fY;
67 b = pts[e].fX - pts[s].fX; 69 fB = pts[e].fX - pts[s].fX;
68 c = pts[s].fX * pts[e].fY - pts[e].fX * pts[s].fY; 70 fC = pts[s].fX * pts[e].fY - pts[e].fX * pts[s].fY;
69 } 71 }
70 72
71 double cubicPart(const SkDCubic& part) { 73 double cubicPart(const SkDCubic& part) {
72 cubicEndPoints(part); 74 cubicEndPoints(part);
73 if (part[0] == part[1] || ((const SkDLine& ) part[0]).nearRay(part[2])) { 75 if (part[0] == part[1] || ((const SkDLine& ) part[0]).nearRay(part[2])) {
74 return pointDistance(part[3]); 76 return pointDistance(part[3]);
75 } 77 }
76 return pointDistance(part[2]); 78 return pointDistance(part[2]);
77 } 79 }
78 80
79 void lineEndPoints(const SkDLine& pts) { 81 void lineEndPoints(const SkDLine& pts) {
80 a = pts[0].fY - pts[1].fY; 82 fA = pts[0].fY - pts[1].fY;
81 b = pts[1].fX - pts[0].fX; 83 fB = pts[1].fX - pts[0].fX;
82 c = pts[0].fX * pts[1].fY - pts[1].fX * pts[0].fY; 84 fC = pts[0].fX * pts[1].fY - pts[1].fX * pts[0].fY;
83 } 85 }
84 86
85 void quadEndPoints(const SkDQuad& pts) { 87 bool quadEndPoints(const SkDQuad& pts) {
86 quadEndPoints(pts, 0, 1); 88 quadEndPoints(pts, 0, 1);
87 if (dy() != 0) { 89 if (dy() != 0) {
88 return; 90 return true;
89 } 91 }
90 if (dx() == 0) { 92 if (dx() == 0) {
91 quadEndPoints(pts, 0, 2); 93 quadEndPoints(pts, 0, 2);
92 return; 94 return false;
93 } 95 }
94 if (dx() < 0) { // only worry about y bias when breaking cw/ccw tie 96 if (dx() < 0) { // only worry about y bias when breaking cw/ccw tie
95 return; 97 return true;
96 } 98 }
99 // FIXME: after switching to round sort, remove this
97 if (pts[0].fY > pts[2].fY) { 100 if (pts[0].fY > pts[2].fY) {
98 a = DBL_EPSILON; 101 fA = DBL_EPSILON;
99 } 102 }
103 return true;
100 } 104 }
101 105
102 void quadEndPoints(const SkDQuad& pts, int s, int e) { 106 void quadEndPoints(const SkDQuad& pts, int s, int e) {
103 a = pts[s].fY - pts[e].fY; 107 fA = pts[s].fY - pts[e].fY;
104 b = pts[e].fX - pts[s].fX; 108 fB = pts[e].fX - pts[s].fX;
105 c = pts[s].fX * pts[e].fY - pts[e].fX * pts[s].fY; 109 fC = pts[s].fX * pts[e].fY - pts[e].fX * pts[s].fY;
106 } 110 }
107 111
108 double quadPart(const SkDQuad& part) { 112 double quadPart(const SkDQuad& part) {
109 quadEndPoints(part); 113 quadEndPoints(part);
110 return pointDistance(part[2]); 114 return pointDistance(part[2]);
111 } 115 }
112 116
113 double normalSquared() const { 117 double normalSquared() const {
114 return a * a + b * b; 118 return fA * fA + fB * fB;
115 } 119 }
116 120
117 bool normalize() { 121 bool normalize() {
118 double normal = sqrt(normalSquared()); 122 double normal = sqrt(normalSquared());
119 if (approximately_zero(normal)) { 123 if (approximately_zero(normal)) {
120 a = b = c = 0; 124 fA = fB = fC = 0;
121 return false; 125 return false;
122 } 126 }
123 double reciprocal = 1 / normal; 127 double reciprocal = 1 / normal;
124 a *= reciprocal; 128 fA *= reciprocal;
125 b *= reciprocal; 129 fB *= reciprocal;
126 c *= reciprocal; 130 fC *= reciprocal;
127 return true; 131 return true;
128 } 132 }
129 133
130 void cubicDistanceY(const SkDCubic& pts, SkDCubic& distance) const { 134 void cubicDistanceY(const SkDCubic& pts, SkDCubic& distance) const {
131 double oneThird = 1 / 3.0; 135 double oneThird = 1 / 3.0;
132 for (int index = 0; index < 4; ++index) { 136 for (int index = 0; index < 4; ++index) {
133 distance[index].fX = index * oneThird; 137 distance[index].fX = index * oneThird;
134 distance[index].fY = a * pts[index].fX + b * pts[index].fY + c; 138 distance[index].fY = fA * pts[index].fX + fB * pts[index].fY + fC;
135 } 139 }
136 } 140 }
137 141
138 void quadDistanceY(const SkDQuad& pts, SkDQuad& distance) const { 142 void quadDistanceY(const SkDQuad& pts, SkDQuad& distance) const {
139 double oneHalf = 1 / 2.0; 143 double oneHalf = 1 / 2.0;
140 for (int index = 0; index < 3; ++index) { 144 for (int index = 0; index < 3; ++index) {
141 distance[index].fX = index * oneHalf; 145 distance[index].fX = index * oneHalf;
142 distance[index].fY = a * pts[index].fX + b * pts[index].fY + c; 146 distance[index].fY = fA * pts[index].fX + fB * pts[index].fY + fC;
143 } 147 }
144 } 148 }
145 149
146 double controlPtDistance(const SkDCubic& pts, int index) const { 150 double controlPtDistance(const SkDCubic& pts, int index) const {
147 SkASSERT(index == 1 || index == 2); 151 SkASSERT(index == 1 || index == 2);
148 return a * pts[index].fX + b * pts[index].fY + c; 152 return fA * pts[index].fX + fB * pts[index].fY + fC;
149 } 153 }
150 154
151 double controlPtDistance(const SkDQuad& pts) const { 155 double controlPtDistance(const SkDQuad& pts) const {
152 return a * pts[1].fX + b * pts[1].fY + c; 156 return fA * pts[1].fX + fB * pts[1].fY + fC;
153 } 157 }
154 158
155 double pointDistance(const SkDPoint& pt) const { 159 double pointDistance(const SkDPoint& pt) const {
156 return a * pt.fX + b * pt.fY + c; 160 return fA * pt.fX + fB * pt.fY + fC;
157 } 161 }
158 162
159 double dx() const { 163 double dx() const {
160 return b; 164 return fB;
161 } 165 }
162 166
163 double dy() const { 167 double dy() const {
164 return -a; 168 return -fA;
165 } 169 }
166 170
167 private: 171 private:
168 double a; 172 double fA;
169 double b; 173 double fB;
170 double c; 174 double fC;
171 }; 175 };
OLDNEW
« no previous file with comments | « src/pathops/SkIntersections.cpp ('k') | src/pathops/SkOpAngle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698