Flutter Engine
The Flutter Engine
Public Types | Public Member Functions | Protected Member Functions | List of all members
LineConicIntersections Class Reference

Public Types

enum  PinTPoint { kPointUninitialized , kPointInitialized }
 

Public Member Functions

 LineConicIntersections (const SkDConic &c, const SkDLine &l, SkIntersections *i)
 
 LineConicIntersections (const SkDConic &c)
 
void allowNear (bool allow)
 
void checkCoincident ()
 
int horizontalIntersect (double axisIntercept, double roots[2])
 
int horizontalIntersect (double axisIntercept, double left, double right, bool flipped)
 
int intersect ()
 
int intersectRay (double roots[2])
 
int validT (double r[3], double axisIntercept, double roots[2])
 
int verticalIntersect (double axisIntercept, double roots[2])
 
int verticalIntersect (double axisIntercept, double top, double bottom, bool flipped)
 

Protected Member Functions

void addExactEndPoints ()
 
void addNearEndPoints ()
 
void addLineNearEndPoints ()
 
void addExactHorizontalEndPoints (double left, double right, double y)
 
void addNearHorizontalEndPoints (double left, double right, double y)
 
void addExactVerticalEndPoints (double top, double bottom, double x)
 
void addNearVerticalEndPoints (double top, double bottom, double x)
 
double findLineT (double t)
 
bool pinTs (double *conicT, double *lineT, SkDPoint *pt, PinTPoint ptSet)
 
bool uniqueAnswer (double conicT, const SkDPoint &pt)
 

Detailed Description

Definition at line 24 of file SkDConicLineIntersection.cpp.

Member Enumeration Documentation

◆ PinTPoint

Enumerator
kPointUninitialized 
kPointInitialized 

Definition at line 26 of file SkDConicLineIntersection.cpp.

Constructor & Destructor Documentation

◆ LineConicIntersections() [1/2]

LineConicIntersections::LineConicIntersections ( const SkDConic c,
const SkDLine l,
SkIntersections i 
)
inline

Definition at line 31 of file SkDConicLineIntersection.cpp.

32 : fConic(c)
33 , fLine(&l)
34 , fIntersections(i)
35 , fAllowNear(true) {
36 i->setMax(4); // allow short partial coincidence plus discrete intersection
37 }

◆ LineConicIntersections() [2/2]

LineConicIntersections::LineConicIntersections ( const SkDConic c)
inline

Definition at line 39 of file SkDConicLineIntersection.cpp.

40 : fConic(c)
41 SkDEBUGPARAMS(fLine(nullptr))
42 SkDEBUGPARAMS(fIntersections(nullptr))
43 SkDEBUGPARAMS(fAllowNear(false)) {
44 }
#define SkDEBUGPARAMS(...)

Member Function Documentation

◆ addExactEndPoints()

void LineConicIntersections::addExactEndPoints ( )
inlineprotected

Definition at line 190 of file SkDConicLineIntersection.cpp.

190 {
191 for (int cIndex = 0; cIndex < SkDConic::kPointCount; cIndex += SkDConic::kPointLast) {
192 double lineT = fLine->exactPoint(fConic[cIndex]);
193 if (lineT < 0) {
194 continue;
195 }
196 double conicT = (double) (cIndex >> 1);
197 fIntersections->insert(conicT, lineT, fConic[cIndex]);
198 }
199 }
int insert(double one, double two, const SkDPoint &pt)
static const int kPointCount
static const int kPointLast
double exactPoint(const SkDPoint &xy) const

◆ addExactHorizontalEndPoints()

void LineConicIntersections::addExactHorizontalEndPoints ( double  left,
double  right,
double  y 
)
inlineprotected

Definition at line 231 of file SkDConicLineIntersection.cpp.

231 {
232 for (int cIndex = 0; cIndex < SkDConic::kPointCount; cIndex += SkDConic::kPointLast) {
233 double lineT = SkDLine::ExactPointH(fConic[cIndex], left, right, y);
234 if (lineT < 0) {
235 continue;
236 }
237 double conicT = (double) (cIndex >> 1);
238 fIntersections->insert(conicT, lineT, fConic[cIndex]);
239 }
240 }
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
double y
static double ExactPointH(const SkDPoint &xy, double left, double right, double y)

◆ addExactVerticalEndPoints()

void LineConicIntersections::addExactVerticalEndPoints ( double  top,
double  bottom,
double  x 
)
inlineprotected

Definition at line 257 of file SkDConicLineIntersection.cpp.

257 {
258 for (int cIndex = 0; cIndex < SkDConic::kPointCount; cIndex += SkDConic::kPointLast) {
259 double lineT = SkDLine::ExactPointV(fConic[cIndex], top, bottom, x);
260 if (lineT < 0) {
261 continue;
262 }
263 double conicT = (double) (cIndex >> 1);
264 fIntersections->insert(conicT, lineT, fConic[cIndex]);
265 }
266 }
double x
static double ExactPointV(const SkDPoint &xy, double top, double bottom, double x)

◆ addLineNearEndPoints()

void LineConicIntersections::addLineNearEndPoints ( )
inlineprotected

Definition at line 216 of file SkDConicLineIntersection.cpp.

216 {
217 for (int lIndex = 0; lIndex < 2; ++lIndex) {
218 double lineT = (double) lIndex;
219 if (fIntersections->hasOppT(lineT)) {
220 continue;
221 }
222 double conicT = ((const SkDCurve*) &fConic)->nearPoint(SkPath::kConic_Verb,
223 (*fLine)[lIndex], (*fLine)[!lIndex]);
224 if (conicT < 0) {
225 continue;
226 }
227 fIntersections->insert(conicT, lineT, (*fLine)[lIndex]);
228 }
229 }
bool hasOppT(double t) const
@ kConic_Verb
Definition: SkPath.h:1469

◆ addNearEndPoints()

void LineConicIntersections::addNearEndPoints ( )
inlineprotected

Definition at line 201 of file SkDConicLineIntersection.cpp.

201 {
202 for (int cIndex = 0; cIndex < SkDConic::kPointCount; cIndex += SkDConic::kPointLast) {
203 double conicT = (double) (cIndex >> 1);
204 if (fIntersections->hasT(conicT)) {
205 continue;
206 }
207 double lineT = fLine->nearPoint(fConic[cIndex], nullptr);
208 if (lineT < 0) {
209 continue;
210 }
211 fIntersections->insert(conicT, lineT, fConic[cIndex]);
212 }
213 this->addLineNearEndPoints();
214 }
bool hasT(double t) const
double nearPoint(const SkDPoint &xy, bool *unequal) const

◆ addNearHorizontalEndPoints()

void LineConicIntersections::addNearHorizontalEndPoints ( double  left,
double  right,
double  y 
)
inlineprotected

Definition at line 242 of file SkDConicLineIntersection.cpp.

242 {
243 for (int cIndex = 0; cIndex < SkDConic::kPointCount; cIndex += SkDConic::kPointLast) {
244 double conicT = (double) (cIndex >> 1);
245 if (fIntersections->hasT(conicT)) {
246 continue;
247 }
248 double lineT = SkDLine::NearPointH(fConic[cIndex], left, right, y);
249 if (lineT < 0) {
250 continue;
251 }
252 fIntersections->insert(conicT, lineT, fConic[cIndex]);
253 }
254 this->addLineNearEndPoints();
255 }
static double NearPointH(const SkDPoint &xy, double left, double right, double y)

◆ addNearVerticalEndPoints()

void LineConicIntersections::addNearVerticalEndPoints ( double  top,
double  bottom,
double  x 
)
inlineprotected

Definition at line 268 of file SkDConicLineIntersection.cpp.

268 {
269 for (int cIndex = 0; cIndex < SkDConic::kPointCount; cIndex += SkDConic::kPointLast) {
270 double conicT = (double) (cIndex >> 1);
271 if (fIntersections->hasT(conicT)) {
272 continue;
273 }
274 double lineT = SkDLine::NearPointV(fConic[cIndex], top, bottom, x);
275 if (lineT < 0) {
276 continue;
277 }
278 fIntersections->insert(conicT, lineT, fConic[cIndex]);
279 }
280 this->addLineNearEndPoints();
281 }
static double NearPointV(const SkDPoint &xy, double top, double bottom, double x)

◆ allowNear()

void LineConicIntersections::allowNear ( bool  allow)
inline

Definition at line 46 of file SkDConicLineIntersection.cpp.

46 {
47 fAllowNear = allow;
48 }

◆ checkCoincident()

void LineConicIntersections::checkCoincident ( )
inline

Definition at line 50 of file SkDConicLineIntersection.cpp.

50 {
51 int last = fIntersections->used() - 1;
52 for (int index = 0; index < last; ) {
53 double conicMidT = ((*fIntersections)[0][index] + (*fIntersections)[0][index + 1]) / 2;
54 SkDPoint conicMidPt = fConic.ptAtT(conicMidT);
55 double t = fLine->nearPoint(conicMidPt, nullptr);
56 if (t < 0) {
57 ++index;
58 continue;
59 }
60 if (fIntersections->isCoincident(index)) {
61 fIntersections->removeOne(index);
62 --last;
63 } else if (fIntersections->isCoincident(index + 1)) {
64 fIntersections->removeOne(index + 1);
65 --last;
66 } else {
67 fIntersections->setCoincident(index++);
68 }
69 fIntersections->setCoincident(index);
70 }
71 }
void removeOne(int index)
int used() const
void setCoincident(int index)
bool isCoincident(int index)
SkDPoint ptAtT(double t) const

◆ findLineT()

double LineConicIntersections::findLineT ( double  t)
inlineprotected

Definition at line 283 of file SkDConicLineIntersection.cpp.

283 {
284 SkDPoint xy = fConic.ptAtT(t);
285 double dx = (*fLine)[1].fX - (*fLine)[0].fX;
286 double dy = (*fLine)[1].fY - (*fLine)[0].fY;
287 if (fabs(dx) > fabs(dy)) {
288 return (xy.fX - (*fLine)[0].fX) / dx;
289 }
290 return (xy.fY - (*fLine)[0].fY) / dy;
291 }
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208

◆ horizontalIntersect() [1/2]

int LineConicIntersections::horizontalIntersect ( double  axisIntercept,
double  left,
double  right,
bool  flipped 
)
inline

Definition at line 84 of file SkDConicLineIntersection.cpp.

84 {
85 this->addExactHorizontalEndPoints(left, right, axisIntercept);
86 if (fAllowNear) {
87 this->addNearHorizontalEndPoints(left, right, axisIntercept);
88 }
89 double roots[2];
90 int count = this->horizontalIntersect(axisIntercept, roots);
91 for (int index = 0; index < count; ++index) {
92 double conicT = roots[index];
93 SkDPoint pt = fConic.ptAtT(conicT);
94 SkDEBUGCODE(double conicVals[] = { fConic[0].fY, fConic[1].fY, fConic[2].fY });
95 SkOPOBJASSERT(fIntersections, close_to(pt.fY, axisIntercept, conicVals));
96 double lineT = (pt.fX - left) / (right - left);
97 if (this->pinTs(&conicT, &lineT, &pt, kPointInitialized)
98 && this->uniqueAnswer(conicT, pt)) {
99 fIntersections->insert(conicT, lineT, pt);
100 }
101 }
102 if (flipped) {
103 fIntersections->flip();
104 }
105 this->checkCoincident();
106 return fIntersections->used();
107 }
int count
Definition: FontMgrTest.cpp:50
#define SkOPOBJASSERT(obj, cond)
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
void addNearHorizontalEndPoints(double left, double right, double y)
int horizontalIntersect(double axisIntercept, double roots[2])
void addExactHorizontalEndPoints(double left, double right, double y)
bool uniqueAnswer(double conicT, const SkDPoint &pt)
bool pinTs(double *conicT, double *lineT, SkDPoint *pt, PinTPoint ptSet)

◆ horizontalIntersect() [2/2]

int LineConicIntersections::horizontalIntersect ( double  axisIntercept,
double  roots[2] 
)
inline

Definition at line 79 of file SkDConicLineIntersection.cpp.

79 {
80 double conicVals[] = { fConic[0].fY, fConic[1].fY, fConic[2].fY };
81 return this->validT(conicVals, axisIntercept, roots);
82 }
int validT(double r[3], double axisIntercept, double roots[2])

◆ intersect()

int LineConicIntersections::intersect ( )
inline

Definition at line 109 of file SkDConicLineIntersection.cpp.

109 {
110 this->addExactEndPoints();
111 if (fAllowNear) {
112 this->addNearEndPoints();
113 }
114 double rootVals[2];
115 int roots = this->intersectRay(rootVals);
116 for (int index = 0; index < roots; ++index) {
117 double conicT = rootVals[index];
118 double lineT = this->findLineT(conicT);
119#ifdef SK_DEBUG
120 if (!fIntersections->globalState()
121 || !fIntersections->globalState()->debugSkipAssert()) {
122 SkDEBUGCODE(SkDPoint conicPt = fConic.ptAtT(conicT));
123 SkDEBUGCODE(SkDPoint linePt = fLine->ptAtT(lineT));
124 SkASSERT(conicPt.approximatelyDEqual(linePt));
125 }
126#endif
127 SkDPoint pt;
128 if (this->pinTs(&conicT, &lineT, &pt, kPointUninitialized)
129 && this->uniqueAnswer(conicT, pt)) {
130 fIntersections->insert(conicT, lineT, pt);
131 }
132 }
133 this->checkCoincident();
134 return fIntersections->used();
135 }
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkDPoint ptAtT(double t) const

◆ intersectRay()

int LineConicIntersections::intersectRay ( double  roots[2])
inline

Definition at line 137 of file SkDConicLineIntersection.cpp.

137 {
138 double adj = (*fLine)[1].fX - (*fLine)[0].fX;
139 double opp = (*fLine)[1].fY - (*fLine)[0].fY;
140 double r[3];
141 for (int n = 0; n < 3; ++n) {
142 r[n] = (fConic[n].fY - (*fLine)[0].fY) * adj - (fConic[n].fX - (*fLine)[0].fX) * opp;
143 }
144 return this->validT(r, 0, roots);
145 }

◆ pinTs()

bool LineConicIntersections::pinTs ( double *  conicT,
double *  lineT,
SkDPoint pt,
PinTPoint  ptSet 
)
inlineprotected

Definition at line 293 of file SkDConicLineIntersection.cpp.

293 {
295 return false;
296 }
298 return false;
299 }
300 double qT = *conicT = SkPinT(*conicT);
301 double lT = *lineT = SkPinT(*lineT);
302 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && qT != 0 && qT != 1)) {
303 *pt = (*fLine).ptAtT(lT);
304 } else if (ptSet == kPointUninitialized) {
305 *pt = fConic.ptAtT(qT);
306 }
307 SkPoint gridPt = pt->asSkPoint();
308 if (SkDPoint::ApproximatelyEqual(gridPt, (*fLine)[0].asSkPoint())) {
309 *pt = (*fLine)[0];
310 *lineT = 0;
311 } else if (SkDPoint::ApproximatelyEqual(gridPt, (*fLine)[1].asSkPoint())) {
312 *pt = (*fLine)[1];
313 *lineT = 1;
314 }
315 if (fIntersections->used() > 0 && approximately_equal((*fIntersections)[1][0], *lineT)) {
316 return false;
317 }
318 if (gridPt == fConic[0].asSkPoint()) {
319 *pt = fConic[0];
320 *conicT = 0;
321 } else if (gridPt == fConic[2].asSkPoint()) {
322 *pt = fConic[2];
323 *conicT = 1;
324 }
325 return true;
326 }
bool approximately_equal(double x, double y)
bool approximately_one_or_less_double(double x)
double SkPinT(double t)
bool approximately_zero_or_more_double(double x)
SkPoint asSkPoint() const
static bool ApproximatelyEqual(const SkPoint &a, const SkPoint &b)

◆ uniqueAnswer()

bool LineConicIntersections::uniqueAnswer ( double  conicT,
const SkDPoint pt 
)
inlineprotected

Definition at line 328 of file SkDConicLineIntersection.cpp.

328 {
329 for (int inner = 0; inner < fIntersections->used(); ++inner) {
330 if (fIntersections->pt(inner) != pt) {
331 continue;
332 }
333 double existingConicT = (*fIntersections)[0][inner];
334 if (conicT == existingConicT) {
335 return false;
336 }
337 // check if midway on conic is also same point. If so, discard this
338 double conicMidT = (existingConicT + conicT) / 2;
339 SkDPoint conicMidPt = fConic.ptAtT(conicMidT);
340 if (conicMidPt.approximatelyEqual(pt)) {
341 return false;
342 }
343 }
344#if ONE_OFF_DEBUG
345 SkDPoint qPt = fConic.ptAtT(conicT);
346 SkDebugf("%s pt=(%1.9g,%1.9g) cPt=(%1.9g,%1.9g)\n", __FUNCTION__, pt.fX, pt.fY,
347 qPt.fX, qPt.fY);
348#endif
349 return true;
350 }
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
const SkDPoint & pt(int index) const
bool approximatelyEqual(const SkDPoint &a) const

◆ validT()

int LineConicIntersections::validT ( double  r[3],
double  axisIntercept,
double  roots[2] 
)
inline

Definition at line 147 of file SkDConicLineIntersection.cpp.

147 {
148 double A = r[2];
149 double B = r[1] * fConic.fWeight - axisIntercept * fConic.fWeight + axisIntercept;
150 double C = r[0];
151 A += C - 2 * B; // A = a + c - 2*(b*w - xCept*w + xCept)
152 B -= C; // B = b*w - w * xCept + xCept - a
153 C -= axisIntercept;
154 return SkDQuad::RootsValidT(A, 2 * B, C, roots);
155 }
#define C(TEST_CATEGORY)
Definition: colrv1.cpp:248
#define B
SkScalar fWeight
static int RootsValidT(const double A, const double B, const double C, double s[2])

◆ verticalIntersect() [1/2]

int LineConicIntersections::verticalIntersect ( double  axisIntercept,
double  roots[2] 
)
inline

Definition at line 157 of file SkDConicLineIntersection.cpp.

157 {
158 double conicVals[] = { fConic[0].fX, fConic[1].fX, fConic[2].fX };
159 return this->validT(conicVals, axisIntercept, roots);
160 }

◆ verticalIntersect() [2/2]

int LineConicIntersections::verticalIntersect ( double  axisIntercept,
double  top,
double  bottom,
bool  flipped 
)
inline

Definition at line 162 of file SkDConicLineIntersection.cpp.

162 {
163 this->addExactVerticalEndPoints(top, bottom, axisIntercept);
164 if (fAllowNear) {
165 this->addNearVerticalEndPoints(top, bottom, axisIntercept);
166 }
167 double roots[2];
168 int count = this->verticalIntersect(axisIntercept, roots);
169 for (int index = 0; index < count; ++index) {
170 double conicT = roots[index];
171 SkDPoint pt = fConic.ptAtT(conicT);
172 SkDEBUGCODE(double conicVals[] = { fConic[0].fX, fConic[1].fX, fConic[2].fX });
173 SkOPOBJASSERT(fIntersections, close_to(pt.fX, axisIntercept, conicVals));
174 double lineT = (pt.fY - top) / (bottom - top);
175 if (this->pinTs(&conicT, &lineT, &pt, kPointInitialized)
176 && this->uniqueAnswer(conicT, pt)) {
177 fIntersections->insert(conicT, lineT, pt);
178 }
179 }
180 if (flipped) {
181 fIntersections->flip();
182 }
183 this->checkCoincident();
184 return fIntersections->used();
185 }
void addNearVerticalEndPoints(double top, double bottom, double x)
int verticalIntersect(double axisIntercept, double roots[2])
void addExactVerticalEndPoints(double top, double bottom, double x)

The documentation for this class was generated from the following file: