2012-08-27 14:11:33 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2012 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
2012-03-28 16:20:21 +00:00
|
|
|
#ifndef Intersections_DEFINE
|
|
|
|
#define Intersections_DEFINE
|
|
|
|
|
2012-01-10 21:46:10 +00:00
|
|
|
class Intersections {
|
|
|
|
public:
|
2013-01-20 07:05:51 +00:00
|
|
|
Intersections()
|
2013-01-19 13:22:39 +00:00
|
|
|
: fFlip(0)
|
2013-02-04 14:06:49 +00:00
|
|
|
#if SK_DEBUG
|
|
|
|
, fDepth(0)
|
|
|
|
#endif
|
2013-02-14 15:29:11 +00:00
|
|
|
, fSwap(0)
|
2012-01-10 21:46:10 +00:00
|
|
|
{
|
2013-02-14 15:29:11 +00:00
|
|
|
#if SK_DEBUG
|
|
|
|
bzero(fPt, sizeof(fPt));
|
2012-01-10 21:46:10 +00:00
|
|
|
bzero(fT, sizeof(fT));
|
2013-02-14 15:29:11 +00:00
|
|
|
bzero(fIsCoincident, sizeof(fIsCoincident));
|
|
|
|
#endif
|
2013-01-19 13:22:39 +00:00
|
|
|
reset();
|
2012-01-10 21:46:10 +00:00
|
|
|
}
|
|
|
|
|
2013-02-14 15:29:11 +00:00
|
|
|
int coincidentUsed() const {
|
|
|
|
if (!fIsCoincident[0]) {
|
|
|
|
SkASSERT(!fIsCoincident[0]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int count = 0;
|
|
|
|
SkDEBUGCODE(int count2 = 0;)
|
2012-08-31 20:55:07 +00:00
|
|
|
for (int index = 0; index < fUsed; ++index) {
|
2013-02-14 15:29:11 +00:00
|
|
|
if (fIsCoincident[0] & (1 << index)) {
|
|
|
|
++count;
|
2012-08-31 20:55:07 +00:00
|
|
|
}
|
2013-02-14 15:29:11 +00:00
|
|
|
#if SK_DEBUG
|
|
|
|
if (fIsCoincident[1] & (1 << index)) {
|
|
|
|
++count2;
|
2012-08-31 20:55:07 +00:00
|
|
|
}
|
2013-02-14 15:29:11 +00:00
|
|
|
#endif
|
2012-08-28 20:44:43 +00:00
|
|
|
}
|
2013-02-14 15:29:11 +00:00
|
|
|
SkASSERT(count == count2);
|
|
|
|
return count;
|
2013-02-04 14:06:49 +00:00
|
|
|
}
|
2012-08-31 20:55:07 +00:00
|
|
|
|
2012-01-10 21:46:10 +00:00
|
|
|
void offset(int base, double start, double end) {
|
|
|
|
for (int index = base; index < fUsed; ++index) {
|
|
|
|
double val = fT[fSwap][index];
|
|
|
|
val *= end - start;
|
|
|
|
val += start;
|
|
|
|
fT[fSwap][index] = val;
|
|
|
|
}
|
|
|
|
}
|
2012-09-15 02:01:41 +00:00
|
|
|
|
2013-02-26 15:56:05 +00:00
|
|
|
// FIXME : does not respect swap
|
2013-02-14 15:29:11 +00:00
|
|
|
int insert(double one, double two, const _Point& pt);
|
2012-01-10 21:46:10 +00:00
|
|
|
|
2013-02-14 15:29:11 +00:00
|
|
|
// start if index == 0 : end if index == 1
|
|
|
|
void insertCoincident(double one, double two, const _Point& pt) {
|
|
|
|
int index = insertSwap(one, two, pt);
|
|
|
|
int bit = 1 << index;
|
|
|
|
fIsCoincident[0] |= bit;
|
|
|
|
fIsCoincident[1] |= bit;
|
|
|
|
}
|
2013-02-15 07:16:57 +00:00
|
|
|
|
2013-02-14 15:29:11 +00:00
|
|
|
void insertCoincidentPair(double s1, double e1, double s2, double e2,
|
|
|
|
const _Point& startPt, const _Point& endPt);
|
|
|
|
|
|
|
|
int insertSwap(double one, double two, const _Point& pt) {
|
|
|
|
if (fSwap) {
|
|
|
|
return insert(two, one, pt);
|
|
|
|
} else {
|
|
|
|
return insert(one, two, pt);
|
|
|
|
}
|
|
|
|
}
|
2013-02-15 07:16:57 +00:00
|
|
|
|
2012-09-14 14:19:30 +00:00
|
|
|
bool intersected() const {
|
2012-01-10 21:46:10 +00:00
|
|
|
return fUsed > 0;
|
|
|
|
}
|
2012-09-15 02:01:41 +00:00
|
|
|
|
2013-02-17 01:41:25 +00:00
|
|
|
void removeOne(int index);
|
2013-02-17 07:02:20 +00:00
|
|
|
|
2013-01-19 13:22:39 +00:00
|
|
|
// leaves flip, swap alone
|
|
|
|
void reset() {
|
2013-02-17 01:41:25 +00:00
|
|
|
fUsed = 0;
|
2013-01-19 13:22:39 +00:00
|
|
|
fUnsortable = false;
|
|
|
|
}
|
|
|
|
|
2012-01-10 21:46:10 +00:00
|
|
|
void swap() {
|
2013-01-17 21:02:47 +00:00
|
|
|
fSwap ^= true;
|
|
|
|
}
|
2013-01-18 07:07:28 +00:00
|
|
|
|
2013-01-17 21:02:47 +00:00
|
|
|
void swapPts() {
|
|
|
|
int index;
|
|
|
|
for (index = 0; index < fUsed; ++index) {
|
|
|
|
SkTSwap(fT[0][index], fT[1][index]);
|
|
|
|
}
|
2012-01-10 21:46:10 +00:00
|
|
|
}
|
2012-08-23 18:14:13 +00:00
|
|
|
|
2013-01-17 21:02:47 +00:00
|
|
|
bool swapped() const {
|
2012-01-10 21:46:10 +00:00
|
|
|
return fSwap;
|
|
|
|
}
|
|
|
|
|
2013-01-17 21:02:47 +00:00
|
|
|
bool unsortable() const {
|
|
|
|
return fUnsortable;
|
|
|
|
}
|
|
|
|
|
|
|
|
int used() const {
|
2012-01-10 21:46:10 +00:00
|
|
|
return fUsed;
|
|
|
|
}
|
|
|
|
|
2013-02-04 14:06:49 +00:00
|
|
|
void downDepth() {
|
|
|
|
SkASSERT(--fDepth >= 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void upDepth() {
|
|
|
|
SkASSERT(++fDepth < 16);
|
|
|
|
}
|
|
|
|
|
2013-02-14 15:29:11 +00:00
|
|
|
#if SK_DEBUG
|
|
|
|
int depth() const {
|
|
|
|
return fDepth;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
_Point fPt[9];
|
2012-01-10 21:46:10 +00:00
|
|
|
double fT[2][9];
|
2013-02-14 15:29:11 +00:00
|
|
|
unsigned short fIsCoincident[2]; // bit arrays, one bit set for each coincident T
|
|
|
|
unsigned char fUsed;
|
2013-01-17 21:02:47 +00:00
|
|
|
bool fFlip;
|
|
|
|
bool fUnsortable;
|
2013-02-04 14:06:49 +00:00
|
|
|
#if SK_DEBUG
|
|
|
|
int fDepth;
|
|
|
|
#endif
|
2013-02-07 13:13:41 +00:00
|
|
|
protected:
|
|
|
|
// used by addCoincident to remove ordinary intersections in range
|
2013-02-14 15:29:11 +00:00
|
|
|
void remove(double one, double two, const _Point& startPt, const _Point& endPt);
|
2012-03-28 16:20:21 +00:00
|
|
|
private:
|
2013-02-14 15:29:11 +00:00
|
|
|
bool fSwap;
|
2012-01-10 21:46:10 +00:00
|
|
|
};
|
2012-03-28 16:20:21 +00:00
|
|
|
|
|
|
|
#endif
|