blob: 7dd60d9a40021581406e911bf8150c9a0e4669ff [file] [log] [blame]
caryclark@google.com198e0542012-03-30 18:47:02 +00001add unit test for quadratic horizontal intersection
2add unit test for cubic horizontal intersection with left/right
3add unit test for ActiveEdge::calcLeft (can currently loop forever)
4does ActiveEdge::isCoincidentWith need to support quad, cubic?
5figure out why variation in ActiveEdge::tooCloseToCall isn't better
6why does 'lastPtr - 2' in addIntersectingTs break testSimplifyTriangle22?
7add code to promote quad to cubic, or add quad/cubic intersection
8figure out why testSimplifySkinnyTriangle13 fails
9
10for quadratics and cubics, once various T values are added, see if consecutive
11Ts have ys that go up instead of down. If so, the edge needs to be broken.
12
13when splitting curves at inflection pts, should I retain the original curve
14data and note that the first/last T are no longer 0/1 ?
15I need to figure this out before I can proceed
16
17would it make sense to leave the InEdge alone, and add multiple copies of
18ActiveEdge, pointing to the same InEdge, where the copy has only the subset
19of Ts that need to be walked in reverse order?
20
caryclark@google.com15fa1382012-05-07 20:49:36 +000021
22-- A Digression Which Shows Why Resolving Coincidence Does Not Make Sense --
23
24Consider the following fine ASCII art:
25
26 +------>-------+ +------>-------+
27 | | | |
28 ^ V ^ V
29 | | | |
30 +------<-------+ +------<-------+
31 +------>-------+ +------<-------+
32 | | | |
33 ^ V V ^
34 | | | |
35 +------<-------+ +------>-------+
36
37(assume the bottom and top of the stacked rectangles are coincident)
38
39Simplifying said rectangles, regardless of rectangle direction, and regardless
40of winding or even/odd, eliminates the coincident edge, i.e., the result is
41always:
42
43 +------>-------+
44 | |
45 | |
46 | |
47 ^ V
48 | |
49 | |
50 | |
51 +------<-------+
52
53But when the rectangles are enclosed in a larger rectangle:
54
55+-------->---------+ +-------->---------+
56| +------>-------+ | | +------>-------+ |
57| | | | | | | |
58| ^ V | | ^ V |
59| | | | | | | |
60| +------<-------+ | | +------<-------+ |
61| +------>-------+ | | +------<-------+ |
62| | | | | | | |
63| ^ V | | V ^ |
64| | | | | | | |
65| +------<-------+ | | +------>-------+ |
66+--------<---------+ +--------<---------+
67
68Simplifying them gives different results depending on the winding setting:
69
70winding:
71+-------->---------+ +-------->---------+
72| | | |
73| | | |
74| | | |
75| | | |
76| | | +------<-------+ |
77| | | | | |
78| | | V ^ |
79| | | | | |
80| | | +------>-------+ |
81+--------<---------+ +--------<---------+
82
83even odd:
84+-------->---------+ +-------->---------+
85| +------<-------+ | | +------<-------+ |
86| | | | | | | |
87| | | | | | | |
88| | | | | | | |
89| | | | | | | |
90| V ^ | | V ^ |
91| | | | | | | |
92| | | | | | | |
93| | | | | | | |
94| +------>-------+ | | +------>-------+ |
95+--------<---------+ +--------<---------+
96
97So, given the inner rectangles alone (e.g., given coincident pairs in some local
98context), we can't know whether to keep the coincident edges or not.
99
100
101-- Thoughts About Sortless Ops --
102
103I can't come up with anything truly sortless. It seems that the crossings need
104to be sorted to know which segment is next on the outside, although sometimes
105we can use that it is not coincident just to follow the direction.
106
107If it is coincident or if there's more than two crossing segments, sorting
108seems inevitable.
109
110Likewise, to resolve whether one contour is inside another, it seems that
111sorting is required. Given a pair of segments on different contours, to know
112if one is inside of the other, I need to know for each which side of the edge
113is the inside/filled side. When the outer contour is walked, it seems like I
114could record the inside info. I guess when the inner contour is found, its
115inside sense is reversed (inside is above the top). But how do I know if the
116next contour is inside another? Maybe shoot out a line and brute-force
117intersect it with all the segments in all the other contours? If every contour
118has an extra segment when the intersections are computed, this may not be as
119crazy as it seems.
120
121Suppose each contour has one extra segment shooting straight up from the top
122(or straight up from any point on the segment). This ray is not intersected
123with the home contour, but is intersected with all other contours as part of
124the normal intersection engine. If it is possible to get from the T values to
125the other segments to the other contours, it would be straightforward to
126count the contour crossings and determine if the home contour is in another
127contour or not (if the count is even, not, if odd, is inside). By itself that
128doesn't tell us about winding, but it's a start.
129
130
131Since intersecting these rays is unrelated to computing other intersections,
132it can be lazily done once the contour is found.
133
134So
135repeat the following
136find the top segment of all contours
137trace the outside, marking touching first and last segments as inside
138continue tracing the touched segments with reversed outside/inside sense
139once the edges are exhausted, remaining must be disjoint contours
140send a ray from a disjoint point through all other contours
141count the crossings, determine if disjoint is inside or outside, then continue
caryclark@google.comb45a1b42012-05-18 20:50:33 +0000142
143===
144
145On Quadratic (and Cubic) Intersections
146
147Currently, if only the end points touch, QuadracticIntersections does a lot of
148work to figure that out. Can I test for that up front, then short circuit the
149recursive search for the end points?
150
151Or, is there something defective in the current approach that makes the end
152point recursion go so deep? I'm seeing 56 stack frames (about 28 divides, but
153thankfully, no splits) to find one matching endpoint.
154
155
156Bezier curve focus may allow more quickly determining that end points with
157identical tangents are practically coicident for some range of T, but I don't
158understand the math yet to know.
159
160Another approach is to determine how flat the curve is to make good guesses
161about how far to move away in T before doing the intersection for the remainder
162and/or to determine whether one curve is to the inside or outside of another.
163According to Mike/Rob, the flatness for quadratics increases by 4 for each
164subdivision, and a crude guess of the curvature can be had by comparing P1 to
165(P0+P2)/2. By looking at the ULPS of the numbers, I can guess what value of
166T may be far enough that the curves diverge but don't cross.