blob: be40ae418f0fd5e6676c86f244559765f5f7776a [file] [log] [blame]
caryclark@google.com9166dcb2013-04-08 11:50:00 +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 */
7#include "SkIntersections.h"
8#include "SkPathOpsLine.h"
9#include "Test.h"
10
11// FIXME: add tests for intersecting, non-intersecting, degenerate, coincident
12static const SkDLine tests[][2] = {
caryclark@google.com07e97fc2013-07-08 17:17:02 +000013#if 0 // FIXME: these fail because one line is too short and appears quasi-coincident
14 {{{{158.000000, 926.000000}, {1108.00000, 926.000000}}},
15 {{{1108.00000, 926.000000}, {1108.00000, 925.999634}}}},
16 {{{{1108,926}, {1108,925.9996337890625}}}, {{{158,926}, {1108,926}}}},
17#endif
caryclark@google.coma5e55922013-05-07 18:51:31 +000018 {{{{192, 4}, {243, 4}}}, {{{246, 4}, {189, 4}}}},
19 {{{{246, 4}, {189, 4}}}, {{{192, 4}, {243, 4}}}},
caryclark@google.com03610322013-04-18 15:58:21 +000020 {{{{5, 0}, {0, 5}}}, {{{5, 4}, {1, 4}}}},
caryclark@google.com9166dcb2013-04-08 11:50:00 +000021 {{{{0, 0}, {1, 0}}}, {{{1, 0}, {0, 0}}}},
22 {{{{0, 0}, {0, 0}}}, {{{0, 0}, {1, 0}}}},
23 {{{{0, 1}, {0, 1}}}, {{{0, 0}, {0, 2}}}},
24 {{{{0, 0}, {1, 0}}}, {{{0, 0}, {2, 0}}}},
25 {{{{1, 1}, {2, 2}}}, {{{0, 0}, {3, 3}}}},
26 {{{{166.86950047022856, 112.69654129527828}, {166.86948801592692, 112.69655741235339}}},
27 {{{166.86960700313026, 112.6965477747386}, {166.86925794355412, 112.69656471103423}}}}
28};
29
caryclark@google.comad65a3e2013-04-15 19:13:59 +000030static const size_t tests_count = SK_ARRAY_COUNT(tests);
caryclark@google.com9166dcb2013-04-08 11:50:00 +000031
32static const SkDLine noIntersect[][2] = {
33 {{{{0, 0}, {1, 0}}}, {{{3, 0}, {2, 0}}}},
34 {{{{0, 0}, {0, 0}}}, {{{1, 0}, {2, 0}}}},
35 {{{{0, 1}, {0, 1}}}, {{{0, 3}, {0, 2}}}},
36 {{{{0, 0}, {1, 0}}}, {{{2, 0}, {3, 0}}}},
37 {{{{1, 1}, {2, 2}}}, {{{4, 4}, {3, 3}}}},
38};
39
caryclark@google.comad65a3e2013-04-15 19:13:59 +000040static const size_t noIntersect_count = SK_ARRAY_COUNT(noIntersect);
caryclark@google.com9166dcb2013-04-08 11:50:00 +000041
caryclark@google.com07e97fc2013-07-08 17:17:02 +000042static const SkDLine coincidentTests[][2] = {
43 {{{{235.681549, 531.000000}, {280.318420, 321.000000}}},
44 {{{286.695129, 291.000000}, {229.304855, 561.000000}}}},
45};
46
47static const size_t coincidentTests_count = SK_ARRAY_COUNT(coincidentTests);
48
caryclark@google.coma5e55922013-05-07 18:51:31 +000049static void check_results(skiatest::Reporter* reporter, const SkDLine& line1, const SkDLine& line2,
50 const SkIntersections& ts) {
51 for (int i = 0; i < ts.used(); ++i) {
52 SkDPoint result1 = line1.xyAtT(ts[0][i]);
53 SkDPoint result2 = line2.xyAtT(ts[1][i]);
54 if (!result1.approximatelyEqual(result2)) {
55 REPORTER_ASSERT(reporter, ts.used() != 1);
56 result2 = line2.xyAtT(ts[1][i ^ 1]);
57 REPORTER_ASSERT(reporter, result1.approximatelyEqual(result2));
58 REPORTER_ASSERT(reporter, result1.approximatelyEqual(ts.pt(i).asSkPoint()));
59 }
60 }
61}
62
caryclark@google.com07e97fc2013-07-08 17:17:02 +000063static void testOne(skiatest::Reporter* reporter, const SkDLine& line1, const SkDLine& line2) {
64 SkIntersections i;
65 int pts = i.intersect(line1, line2);
66 REPORTER_ASSERT(reporter, pts);
67 REPORTER_ASSERT(reporter, pts == i.used());
68 check_results(reporter, line1, line2, i);
69 if (line1[0] == line1[1] || line2[0] == line2[1]) {
70 return;
71 }
72 if (line1[0].fY == line1[1].fY) {
73 double left = SkTMin(line1[0].fX, line1[1].fX);
74 double right = SkTMax(line1[0].fX, line1[1].fX);
75 SkIntersections ts;
76 ts.horizontal(line2, left, right, line1[0].fY, line1[0].fX != left);
77 check_results(reporter, line2, line1, ts);
78 }
79 if (line2[0].fY == line2[1].fY) {
80 double left = SkTMin(line2[0].fX, line2[1].fX);
81 double right = SkTMax(line2[0].fX, line2[1].fX);
82 SkIntersections ts;
83 ts.horizontal(line1, left, right, line2[0].fY, line2[0].fX != left);
84 check_results(reporter, line1, line2, ts);
85 }
86 if (line1[0].fX == line1[1].fX) {
87 double top = SkTMin(line1[0].fY, line1[1].fY);
88 double bottom = SkTMax(line1[0].fY, line1[1].fY);
89 SkIntersections ts;
90 ts.vertical(line2, top, bottom, line1[0].fX, line1[0].fY != top);
91 check_results(reporter, line2, line1, ts);
92 }
93 if (line2[0].fX == line2[1].fX) {
94 double top = SkTMin(line2[0].fY, line2[1].fY);
95 double bottom = SkTMax(line2[0].fY, line2[1].fY);
96 SkIntersections ts;
97 ts.vertical(line1, top, bottom, line2[0].fX, line2[0].fY != top);
98 check_results(reporter, line1, line2, ts);
99 }
100}
101
102static void testOneCoincident(skiatest::Reporter* reporter, const SkDLine& line1,
103 const SkDLine& line2) {
104 SkIntersections ts2;
105 int pts2 = ts2.intersect(line1, line2);
106 REPORTER_ASSERT(reporter, pts2 == 2);
107 REPORTER_ASSERT(reporter, pts2 == ts2.used());
108 check_results(reporter, line1, line2, ts2);
109#if 0
110 SkIntersections ts;
111 int pts = ts.intersect(line1, line2);
112 REPORTER_ASSERT(reporter, pts == pts2);
113 REPORTER_ASSERT(reporter, pts == 2);
114 REPORTER_ASSERT(reporter, pts == ts.used());
115 check_results(reporter, line1, line2, ts);
116#endif
117}
118
caryclark@google.comad65a3e2013-04-15 19:13:59 +0000119static void PathOpsLineIntersectionTest(skiatest::Reporter* reporter) {
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000120 size_t index;
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000121 for (index = 0; index < coincidentTests_count; ++index) {
122 const SkDLine& line1 = coincidentTests[index][0];
123 const SkDLine& line2 = coincidentTests[index][1];
124 testOneCoincident(reporter, line1, line2);
125 reporter->bumpTestCount();
126 }
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000127 for (index = 0; index < tests_count; ++index) {
128 const SkDLine& line1 = tests[index][0];
129 const SkDLine& line2 = tests[index][1];
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000130 testOne(reporter, line1, line2);
131 reporter->bumpTestCount();
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000132 }
133 for (index = 0; index < noIntersect_count; ++index) {
134 const SkDLine& line1 = noIntersect[index][0];
135 const SkDLine& line2 = noIntersect[index][1];
136 SkIntersections ts;
137 int pts = ts.intersect(line1, line2);
skia.committer@gmail.com2b34fe02013-05-08 07:01:40 +0000138 REPORTER_ASSERT(reporter, !pts);
caryclark@google.coma5e55922013-05-07 18:51:31 +0000139 REPORTER_ASSERT(reporter, pts == ts.used());
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000140 reporter->bumpTestCount();
caryclark@google.coma5e55922013-05-07 18:51:31 +0000141 }
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000142}
143
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000144static void PathOpsLineIntersectionTestOne(skiatest::Reporter* reporter) {
145 int index = 0;
146 SkASSERT(index < (int) tests_count);
147 const SkDLine& line1 = tests[index][0];
148 const SkDLine& line2 = tests[index][1];
149 testOne(reporter, line1, line2);
150}
151
152static void PathOpsLineIntersectionTestOneCoincident(skiatest::Reporter* reporter) {
153 int index = 0;
154 SkASSERT(index < (int) coincidentTests_count);
155 const SkDLine& line1 = coincidentTests[index][0];
156 const SkDLine& line2 = coincidentTests[index][1];
157 testOneCoincident(reporter, line1, line2);
158}
159
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000160#include "TestClassDef.h"
caryclark@google.comad65a3e2013-04-15 19:13:59 +0000161DEFINE_TESTCLASS_SHORT(PathOpsLineIntersectionTest)
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000162
163DEFINE_TESTCLASS_SHORT(PathOpsLineIntersectionTestOne)
164
165DEFINE_TESTCLASS_SHORT(PathOpsLineIntersectionTestOneCoincident)