From 1f0d479a00b07bfad54aa1b94d8619033024e636 Mon Sep 17 00:00:00 2001 From: danielwboyce Date: Sun, 5 Jan 2020 12:26:52 -0700 Subject: [PATCH 1/3] bugfix of node_in_or_on_polygon function in utils/geom.c so that it no longer adds spurious lines to polygon renders --- utils/geom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/geom.c b/utils/geom.c index a83beb8..7883232 100644 --- a/utils/geom.c +++ b/utils/geom.c @@ -2062,7 +2062,7 @@ boolean node_in_or_on_polygon(vector3 q0, vector3 *nodes, int num_nodes, // Consider all edges while (checkedPoints < num_nodes) { int savedIndex = (nn + 1) % num_nodes; - int savedX = nodes[savedIndex].x; + double savedX = nodes[savedIndex].x; // Move to next point which is not on the x-axis do { @@ -2085,7 +2085,7 @@ boolean node_in_or_on_polygon(vector3 q0, vector3 *nodes, int num_nodes, // If at least one node on the right side has been skipped, // the original edge would have been intersected // --> intersect with full x-axis - else if (savedX > THRESH) { + else if (savedX > q0.x + THRESH) { int status = intersect_line_with_segment(q0, startPoint, endPoint, xAxis, 0); if (status == INTERSECTING) { edges_crossed++; } } From 3ced329aac957c4d0751cf648e00a5848c657ac4 Mon Sep 17 00:00:00 2001 From: danielwboyce Date: Sun, 5 Jan 2020 12:27:55 -0700 Subject: [PATCH 2/3] added unit test to utils/test-prism.c to test accuracy of point in polygon engine around a slanted H polygon that was giving us troubles before --- utils/ctlgeom.h | 3 ++ utils/test-prism.c | 86 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/utils/ctlgeom.h b/utils/ctlgeom.h index 5fd3375..6fe2bba 100644 --- a/utils/ctlgeom.h +++ b/utils/ctlgeom.h @@ -152,6 +152,9 @@ GEOMETRIC_OBJECT make_block(MATERIAL_TYPE material, vector3 center, vector3 e1, GEOMETRIC_OBJECT make_ellipsoid(MATERIAL_TYPE material, vector3 center, vector3 e1, vector3 e2, vector3 e3, vector3 size); +extern boolean node_in_or_on_polygon(vector3 q0, vector3 *nodes, int num_nodes, + boolean include_boundaries); + // prism with `center` field computed automatically from vertices, height, axis GEOMETRIC_OBJECT make_prism(MATERIAL_TYPE material, const vector3 *vertices, int num_vertices, double height, vector3 axis); diff --git a/utils/test-prism.c b/utils/test-prism.c index b5b9188..49d3576 100644 --- a/utils/test-prism.c +++ b/utils/test-prism.c @@ -366,6 +366,89 @@ int test_line_segment_intersection(geometric_object the_block, geometric_object return num_failed; } +/************************************************************************/ +/* fourth unit test: check of point in polygon test with slanted H */ +/************************************************************************/ +int test_point_in_polygon(int write_log) { + // make array of test points that should always pass + vector3 pass[5]; + pass[0] = make_vector3(0.3, 0.5, 0.0); + pass[1] = make_vector3(0.4, 0.4, 0.0); + pass[2] = make_vector3(0.5, 0.7, 0.0); + pass[3] = make_vector3(0.5, 0.5, 0.0); + pass[4] = make_vector3(0.5, 0.3, 0.0); + + // make array of test points that should always pass + vector3 fail[5]; + fail[0] = make_vector3(0.2, 0.2, 0.0); + fail[1] = make_vector3(0.3, 0.3, 0.0); + fail[2] = make_vector3(0.4, 0.6, 0.0); + fail[3] = make_vector3(0.6, 0.4, 0.0); + fail[4] = make_vector3(0.7, 0.7, 0.0); + + // make array of nodes for the test polygon (an H slanted by 45 degrees) + int num_nodes = 12; + vector3 nodes[num_nodes]; + nodes[0] = make_vector3(0.5, 0.2, 0.0); + nodes[1] = make_vector3(0.6, 0.3, 0.0); + nodes[2] = make_vector3(0.5, 0.4, 0.0); + nodes[3] = make_vector3(0.6, 0.5, 0.0); + nodes[4] = make_vector3(0.7, 0.4, 0.0); + nodes[5] = make_vector3(0.8, 0.5, 0.0); + nodes[6] = make_vector3(0.5, 0.8, 0.0); + nodes[7] = make_vector3(0.4, 0.7, 0.0); + nodes[8] = make_vector3(0.5, 0.6, 0.0); + nodes[9] = make_vector3(0.4, 0.5, 0.0); + nodes[10] = make_vector3(0.3, 0.6, 0.0); + nodes[11] = make_vector3(0.2, 0.5, 0.0); + + FILE *f = write_log ? fopen("/tmp/test-prism.point-in-polygon", "w") : 0; + + boolean all_points_success = 1; + boolean include_boundaries = 1; + int i; + for (i = 0; i < 5; i++) { + boolean local_success = node_in_or_on_polygon(pass[i], nodes, num_nodes, include_boundaries); + if (!local_success) { + all_points_success = 0; + } + if (f) { + fprintf(f, "%f %f %i\n", pass[i].x, pass[i].y, local_success); + } + } + for (i = 0; i < 5; i++) { + boolean local_success = !node_in_or_on_polygon(fail[i], nodes, num_nodes, include_boundaries); + if (!local_success) { + all_points_success = 0; + } + if (f) { + fprintf(f, "%f %f %i\n", pass[i].x, pass[i].y, local_success); + } + } + + if (f) { + if (all_points_success) { + printf("all test points for slanted H pass and fail as expected\n"); + } + else { + printf("one or more test points for slanted H do not pass and fail as expected\n"); + } + fclose(f); + } + + int num_failed; + if (all_points_success) { + num_failed = 0; + printf("all test points for slanted H pass and fail as expected\n"); + } + else { + num_failed = 1; + printf("one or more test points for slanted H do not pass and fail as expected\n"); + } + + return num_failed; +} + /***************************************************************/ /* unit tests: create the same parallelepiped two ways (as a */ /* block and as a prism) and verify that geometric primitives */ @@ -425,8 +508,9 @@ int run_unit_tests() { // although the distinction is only significant in cases where it is irrelevant int num_failed_2 = 0; // test_normal_to_object(the_block, the_prism, NUMLINES, write_log); int num_failed_3 = test_line_segment_intersection(the_block, the_prism, NUMLINES, write_log); + int num_failed_4 = test_point_in_polygon(write_log); - return num_failed_1 + num_failed_2 + num_failed_3; + return num_failed_1 + num_failed_2 + num_failed_3 + num_failed_4; } /***************************************************************/ From 5a8df2c5c354e78398f3eb3054f9f7edb64167a3 Mon Sep 17 00:00:00 2001 From: danielwboyce Date: Sun, 5 Jan 2020 12:38:21 -0700 Subject: [PATCH 3/3] slight change to messages generated by unit test 4 --- utils/test-prism.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/test-prism.c b/utils/test-prism.c index 49d3576..12eb0b5 100644 --- a/utils/test-prism.c +++ b/utils/test-prism.c @@ -428,10 +428,10 @@ int test_point_in_polygon(int write_log) { if (f) { if (all_points_success) { - printf("all test points for slanted H pass and fail as expected\n"); + printf("all test points for slanted H pass\n"); } else { - printf("one or more test points for slanted H do not pass and fail as expected\n"); + printf("one or more test points for slanted H fail\n"); } fclose(f); } @@ -439,11 +439,11 @@ int test_point_in_polygon(int write_log) { int num_failed; if (all_points_success) { num_failed = 0; - printf("all test points for slanted H pass and fail as expected\n"); + printf("all test points for slanted H pass\n"); } else { num_failed = 1; - printf("one or more test points for slanted H do not pass and fail as expected\n"); + printf("one or more test points for slanted H fail\n"); } return num_failed;