blob: 26e0d9bbc0b0a9282a25ade492b08cc5f2f50e0a [file] [log] [blame]
caryclark@google.com9e49fb62012-08-27 14:11:33 +00001/*
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 */
caryclark@google.coma5764232012-03-28 16:20:21 +00007#ifndef Intersections_DEFINE
8#define Intersections_DEFINE
9
caryclark@google.com73ca6242013-01-17 21:02:47 +000010#include <algorithm> // for std::min -- Skia doesn't have a SkMinDouble
11#include "SkTypes.h"
caryclark@google.com235f56a2012-09-14 14:19:30 +000012
caryclark@google.com639df892012-01-10 21:46:10 +000013class Intersections {
14public:
skia.committer@gmail.com9f876ed2013-01-20 07:05:51 +000015 Intersections()
caryclark@google.com05c4bad2013-01-19 13:22:39 +000016 : fFlip(0)
caryclark@google.com639df892012-01-10 21:46:10 +000017 , fSwap(0)
18 {
caryclark@google.coma7e483d2012-08-28 20:44:43 +000019 // OPTIMIZE: don't need to be initialized in release
caryclark@google.com639df892012-01-10 21:46:10 +000020 bzero(fT, sizeof(fT));
caryclark@google.coma7e483d2012-08-28 20:44:43 +000021 bzero(fCoincidentT, sizeof(fCoincidentT));
caryclark@google.com05c4bad2013-01-19 13:22:39 +000022 reset();
caryclark@google.com639df892012-01-10 21:46:10 +000023 }
24
25 void add(double one, double two) {
caryclark@google.com32546db2012-08-31 20:55:07 +000026 for (int index = 0; index < fUsed; ++index) {
27 if (approximately_equal(fT[fSwap][index], one)
28 && approximately_equal(fT[fSwap ^ 1][index], two)) {
29 return;
30 }
caryclark@google.com639df892012-01-10 21:46:10 +000031 }
caryclark@google.com235f56a2012-09-14 14:19:30 +000032 assert(fUsed < 9);
caryclark@google.com639df892012-01-10 21:46:10 +000033 fT[fSwap][fUsed] = one;
34 fT[fSwap ^ 1][fUsed] = two;
35 ++fUsed;
36 }
37
caryclark@google.coma7e483d2012-08-28 20:44:43 +000038 // start if index == 0 : end if index == 1
caryclark@google.com235f56a2012-09-14 14:19:30 +000039 void addCoincident(double one, double two) {
caryclark@google.com32546db2012-08-31 20:55:07 +000040 for (int index = 0; index < fCoincidentUsed; ++index) {
41 if (approximately_equal(fCoincidentT[fSwap][index], one)
42 && approximately_equal(fCoincidentT[fSwap ^ 1][index], two)) {
caryclark@google.com32546db2012-08-31 20:55:07 +000043 return;
44 }
caryclark@google.coma7e483d2012-08-28 20:44:43 +000045 }
caryclark@google.com235f56a2012-09-14 14:19:30 +000046 assert(fCoincidentUsed < 9);
caryclark@google.coma7e483d2012-08-28 20:44:43 +000047 fCoincidentT[fSwap][fCoincidentUsed] = one;
48 fCoincidentT[fSwap ^ 1][fCoincidentUsed] = two;
49 ++fCoincidentUsed;
50 }
51
caryclark@google.com73ca6242013-01-17 21:02:47 +000052 void addCoincident(double s1, double e1, double s2, double e2);
caryclark@google.com235f56a2012-09-14 14:19:30 +000053
54 // FIXME: this is necessary because curve/curve intersections are noisy
55 // remove once curve/curve intersections are improved
56 void cleanUp();
57
caryclark@google.com73ca6242013-01-17 21:02:47 +000058 int coincidentUsed() const{
caryclark@google.com32546db2012-08-31 20:55:07 +000059 return fCoincidentUsed;
60 }
61
caryclark@google.com639df892012-01-10 21:46:10 +000062 void offset(int base, double start, double end) {
63 for (int index = base; index < fUsed; ++index) {
64 double val = fT[fSwap][index];
65 val *= end - start;
66 val += start;
67 fT[fSwap][index] = val;
68 }
69 }
skia.committer@gmail.com055c7c22012-09-15 02:01:41 +000070
caryclark@google.com73ca6242013-01-17 21:02:47 +000071 void insert(double one, double two);
72 void insertOne(double t, int side);
caryclark@google.com639df892012-01-10 21:46:10 +000073
caryclark@google.com235f56a2012-09-14 14:19:30 +000074 bool intersected() const {
caryclark@google.com639df892012-01-10 21:46:10 +000075 return fUsed > 0;
76 }
skia.committer@gmail.com055c7c22012-09-15 02:01:41 +000077
caryclark@google.com235f56a2012-09-14 14:19:30 +000078 bool insertBalanced() const {
79 return fUsed == fUsed2;
80 }
caryclark@google.com639df892012-01-10 21:46:10 +000081
caryclark@google.com05c4bad2013-01-19 13:22:39 +000082 // leaves flip, swap alone
83 void reset() {
84 fUsed = fUsed2 = fCoincidentUsed = 0;
85 fUnsortable = false;
86 }
87
caryclark@google.com639df892012-01-10 21:46:10 +000088 void swap() {
caryclark@google.com73ca6242013-01-17 21:02:47 +000089 fSwap ^= true;
90 }
skia.committer@gmail.com15dd3002013-01-18 07:07:28 +000091
caryclark@google.com73ca6242013-01-17 21:02:47 +000092 void swapPts() {
93 int index;
94 for (index = 0; index < fUsed; ++index) {
95 SkTSwap(fT[0][index], fT[1][index]);
96 }
caryclark@google.com639df892012-01-10 21:46:10 +000097 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000098
caryclark@google.com73ca6242013-01-17 21:02:47 +000099 bool swapped() const {
caryclark@google.com639df892012-01-10 21:46:10 +0000100 return fSwap;
101 }
102
caryclark@google.com73ca6242013-01-17 21:02:47 +0000103 bool unsortable() const {
104 return fUnsortable;
105 }
106
107 int used() const {
caryclark@google.com639df892012-01-10 21:46:10 +0000108 return fUsed;
109 }
110
111 double fT[2][9];
caryclark@google.coma7e483d2012-08-28 20:44:43 +0000112 double fCoincidentT[2][9];
caryclark@google.com639df892012-01-10 21:46:10 +0000113 int fUsed;
caryclark@google.com235f56a2012-09-14 14:19:30 +0000114 int fUsed2;
caryclark@google.coma7e483d2012-08-28 20:44:43 +0000115 int fCoincidentUsed;
caryclark@google.com73ca6242013-01-17 21:02:47 +0000116 bool fFlip;
117 bool fUnsortable;
caryclark@google.coma5764232012-03-28 16:20:21 +0000118private:
caryclark@google.com639df892012-01-10 21:46:10 +0000119 int fSwap;
120};
caryclark@google.coma5764232012-03-28 16:20:21 +0000121
122#endif