blob: 17d9c4714db54e2c6440e23e3e748b7dc8e2ee48 [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
36 int firstPointDegeneratesTest = run == RunAll ? 0 : run == RunPointDegenerates ? firstTestIndex : INT_MAX;
37 int firstNotPointDegeneratesTest = run == RunAll ? 0 : run == RunNotPointDegenerates ? firstTestIndex : INT_MAX;
38 int firstLinesTest = run == RunAll ? 0 : run == RunLines ? firstTestIndex : INT_MAX;
39 int firstNotLinesTest = run == RunAll ? 0 : run == RunNotLines ? firstTestIndex : INT_MAX;
40 int firstModEpsilonTest = run == RunAll ? 0 : run == RunModEpsilonLines ? firstTestIndex : INT_MAX;
41 int firstLessEpsilonTest = run == RunAll ? 0 : run == RunLessEpsilonLines ? firstTestIndex : INT_MAX;
42 int firstNegEpsilonTest = run == RunAll ? 0 : run == RunNegEpsilonLines ? firstTestIndex : INT_MAX;
43 int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines ? firstTestIndex : INT_MAX;
44 int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines ? firstTestIndex : INT_MAX;
45 int firstComputedLinesTest = run == RunAll ? 0 : run == RunComputedLines ? firstTestIndex : INT_MAX;
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];
49 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
50 if (order != 1) {
51 printf("[%d] pointDegenerates order=%d\n", (int) index, order);
52 }
53 }
54 for (index = firstNotPointDegeneratesTest; index < notPointDegenerates_count; ++index) {
55 const Cubic& cubic = notPointDegenerates[index];
56 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
57 if (order == 1) {
58 printf("[%d] notPointDegenerates order=%d\n", (int) index, order);
59 }
60 }
61 for (index = firstLinesTest; index < lines_count; ++index) {
62 const Cubic& cubic = lines[index];
63 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
64 if (order != 2) {
65 printf("[%d] lines order=%d\n", (int) index, order);
66 }
67 }
68 for (index = firstNotLinesTest; index < notLines_count; ++index) {
69 const Cubic& cubic = notLines[index];
70 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
71 if (order == 2) {
72 printf("[%d] notLines order=%d\n", (int) index, order);
73 }
74 }
75 for (index = firstModEpsilonTest; index < modEpsilonLines_count; ++index) {
76 const Cubic& cubic = modEpsilonLines[index];
77 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
78 if (order == 2) {
79 printf("[%d] line mod by epsilon order=%d\n", (int) index, order);
80 }
81 }
82 for (index = firstLessEpsilonTest; index < lessEpsilonLines_count; ++index) {
83 const Cubic& cubic = lessEpsilonLines[index];
84 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
85 if (order != 2) {
86 printf("[%d] line less by epsilon/2 order=%d\n", (int) index, order);
87 }
88 }
89 for (index = firstNegEpsilonTest; index < negEpsilonLines_count; ++index) {
90 const Cubic& cubic = negEpsilonLines[index];
91 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
92 if (order != 2) {
93 printf("[%d] line neg by epsilon/2 order=%d\n", (int) index, order);
94 }
95 }
96 for (index = firstQuadraticLineTest; index < quadraticLines_count; ++index) {
97 const Quadratic& quad = quadraticLines[index];
98 Cubic cubic;
99 quad_to_cubic(quad, cubic);
100 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
101 if (order != 2) {
102 printf("[%d] line quad order=%d\n", (int) index, order);
103 }
104 }
105 for (index = firstQuadraticModLineTest; index < quadraticModEpsilonLines_count; ++index) {
106 const Quadratic& quad = quadraticModEpsilonLines[index];
107 Cubic cubic;
108 quad_to_cubic(quad, cubic);
109 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
110 if (order != 3) {
111 printf("[%d] line mod quad order=%d\n", (int) index, order);
112 }
113 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000114
caryclark@google.com27accef2012-01-25 18:57:23 +0000115 // test if computed line end points are valid
116 for (index = firstComputedLinesTest; index < lines_count; ++index) {
117 const Cubic& cubic = lines[index];
rmistry@google.comd6176b02012-08-23 18:14:13 +0000118 bool controlsInside = controls_inside(cubic);
caryclark@google.com27accef2012-01-25 18:57:23 +0000119 order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
120 if (reduce[0].x == reduce[1].x && reduce[0].y == reduce[1].y) {
121 printf("[%d] line computed ends match order=%d\n", (int) index, order);
122 }
123 if (controlsInside) {
caryclark@google.com9f3e9a52012-12-10 12:50:53 +0000124 if ( (reduce[0].x != cubic[0].x && reduce[0].x != cubic[3].x)
125 || (reduce[0].y != cubic[0].y && reduce[0].y != cubic[3].y)
126 || (reduce[1].x != cubic[0].x && reduce[1].x != cubic[3].x)
127 || (reduce[1].y != cubic[0].y && reduce[1].y != cubic[3].y)) {
caryclark@google.com27accef2012-01-25 18:57:23 +0000128 printf("[%d] line computed ends order=%d\n", (int) index, order);
129 }
130 } else {
131 // binary search for extrema, compare against actual results
132 // while a control point is outside of bounding box formed by end points, split
133 _Rect bounds = {DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX};
134 find_tight_bounds(cubic, bounds);
caryclark@google.com6d0032a2013-01-04 19:41:13 +0000135 if ( (!AlmostEqualUlps(reduce[0].x, bounds.left) && !AlmostEqualUlps(reduce[0].x, bounds.right))
136 || (!AlmostEqualUlps(reduce[0].y, bounds.top) && !AlmostEqualUlps(reduce[0].y, bounds.bottom))
137 || (!AlmostEqualUlps(reduce[1].x, bounds.left) && !AlmostEqualUlps(reduce[1].x, bounds.right))
138 || (!AlmostEqualUlps(reduce[1].y, bounds.top) && !AlmostEqualUlps(reduce[1].y, bounds.bottom))) {
caryclark@google.com27accef2012-01-25 18:57:23 +0000139 printf("[%d] line computed tight bounds order=%d\n", (int) index, order);
140 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000141
caryclark@google.com27accef2012-01-25 18:57:23 +0000142 }
143 }
144}