blob: 79b34288d3ed3f6544739914a89789a52ac5ce56 [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.comc6825902012-02-03 22:07:47 +00007#include "CurveIntersection.h"
caryclark@google.com27accef2012-01-25 18:57:23 +00008#include "CubicIntersection_TestData.h"
9#include "Intersection_Tests.h"
10#include "QuadraticIntersection_TestData.h"
11#include "TestUtilities.h"
12
13void CubicReduceOrder_Test() {
14 size_t index;
15 Cubic reduce;
16 int order;
17 enum {
18 RunAll,
19 RunPointDegenerates,
20 RunNotPointDegenerates,
21 RunLines,
22 RunNotLines,
23 RunModEpsilonLines,
24 RunLessEpsilonLines,
25 RunNegEpsilonLines,
26 RunQuadraticLines,
27 RunQuadraticModLines,
28 RunComputedLines,
29 RunNone
30 } run = RunAll;
31 int firstTestIndex = 0;
32#if 0
33 run = RunComputedLines;
34 firstTestIndex = 18;
35#endif
caryclark@google.comaa358312013-01-29 20:28:49 +000036 int firstPointDegeneratesTest = run == RunAll ? 0 : run == RunPointDegenerates ? firstTestIndex : SK_MaxS32;
37 int firstNotPointDegeneratesTest = run == RunAll ? 0 : run == RunNotPointDegenerates ? firstTestIndex : SK_MaxS32;
38 int firstLinesTest = run == RunAll ? 0 : run == RunLines ? firstTestIndex : SK_MaxS32;
39 int firstNotLinesTest = run == RunAll ? 0 : run == RunNotLines ? firstTestIndex : SK_MaxS32;
40 int firstModEpsilonTest = run == RunAll ? 0 : run == RunModEpsilonLines ? firstTestIndex : SK_MaxS32;
41 int firstLessEpsilonTest = run == RunAll ? 0 : run == RunLessEpsilonLines ? firstTestIndex : SK_MaxS32;
42 int firstNegEpsilonTest = run == RunAll ? 0 : run == RunNegEpsilonLines ? firstTestIndex : SK_MaxS32;
43 int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines ? firstTestIndex : SK_MaxS32;
44 int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines ? firstTestIndex : SK_MaxS32;
45 int firstComputedLinesTest = run == RunAll ? 0 : run == RunComputedLines ? firstTestIndex : SK_MaxS32;
rmistry@google.comd6176b02012-08-23 18:14:13 +000046
caryclark@google.com27accef2012-01-25 18:57:23 +000047 for (index = firstPointDegeneratesTest; index < pointDegenerates_count; ++index) {
48 const Cubic& cubic = pointDegenerates[index];
caryclark@google.com47d73da2013-02-17 01:41:25 +000049 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed,
50 kReduceOrder_TreatAsFill);
caryclark@google.com27accef2012-01-25 18:57:23 +000051 if (order != 1) {
caryclark@google.comaa358312013-01-29 20:28:49 +000052 SkDebugf("[%d] pointDegenerates order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +000053 }
54 }
55 for (index = firstNotPointDegeneratesTest; index < notPointDegenerates_count; ++index) {
56 const Cubic& cubic = notPointDegenerates[index];
caryclark@google.com47d73da2013-02-17 01:41:25 +000057 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed,
58 kReduceOrder_TreatAsFill);
caryclark@google.com27accef2012-01-25 18:57:23 +000059 if (order == 1) {
caryclark@google.comaa358312013-01-29 20:28:49 +000060 SkDebugf("[%d] notPointDegenerates order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +000061 }
62 }
63 for (index = firstLinesTest; index < lines_count; ++index) {
64 const Cubic& cubic = lines[index];
caryclark@google.com47d73da2013-02-17 01:41:25 +000065 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed,
66 kReduceOrder_TreatAsFill);
caryclark@google.com27accef2012-01-25 18:57:23 +000067 if (order != 2) {
caryclark@google.comaa358312013-01-29 20:28:49 +000068 SkDebugf("[%d] lines order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +000069 }
70 }
71 for (index = firstNotLinesTest; index < notLines_count; ++index) {
72 const Cubic& cubic = notLines[index];
caryclark@google.com47d73da2013-02-17 01:41:25 +000073 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed,
74 kReduceOrder_TreatAsFill);
caryclark@google.com27accef2012-01-25 18:57:23 +000075 if (order == 2) {
caryclark@google.comaa358312013-01-29 20:28:49 +000076 SkDebugf("[%d] notLines order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +000077 }
78 }
79 for (index = firstModEpsilonTest; index < modEpsilonLines_count; ++index) {
80 const Cubic& cubic = modEpsilonLines[index];
caryclark@google.com47d73da2013-02-17 01:41:25 +000081 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed,
82 kReduceOrder_TreatAsFill);
caryclark@google.com27accef2012-01-25 18:57:23 +000083 if (order == 2) {
caryclark@google.comaa358312013-01-29 20:28:49 +000084 SkDebugf("[%d] line mod by epsilon order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +000085 }
86 }
87 for (index = firstLessEpsilonTest; index < lessEpsilonLines_count; ++index) {
88 const Cubic& cubic = lessEpsilonLines[index];
caryclark@google.com47d73da2013-02-17 01:41:25 +000089 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed,
90 kReduceOrder_TreatAsFill);
caryclark@google.com27accef2012-01-25 18:57:23 +000091 if (order != 2) {
caryclark@google.comaa358312013-01-29 20:28:49 +000092 SkDebugf("[%d] line less by epsilon/2 order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +000093 }
94 }
95 for (index = firstNegEpsilonTest; index < negEpsilonLines_count; ++index) {
96 const Cubic& cubic = negEpsilonLines[index];
caryclark@google.com47d73da2013-02-17 01:41:25 +000097 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed,
98 kReduceOrder_TreatAsFill);
caryclark@google.com27accef2012-01-25 18:57:23 +000099 if (order != 2) {
caryclark@google.comaa358312013-01-29 20:28:49 +0000100 SkDebugf("[%d] line neg by epsilon/2 order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +0000101 }
102 }
103 for (index = firstQuadraticLineTest; index < quadraticLines_count; ++index) {
104 const Quadratic& quad = quadraticLines[index];
105 Cubic cubic;
106 quad_to_cubic(quad, cubic);
caryclark@google.com47d73da2013-02-17 01:41:25 +0000107 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed,
108 kReduceOrder_TreatAsFill);
caryclark@google.com27accef2012-01-25 18:57:23 +0000109 if (order != 2) {
caryclark@google.comaa358312013-01-29 20:28:49 +0000110 SkDebugf("[%d] line quad order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +0000111 }
112 }
113 for (index = firstQuadraticModLineTest; index < quadraticModEpsilonLines_count; ++index) {
114 const Quadratic& quad = quadraticModEpsilonLines[index];
115 Cubic cubic;
116 quad_to_cubic(quad, cubic);
caryclark@google.com47d73da2013-02-17 01:41:25 +0000117 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed,
118 kReduceOrder_TreatAsFill);
caryclark@google.com27accef2012-01-25 18:57:23 +0000119 if (order != 3) {
caryclark@google.comaa358312013-01-29 20:28:49 +0000120 SkDebugf("[%d] line mod quad order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +0000121 }
122 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000123
caryclark@google.com27accef2012-01-25 18:57:23 +0000124 // test if computed line end points are valid
125 for (index = firstComputedLinesTest; index < lines_count; ++index) {
126 const Cubic& cubic = lines[index];
rmistry@google.comd6176b02012-08-23 18:14:13 +0000127 bool controlsInside = controls_inside(cubic);
caryclark@google.com47d73da2013-02-17 01:41:25 +0000128 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed,
129 kReduceOrder_TreatAsFill);
caryclark@google.com27accef2012-01-25 18:57:23 +0000130 if (reduce[0].x == reduce[1].x && reduce[0].y == reduce[1].y) {
caryclark@google.comaa358312013-01-29 20:28:49 +0000131 SkDebugf("[%d] line computed ends match order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +0000132 }
133 if (controlsInside) {
caryclark@google.com9f3e9a52012-12-10 12:50:53 +0000134 if ( (reduce[0].x != cubic[0].x && reduce[0].x != cubic[3].x)
135 || (reduce[0].y != cubic[0].y && reduce[0].y != cubic[3].y)
136 || (reduce[1].x != cubic[0].x && reduce[1].x != cubic[3].x)
137 || (reduce[1].y != cubic[0].y && reduce[1].y != cubic[3].y)) {
caryclark@google.comaa358312013-01-29 20:28:49 +0000138 SkDebugf("[%d] line computed ends order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +0000139 }
140 } else {
141 // binary search for extrema, compare against actual results
142 // while a control point is outside of bounding box formed by end points, split
143 _Rect bounds = {DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX};
144 find_tight_bounds(cubic, bounds);
caryclark@google.com6d0032a2013-01-04 19:41:13 +0000145 if ( (!AlmostEqualUlps(reduce[0].x, bounds.left) && !AlmostEqualUlps(reduce[0].x, bounds.right))
146 || (!AlmostEqualUlps(reduce[0].y, bounds.top) && !AlmostEqualUlps(reduce[0].y, bounds.bottom))
147 || (!AlmostEqualUlps(reduce[1].x, bounds.left) && !AlmostEqualUlps(reduce[1].x, bounds.right))
148 || (!AlmostEqualUlps(reduce[1].y, bounds.top) && !AlmostEqualUlps(reduce[1].y, bounds.bottom))) {
caryclark@google.comaa358312013-01-29 20:28:49 +0000149 SkDebugf("[%d] line computed tight bounds order=%d\n", (int) index, order);
caryclark@google.com27accef2012-01-25 18:57:23 +0000150 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000151
caryclark@google.com27accef2012-01-25 18:57:23 +0000152 }
153 }
154}