[Commit] tess ChangeLog,1.1,1.2 bentley.5c,1.2,1.3
Carl Worth
commit at keithp.com
Wed Jul 7 08:47:27 PDT 2004
Committed by: cworth
Update of /local/src/CVS/tess
In directory home.keithp.com:/tmp/cvs-serv30124
Modified Files:
ChangeLog bentley.5c
Log Message:
(intersect_lines): Rename intersect to intersect_lines.
(intersect_segments): New function that calls intersect_lines and
checks whether the intersection lies within both segments.
(edges_have_an_intersection_quadratic): New O(n**2) algorithm to
check if there are any remaining intersections after the main
algorithm is complete.
Added a few focused test cases and one random test.
Index: ChangeLog
===================================================================
RCS file: /local/src/CVS/tess/ChangeLog,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ChangeLog 7 Jul 2004 15:32:35 -0000 1.1
+++ ChangeLog 7 Jul 2004 15:47:25 -0000 1.2
@@ -2,4 +2,11 @@
* bentley.5c: Move SVG printing up to the top-level to declutter
the algorithm.
+ (intersect_lines): Rename intersect to intersect_lines.
+ (intersect_segments): New function that calls intersect_lines and
+ checks whether the intersection lies within both segments.
+ (edges_have_an_intersection_quadratic): New O(n**2) algorithm to
+ check if there are any remaining intersections after the main
+ algorithm is complete.
+ Added a few focused test cases and one random test.
Index: bentley.5c
===================================================================
RCS file: /local/src/CVS/tess/bentley.5c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- bentley.5c 7 Jul 2004 15:32:35 -0000 1.2
+++ bentley.5c 7 Jul 2004 15:47:25 -0000 1.3
@@ -79,8 +79,10 @@
exception parallel (void);
-RationalPoint intersect (Edge a, Edge b) {
+exception no_intersection (void);
+RationalPoint intersect_lines (Edge a, Edge b)
+{
int det (int a, int b, int c, int d) {
return a * d - b * c;
}
@@ -109,6 +111,30 @@
};
}
+/* XXX: As should be obvious, this function is a bit simpler in the
+ * absence of horizontal edges */
+RationalPoint intersect_segments (Edge a, Edge b)
+{
+ RationalPoint intersection = intersect_lines (a, b);
+
+ if (a.top.y == a.bottom.y) {
+ if (intersection.x <= a.top.x || intersection.x >= a.bottom.x)
+ raise no_intersection ();
+ } else {
+ if (intersection.y <= a.top.y || intersection.y >= a.bottom.y)
+ raise no_intersection ();
+ }
+
+ if (b.top.y == b.bottom.y) {
+ if (intersection.x <= b.top.x || intersection.x >= b.bottom.x)
+ raise no_intersection ();
+ } else {
+ if (intersection.y <= b.top.y || intersection.y >= b.bottom.y)
+ raise no_intersection ();
+ }
+
+ return intersection;
+}
bool event_ptr_greater (EventPtr a, EventPtr b)
{
@@ -334,7 +360,7 @@
RationalPoint intersection;
try {
- intersection = intersect (*a.elt, *b.elt);
+ intersection = intersect_lines (*a.elt, *b.elt);
} catch parallel () {
return;
}
@@ -450,11 +476,86 @@
return edges;
}
+bool edges_have_an_intersection_quadratic (Edge[*] edges)
+{
+ RationalPoint intersection;
+ Edge a, b;
+
+ for (int i=0; i < dim(edges); i++) {
+ if (point_greater (edges[i].top, edges[i].bottom)) {
+ Point tmp;
+ tmp = edges[i].top;
+ edges[i].top = edges[i].bottom;
+ edges[i].bottom = tmp;
+ }
+ }
+ for (int i=0; i < dim(edges); i++) {
+ for (int j=0; j < dim (edges); j++) {
+ if (i==j)
+ continue;
+ a = edges[i];
+ b = edges[j];
+ try {
+ intersection = intersect_segments (a, b);
+ } catch parallel () {
+ continue;
+ } catch no_intersection () {
+ continue;
+ }
+ printf ("Found intersection (%g,%g) between (%g,%g)-(%g,%g) and (%g,%g)-(%g,%g)\n",
+ intersection.x, intersection.y,
+ a.top.x, a.top.y,
+ a.bottom.x, a.bottom.y,
+ b.top.x, b.top.y,
+ b.bottom.x, b.bottom.y);
+ return true;
+ }
+ }
+ return false;
+}
+
/* Cool, degnerate case from Hobby's paper. Require's 3 passes until
* we implement tolerance squares. */
Edge[*] hobby_edges = { { top = { x = 0, y = 0}, bottom = { x = 9, y = 5}},
{ top = { x = 0, y = 0}, bottom = { x = 13, y = 6}},
- { top = { x = 9, y = 5}, bottom = { x = -1, y = -2}}
+ { top = { x = -1, y = -2}, bottom = { x = 9, y = 5}},
};
-bentley_ottman_iterative (hobby_edges);
+/* Some focused test for several corner cases. */
+Edge[*] slope_test = { { top = { x = 4, y = 1}, bottom = { x = 6, y = 3}},
+ { top = { x = 4, y = 1}, bottom = { x = 2, y = 3}},
+ { top = { x = 2, y = 4}, bottom = { x = 4, y = 6}},
+ { top = { x = 6, y = 4}, bottom = { x = 4, y = 6}}
+};
+
+Edge[*] horizontal_test = { { top = { x = 1, y = 1}, bottom = { x = 6, y = 6}},
+ { top = { x = 2, y = 3}, bottom = { x = 5, y = 3}}
+};
+
+Edge[*] vertical_test = { { top = { x = 5, y = 1}, bottom = { x = 5, y = 7}},
+ { top = { x = 2, y = 4}, bottom = { x = 8, y = 5}}
+};
+
+Edge[*] congruent_test = { { top = { x = 5, y = 1}, bottom = { x = 5, y = 7}},
+ { top = { x = 5, y = 2}, bottom = { x = 5, y = 6}},
+ { top = { x = 2, y = 4}, bottom = { x = 8, y = 5}}
+};
+
+num_random = 8;
+
+PRNG::srandom (0);
+Edge[...] random_edges = {};
+for (int i=0; i < num_random; i++)
+{
+ random_edges[dim (random_edges)] = (Edge) {
+ top = { x = PRNG::randint (10), y = PRNG::randint (10) },
+ bottom = { x = PRNG::randint (10), y = PRNG::randint (10) }
+ };
+}
+
+Edge[*] intersected_edges = bentley_ottman_iterative (congruent_test);
+
+if (edges_have_an_intersection_quadratic (intersected_edges))
+ printf ("Error: There's still at least one intersection left.\n");
+else
+ printf ("Phew: No intersections left\n");
More information about the Commit
mailing list