2012-03-30 18:47:02 +00:00
|
|
|
add unit test for quadratic horizontal intersection
|
|
|
|
add unit test for cubic horizontal intersection with left/right
|
|
|
|
add unit test for ActiveEdge::calcLeft (can currently loop forever)
|
|
|
|
does ActiveEdge::isCoincidentWith need to support quad, cubic?
|
|
|
|
figure out why variation in ActiveEdge::tooCloseToCall isn't better
|
|
|
|
why does 'lastPtr - 2' in addIntersectingTs break testSimplifyTriangle22?
|
|
|
|
add code to promote quad to cubic, or add quad/cubic intersection
|
|
|
|
figure out why testSimplifySkinnyTriangle13 fails
|
|
|
|
|
|
|
|
for quadratics and cubics, once various T values are added, see if consecutive
|
|
|
|
Ts have ys that go up instead of down. If so, the edge needs to be broken.
|
|
|
|
|
|
|
|
when splitting curves at inflection pts, should I retain the original curve
|
|
|
|
data and note that the first/last T are no longer 0/1 ?
|
|
|
|
I need to figure this out before I can proceed
|
|
|
|
|
|
|
|
would it make sense to leave the InEdge alone, and add multiple copies of
|
|
|
|
ActiveEdge, pointing to the same InEdge, where the copy has only the subset
|
|
|
|
of Ts that need to be walked in reverse order?
|
|
|
|
|
2012-05-07 20:49:36 +00:00
|
|
|
|
|
|
|
-- A Digression Which Shows Why Resolving Coincidence Does Not Make Sense --
|
|
|
|
|
|
|
|
Consider the following fine ASCII art:
|
|
|
|
|
|
|
|
+------>-------+ +------>-------+
|
|
|
|
| | | |
|
|
|
|
^ V ^ V
|
|
|
|
| | | |
|
|
|
|
+------<-------+ +------<-------+
|
|
|
|
+------>-------+ +------<-------+
|
|
|
|
| | | |
|
|
|
|
^ V V ^
|
|
|
|
| | | |
|
|
|
|
+------<-------+ +------>-------+
|
|
|
|
|
|
|
|
(assume the bottom and top of the stacked rectangles are coincident)
|
|
|
|
|
|
|
|
Simplifying said rectangles, regardless of rectangle direction, and regardless
|
|
|
|
of winding or even/odd, eliminates the coincident edge, i.e., the result is
|
|
|
|
always:
|
|
|
|
|
|
|
|
+------>-------+
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
^ V
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
+------<-------+
|
|
|
|
|
|
|
|
But when the rectangles are enclosed in a larger rectangle:
|
|
|
|
|
|
|
|
+-------->---------+ +-------->---------+
|
|
|
|
| +------>-------+ | | +------>-------+ |
|
|
|
|
| | | | | | | |
|
|
|
|
| ^ V | | ^ V |
|
|
|
|
| | | | | | | |
|
|
|
|
| +------<-------+ | | +------<-------+ |
|
|
|
|
| +------>-------+ | | +------<-------+ |
|
|
|
|
| | | | | | | |
|
|
|
|
| ^ V | | V ^ |
|
|
|
|
| | | | | | | |
|
|
|
|
| +------<-------+ | | +------>-------+ |
|
|
|
|
+--------<---------+ +--------<---------+
|
|
|
|
|
|
|
|
Simplifying them gives different results depending on the winding setting:
|
|
|
|
|
|
|
|
winding:
|
|
|
|
+-------->---------+ +-------->---------+
|
|
|
|
| | | |
|
|
|
|
| | | |
|
|
|
|
| | | |
|
|
|
|
| | | |
|
|
|
|
| | | +------<-------+ |
|
|
|
|
| | | | | |
|
|
|
|
| | | V ^ |
|
|
|
|
| | | | | |
|
|
|
|
| | | +------>-------+ |
|
|
|
|
+--------<---------+ +--------<---------+
|
|
|
|
|
|
|
|
even odd:
|
|
|
|
+-------->---------+ +-------->---------+
|
|
|
|
| +------<-------+ | | +------<-------+ |
|
|
|
|
| | | | | | | |
|
|
|
|
| | | | | | | |
|
|
|
|
| | | | | | | |
|
|
|
|
| | | | | | | |
|
|
|
|
| V ^ | | V ^ |
|
|
|
|
| | | | | | | |
|
|
|
|
| | | | | | | |
|
|
|
|
| | | | | | | |
|
|
|
|
| +------>-------+ | | +------>-------+ |
|
|
|
|
+--------<---------+ +--------<---------+
|
|
|
|
|
|
|
|
So, given the inner rectangles alone (e.g., given coincident pairs in some local
|
|
|
|
context), we can't know whether to keep the coincident edges or not.
|
|
|
|
|
|
|
|
|
|
|
|
-- Thoughts About Sortless Ops --
|
|
|
|
|
|
|
|
I can't come up with anything truly sortless. It seems that the crossings need
|
|
|
|
to be sorted to know which segment is next on the outside, although sometimes
|
|
|
|
we can use that it is not coincident just to follow the direction.
|
|
|
|
|
|
|
|
If it is coincident or if there's more than two crossing segments, sorting
|
|
|
|
seems inevitable.
|
|
|
|
|
|
|
|
Likewise, to resolve whether one contour is inside another, it seems that
|
|
|
|
sorting is required. Given a pair of segments on different contours, to know
|
|
|
|
if one is inside of the other, I need to know for each which side of the edge
|
|
|
|
is the inside/filled side. When the outer contour is walked, it seems like I
|
|
|
|
could record the inside info. I guess when the inner contour is found, its
|
|
|
|
inside sense is reversed (inside is above the top). But how do I know if the
|
|
|
|
next contour is inside another? Maybe shoot out a line and brute-force
|
|
|
|
intersect it with all the segments in all the other contours? If every contour
|
|
|
|
has an extra segment when the intersections are computed, this may not be as
|
|
|
|
crazy as it seems.
|
|
|
|
|
|
|
|
Suppose each contour has one extra segment shooting straight up from the top
|
|
|
|
(or straight up from any point on the segment). This ray is not intersected
|
|
|
|
with the home contour, but is intersected with all other contours as part of
|
|
|
|
the normal intersection engine. If it is possible to get from the T values to
|
|
|
|
the other segments to the other contours, it would be straightforward to
|
|
|
|
count the contour crossings and determine if the home contour is in another
|
|
|
|
contour or not (if the count is even, not, if odd, is inside). By itself that
|
|
|
|
doesn't tell us about winding, but it's a start.
|
|
|
|
|
|
|
|
|
|
|
|
Since intersecting these rays is unrelated to computing other intersections,
|
|
|
|
it can be lazily done once the contour is found.
|
|
|
|
|
|
|
|
So
|
|
|
|
repeat the following
|
|
|
|
find the top segment of all contours
|
|
|
|
trace the outside, marking touching first and last segments as inside
|
|
|
|
continue tracing the touched segments with reversed outside/inside sense
|
|
|
|
once the edges are exhausted, remaining must be disjoint contours
|
|
|
|
send a ray from a disjoint point through all other contours
|
|
|
|
count the crossings, determine if disjoint is inside or outside, then continue
|
2012-05-18 20:50:33 +00:00
|
|
|
|
|
|
|
===
|
|
|
|
|
|
|
|
On Quadratic (and Cubic) Intersections
|
|
|
|
|
|
|
|
Currently, if only the end points touch, QuadracticIntersections does a lot of
|
|
|
|
work to figure that out. Can I test for that up front, then short circuit the
|
|
|
|
recursive search for the end points?
|
|
|
|
|
|
|
|
Or, is there something defective in the current approach that makes the end
|
|
|
|
point recursion go so deep? I'm seeing 56 stack frames (about 28 divides, but
|
|
|
|
thankfully, no splits) to find one matching endpoint.
|
|
|
|
|
|
|
|
|
|
|
|
Bezier curve focus may allow more quickly determining that end points with
|
|
|
|
identical tangents are practically coicident for some range of T, but I don't
|
|
|
|
understand the math yet to know.
|
|
|
|
|
|
|
|
Another approach is to determine how flat the curve is to make good guesses
|
|
|
|
about how far to move away in T before doing the intersection for the remainder
|
|
|
|
and/or to determine whether one curve is to the inside or outside of another.
|
|
|
|
According to Mike/Rob, the flatness for quadratics increases by 4 for each
|
|
|
|
subdivision, and a crude guess of the curvature can be had by comparing P1 to
|
|
|
|
(P0+P2)/2. By looking at the ULPS of the numbers, I can guess what value of
|
|
|
|
T may be far enough that the curves diverge but don't cross.
|