@sentryware/s2-node 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.circleci/config.yml +45 -0
- package/.dockerignore +1 -0
- package/.gitmodules +3 -0
- package/CHANGELOG.md +33 -0
- package/LICENSE +201 -0
- package/README.md +147 -0
- package/binding.gyp +170 -0
- package/docker/Dockerfile.node20.test +8 -0
- package/docker/Dockerfile.node22.test +8 -0
- package/docker/Dockerfile.node24.test +8 -0
- package/index.d.ts +117 -0
- package/index.js +6 -0
- package/jest.config.js +184 -0
- package/package.json +43 -0
- package/publish-linux.sh +18 -0
- package/publish-osx.sh +19 -0
- package/src/builder.cc +84 -0
- package/src/builder.h +29 -0
- package/src/cell.cc +71 -0
- package/src/cell.h +26 -0
- package/src/cell_id.cc +210 -0
- package/src/cell_id.h +44 -0
- package/src/cell_union.cc +237 -0
- package/src/cell_union.h +34 -0
- package/src/earth.cc +185 -0
- package/src/earth.h +33 -0
- package/src/latlng.cc +132 -0
- package/src/latlng.h +28 -0
- package/src/loop.cc +51 -0
- package/src/loop.h +21 -0
- package/src/point.cc +69 -0
- package/src/point.h +23 -0
- package/src/polygon.cc +36 -0
- package/src/polygon.h +20 -0
- package/src/polyline.cc +186 -0
- package/src/polyline.h +34 -0
- package/src/region_coverer.cc +450 -0
- package/src/region_coverer.h +56 -0
- package/src/s2.cc +27 -0
- package/test/Cell.test.js +37 -0
- package/test/CellId.test.js +135 -0
- package/test/CellUnion.test.js +150 -0
- package/test/Earth.test.js +62 -0
- package/test/LatLng.test.js +45 -0
- package/test/Point.test.js +14 -0
- package/test/Polyline.test.js +78 -0
- package/test/RegionCoverer.test.js +301 -0
- package/test.sh +16 -0
- package/third_party/s2geometry/.travis.yml +163 -0
- package/third_party/s2geometry/AUTHORS +13 -0
- package/third_party/s2geometry/CONTRIBUTING.md +65 -0
- package/third_party/s2geometry/CONTRIBUTORS +30 -0
- package/third_party/s2geometry/LICENSE +202 -0
- package/third_party/s2geometry/NOTICE +5 -0
- package/third_party/s2geometry/README.md +127 -0
- package/third_party/s2geometry/doc/examples/point_index.cc +44 -0
- package/third_party/s2geometry/doc/examples/term_index.cc +99 -0
- package/third_party/s2geometry/doc/examples/term_index.py +101 -0
- package/third_party/s2geometry/src/python/coder.i +125 -0
- package/third_party/s2geometry/src/python/pywraps2_test.py +786 -0
- package/third_party/s2geometry/src/python/s2.i +37 -0
- package/third_party/s2geometry/src/python/s2_common.i +756 -0
- package/third_party/s2geometry/src/s2/_fp_contract_off.h +60 -0
- package/third_party/s2geometry/src/s2/base/casts.h +318 -0
- package/third_party/s2geometry/src/s2/base/commandlineflags.h +67 -0
- package/third_party/s2geometry/src/s2/base/integral_types.h +31 -0
- package/third_party/s2geometry/src/s2/base/log_severity.h +40 -0
- package/third_party/s2geometry/src/s2/base/logging.h +173 -0
- package/third_party/s2geometry/src/s2/base/mutex.h +61 -0
- package/third_party/s2geometry/src/s2/base/port.h +999 -0
- package/third_party/s2geometry/src/s2/base/spinlock.h +60 -0
- package/third_party/s2geometry/src/s2/base/stringprintf.cc +107 -0
- package/third_party/s2geometry/src/s2/base/stringprintf.h +53 -0
- package/third_party/s2geometry/src/s2/base/strtoint.cc +65 -0
- package/third_party/s2geometry/src/s2/base/strtoint.h +106 -0
- package/third_party/s2geometry/src/s2/base/timer.h +50 -0
- package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector.cc +164 -0
- package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector.h +110 -0
- package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector_test.cc +232 -0
- package/third_party/s2geometry/src/s2/encoded_s2point_vector.cc +838 -0
- package/third_party/s2geometry/src/s2/encoded_s2point_vector.h +140 -0
- package/third_party/s2geometry/src/s2/encoded_s2point_vector_test.cc +344 -0
- package/third_party/s2geometry/src/s2/encoded_s2shape_index.cc +181 -0
- package/third_party/s2geometry/src/s2/encoded_s2shape_index.h +276 -0
- package/third_party/s2geometry/src/s2/encoded_s2shape_index_test.cc +244 -0
- package/third_party/s2geometry/src/s2/encoded_string_vector.cc +66 -0
- package/third_party/s2geometry/src/s2/encoded_string_vector.h +164 -0
- package/third_party/s2geometry/src/s2/encoded_string_vector_test.cc +69 -0
- package/third_party/s2geometry/src/s2/encoded_uint_vector.h +299 -0
- package/third_party/s2geometry/src/s2/encoded_uint_vector_test.cc +124 -0
- package/third_party/s2geometry/src/s2/id_set_lexicon.cc +81 -0
- package/third_party/s2geometry/src/s2/id_set_lexicon.h +199 -0
- package/third_party/s2geometry/src/s2/id_set_lexicon_test.cc +70 -0
- package/third_party/s2geometry/src/s2/mutable_s2shape_index.cc +1585 -0
- package/third_party/s2geometry/src/s2/mutable_s2shape_index.h +600 -0
- package/third_party/s2geometry/src/s2/mutable_s2shape_index_test.cc +589 -0
- package/third_party/s2geometry/src/s2/r1interval.h +220 -0
- package/third_party/s2geometry/src/s2/r1interval_test.cc +185 -0
- package/third_party/s2geometry/src/s2/r2.h +26 -0
- package/third_party/s2geometry/src/s2/r2rect.cc +93 -0
- package/third_party/s2geometry/src/s2/r2rect.h +234 -0
- package/third_party/s2geometry/src/s2/r2rect_test.cc +228 -0
- package/third_party/s2geometry/src/s2/s1angle.cc +54 -0
- package/third_party/s2geometry/src/s2/s1angle.h +336 -0
- package/third_party/s2geometry/src/s2/s1angle_test.cc +185 -0
- package/third_party/s2geometry/src/s2/s1chord_angle.cc +159 -0
- package/third_party/s2geometry/src/s2/s1chord_angle.h +369 -0
- package/third_party/s2geometry/src/s2/s1chord_angle_test.cc +207 -0
- package/third_party/s2geometry/src/s2/s1interval.cc +296 -0
- package/third_party/s2geometry/src/s2/s1interval.h +266 -0
- package/third_party/s2geometry/src/s2/s1interval_test.cc +469 -0
- package/third_party/s2geometry/src/s2/s2boolean_operation.cc +2391 -0
- package/third_party/s2geometry/src/s2/s2boolean_operation.h +501 -0
- package/third_party/s2geometry/src/s2/s2boolean_operation_test.cc +1400 -0
- package/third_party/s2geometry/src/s2/s2builder.cc +1828 -0
- package/third_party/s2geometry/src/s2/s2builder.h +1057 -0
- package/third_party/s2geometry/src/s2/s2builder_graph.cc +1084 -0
- package/third_party/s2geometry/src/s2/s2builder_graph.h +799 -0
- package/third_party/s2geometry/src/s2/s2builder_graph_test.cc +462 -0
- package/third_party/s2geometry/src/s2/s2builder_layer.h +50 -0
- package/third_party/s2geometry/src/s2/s2builder_test.cc +1329 -0
- package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer.cc +313 -0
- package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer.h +221 -0
- package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer_test.cc +261 -0
- package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies.cc +392 -0
- package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies.h +86 -0
- package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies_test.cc +182 -0
- package/third_party/s2geometry/src/s2/s2builderutil_graph_shape.h +57 -0
- package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer.cc +212 -0
- package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer.h +218 -0
- package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer_test.cc +367 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer.cc +74 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer.h +122 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer_test.cc +167 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer.cc +191 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer.h +211 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer_test.cc +312 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer.cc +105 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer.h +174 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer_test.cc +220 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer.cc +98 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer.h +292 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer_test.cc +233 -0
- package/third_party/s2geometry/src/s2/s2builderutil_snap_functions.cc +354 -0
- package/third_party/s2geometry/src/s2/s2builderutil_snap_functions.h +239 -0
- package/third_party/s2geometry/src/s2/s2builderutil_snap_functions_test.cc +716 -0
- package/third_party/s2geometry/src/s2/s2builderutil_testing.cc +37 -0
- package/third_party/s2geometry/src/s2/s2builderutil_testing.h +100 -0
- package/third_party/s2geometry/src/s2/s2builderutil_testing_test.cc +85 -0
- package/third_party/s2geometry/src/s2/s2cap.cc +347 -0
- package/third_party/s2geometry/src/s2/s2cap.h +286 -0
- package/third_party/s2geometry/src/s2/s2cap_test.cc +379 -0
- package/third_party/s2geometry/src/s2/s2cell.cc +552 -0
- package/third_party/s2geometry/src/s2/s2cell.h +249 -0
- package/third_party/s2geometry/src/s2/s2cell_id.cc +619 -0
- package/third_party/s2geometry/src/s2/s2cell_id.h +705 -0
- package/third_party/s2geometry/src/s2/s2cell_id_test.cc +633 -0
- package/third_party/s2geometry/src/s2/s2cell_index.cc +149 -0
- package/third_party/s2geometry/src/s2/s2cell_index.h +660 -0
- package/third_party/s2geometry/src/s2/s2cell_index_test.cc +411 -0
- package/third_party/s2geometry/src/s2/s2cell_test.cc +687 -0
- package/third_party/s2geometry/src/s2/s2cell_union.cc +515 -0
- package/third_party/s2geometry/src/s2/s2cell_union.h +399 -0
- package/third_party/s2geometry/src/s2/s2cell_union_test.cc +598 -0
- package/third_party/s2geometry/src/s2/s2centroids.cc +84 -0
- package/third_party/s2geometry/src/s2/s2centroids.h +87 -0
- package/third_party/s2geometry/src/s2/s2centroids_test.cc +82 -0
- package/third_party/s2geometry/src/s2/s2closest_cell_query.cc +123 -0
- package/third_party/s2geometry/src/s2/s2closest_cell_query.h +385 -0
- package/third_party/s2geometry/src/s2/s2closest_cell_query_base.h +841 -0
- package/third_party/s2geometry/src/s2/s2closest_cell_query_base_test.cc +63 -0
- package/third_party/s2geometry/src/s2/s2closest_cell_query_test.cc +412 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query.cc +106 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query.h +421 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query_base.h +946 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query_base_test.cc +59 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query_test.cc +505 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query_testing.h +91 -0
- package/third_party/s2geometry/src/s2/s2closest_point_query.cc +66 -0
- package/third_party/s2geometry/src/s2/s2closest_point_query.h +465 -0
- package/third_party/s2geometry/src/s2/s2closest_point_query_base.h +767 -0
- package/third_party/s2geometry/src/s2/s2closest_point_query_base_test.cc +63 -0
- package/third_party/s2geometry/src/s2/s2closest_point_query_test.cc +312 -0
- package/third_party/s2geometry/src/s2/s2contains_point_query.h +328 -0
- package/third_party/s2geometry/src/s2/s2contains_point_query_test.cc +159 -0
- package/third_party/s2geometry/src/s2/s2contains_vertex_query.cc +39 -0
- package/third_party/s2geometry/src/s2/s2contains_vertex_query.h +66 -0
- package/third_party/s2geometry/src/s2/s2contains_vertex_query_test.cc +67 -0
- package/third_party/s2geometry/src/s2/s2convex_hull_query.cc +198 -0
- package/third_party/s2geometry/src/s2/s2convex_hull_query.h +110 -0
- package/third_party/s2geometry/src/s2/s2convex_hull_query_test.cc +208 -0
- package/third_party/s2geometry/src/s2/s2coords.cc +146 -0
- package/third_party/s2geometry/src/s2/s2coords.h +459 -0
- package/third_party/s2geometry/src/s2/s2coords_internal.h +71 -0
- package/third_party/s2geometry/src/s2/s2coords_test.cc +218 -0
- package/third_party/s2geometry/src/s2/s2crossing_edge_query.cc +380 -0
- package/third_party/s2geometry/src/s2/s2crossing_edge_query.h +220 -0
- package/third_party/s2geometry/src/s2/s2crossing_edge_query_test.cc +382 -0
- package/third_party/s2geometry/src/s2/s2debug.cc +23 -0
- package/third_party/s2geometry/src/s2/s2debug.h +69 -0
- package/third_party/s2geometry/src/s2/s2distance_target.h +165 -0
- package/third_party/s2geometry/src/s2/s2earth.cc +52 -0
- package/third_party/s2geometry/src/s2/s2earth.h +268 -0
- package/third_party/s2geometry/src/s2/s2earth_test.cc +146 -0
- package/third_party/s2geometry/src/s2/s2edge_clipping.cc +462 -0
- package/third_party/s2geometry/src/s2/s2edge_clipping.h +183 -0
- package/third_party/s2geometry/src/s2/s2edge_clipping_test.cc +335 -0
- package/third_party/s2geometry/src/s2/s2edge_crosser.cc +85 -0
- package/third_party/s2geometry/src/s2/s2edge_crosser.h +343 -0
- package/third_party/s2geometry/src/s2/s2edge_crosser_test.cc +264 -0
- package/third_party/s2geometry/src/s2/s2edge_crossings.cc +515 -0
- package/third_party/s2geometry/src/s2/s2edge_crossings.h +138 -0
- package/third_party/s2geometry/src/s2/s2edge_crossings_internal.h +59 -0
- package/third_party/s2geometry/src/s2/s2edge_crossings_test.cc +246 -0
- package/third_party/s2geometry/src/s2/s2edge_distances.cc +419 -0
- package/third_party/s2geometry/src/s2/s2edge_distances.h +192 -0
- package/third_party/s2geometry/src/s2/s2edge_distances_test.cc +539 -0
- package/third_party/s2geometry/src/s2/s2edge_tessellator.cc +276 -0
- package/third_party/s2geometry/src/s2/s2edge_tessellator.h +101 -0
- package/third_party/s2geometry/src/s2/s2edge_tessellator_test.cc +492 -0
- package/third_party/s2geometry/src/s2/s2edge_vector_shape.h +85 -0
- package/third_party/s2geometry/src/s2/s2edge_vector_shape_test.cc +66 -0
- package/third_party/s2geometry/src/s2/s2error.cc +29 -0
- package/third_party/s2geometry/src/s2/s2error.h +147 -0
- package/third_party/s2geometry/src/s2/s2error_test.cc +31 -0
- package/third_party/s2geometry/src/s2/s2furthest_edge_query.cc +117 -0
- package/third_party/s2geometry/src/s2/s2furthest_edge_query.h +439 -0
- package/third_party/s2geometry/src/s2/s2furthest_edge_query_test.cc +487 -0
- package/third_party/s2geometry/src/s2/s2latlng.cc +90 -0
- package/third_party/s2geometry/src/s2/s2latlng.h +234 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect.cc +727 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect.h +434 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect_bounder.cc +344 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect_bounder.h +89 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect_bounder_test.cc +306 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect_test.cc +1030 -0
- package/third_party/s2geometry/src/s2/s2latlng_test.cc +165 -0
- package/third_party/s2geometry/src/s2/s2lax_loop_shape.cc +104 -0
- package/third_party/s2geometry/src/s2/s2lax_loop_shape.h +153 -0
- package/third_party/s2geometry/src/s2/s2lax_loop_shape_test.cc +101 -0
- package/third_party/s2geometry/src/s2/s2lax_polygon_shape.cc +348 -0
- package/third_party/s2geometry/src/s2/s2lax_polygon_shape.h +183 -0
- package/third_party/s2geometry/src/s2/s2lax_polygon_shape_test.cc +234 -0
- package/third_party/s2geometry/src/s2/s2lax_polyline_shape.cc +118 -0
- package/third_party/s2geometry/src/s2/s2lax_polyline_shape.h +124 -0
- package/third_party/s2geometry/src/s2/s2lax_polyline_shape_test.cc +62 -0
- package/third_party/s2geometry/src/s2/s2loop.cc +1509 -0
- package/third_party/s2geometry/src/s2/s2loop.h +711 -0
- package/third_party/s2geometry/src/s2/s2loop_measures.cc +313 -0
- package/third_party/s2geometry/src/s2/s2loop_measures.h +280 -0
- package/third_party/s2geometry/src/s2/s2loop_measures_test.cc +367 -0
- package/third_party/s2geometry/src/s2/s2loop_test.cc +1371 -0
- package/third_party/s2geometry/src/s2/s2max_distance_targets.cc +265 -0
- package/third_party/s2geometry/src/s2/s2max_distance_targets.h +241 -0
- package/third_party/s2geometry/src/s2/s2max_distance_targets_test.cc +367 -0
- package/third_party/s2geometry/src/s2/s2measures.cc +128 -0
- package/third_party/s2geometry/src/s2/s2measures.h +78 -0
- package/third_party/s2geometry/src/s2/s2measures_test.cc +135 -0
- package/third_party/s2geometry/src/s2/s2metrics.cc +122 -0
- package/third_party/s2geometry/src/s2/s2metrics.h +199 -0
- package/third_party/s2geometry/src/s2/s2metrics_test.cc +127 -0
- package/third_party/s2geometry/src/s2/s2min_distance_targets.cc +295 -0
- package/third_party/s2geometry/src/s2/s2min_distance_targets.h +273 -0
- package/third_party/s2geometry/src/s2/s2min_distance_targets_test.cc +239 -0
- package/third_party/s2geometry/src/s2/s2padded_cell.cc +162 -0
- package/third_party/s2geometry/src/s2/s2padded_cell.h +108 -0
- package/third_party/s2geometry/src/s2/s2padded_cell_test.cc +138 -0
- package/third_party/s2geometry/src/s2/s2point.h +38 -0
- package/third_party/s2geometry/src/s2/s2point_compression.cc +388 -0
- package/third_party/s2geometry/src/s2/s2point_compression.h +78 -0
- package/third_party/s2geometry/src/s2/s2point_compression_test.cc +305 -0
- package/third_party/s2geometry/src/s2/s2point_index.h +345 -0
- package/third_party/s2geometry/src/s2/s2point_index_test.cc +147 -0
- package/third_party/s2geometry/src/s2/s2point_region.cc +72 -0
- package/third_party/s2geometry/src/s2/s2point_region.h +76 -0
- package/third_party/s2geometry/src/s2/s2point_region_test.cc +100 -0
- package/third_party/s2geometry/src/s2/s2point_span.h +57 -0
- package/third_party/s2geometry/src/s2/s2point_test.cc +47 -0
- package/third_party/s2geometry/src/s2/s2point_vector_shape.h +127 -0
- package/third_party/s2geometry/src/s2/s2point_vector_shape_test.cc +59 -0
- package/third_party/s2geometry/src/s2/s2pointutil.cc +131 -0
- package/third_party/s2geometry/src/s2/s2pointutil.h +138 -0
- package/third_party/s2geometry/src/s2/s2pointutil_test.cc +157 -0
- package/third_party/s2geometry/src/s2/s2polygon.cc +1569 -0
- package/third_party/s2geometry/src/s2/s2polygon.h +934 -0
- package/third_party/s2geometry/src/s2/s2polygon_test.cc +3025 -0
- package/third_party/s2geometry/src/s2/s2polyline.cc +645 -0
- package/third_party/s2geometry/src/s2/s2polyline.h +379 -0
- package/third_party/s2geometry/src/s2/s2polyline_alignment.cc +414 -0
- package/third_party/s2geometry/src/s2/s2polyline_alignment.h +245 -0
- package/third_party/s2geometry/src/s2/s2polyline_alignment_internal.h +158 -0
- package/third_party/s2geometry/src/s2/s2polyline_alignment_test.cc +610 -0
- package/third_party/s2geometry/src/s2/s2polyline_measures.cc +42 -0
- package/third_party/s2geometry/src/s2/s2polyline_measures.h +53 -0
- package/third_party/s2geometry/src/s2/s2polyline_measures_test.cc +57 -0
- package/third_party/s2geometry/src/s2/s2polyline_simplifier.cc +187 -0
- package/third_party/s2geometry/src/s2/s2polyline_simplifier.h +109 -0
- package/third_party/s2geometry/src/s2/s2polyline_simplifier_test.cc +165 -0
- package/third_party/s2geometry/src/s2/s2polyline_test.cc +554 -0
- package/third_party/s2geometry/src/s2/s2predicates.cc +1486 -0
- package/third_party/s2geometry/src/s2/s2predicates.h +282 -0
- package/third_party/s2geometry/src/s2/s2predicates_internal.h +135 -0
- package/third_party/s2geometry/src/s2/s2predicates_test.cc +1427 -0
- package/third_party/s2geometry/src/s2/s2projections.cc +109 -0
- package/third_party/s2geometry/src/s2/s2projections.h +161 -0
- package/third_party/s2geometry/src/s2/s2projections_test.cc +78 -0
- package/third_party/s2geometry/src/s2/s2r2rect.cc +88 -0
- package/third_party/s2geometry/src/s2/s2r2rect.h +292 -0
- package/third_party/s2geometry/src/s2/s2r2rect_test.cc +312 -0
- package/third_party/s2geometry/src/s2/s2region.cc +26 -0
- package/third_party/s2geometry/src/s2/s2region.h +142 -0
- package/third_party/s2geometry/src/s2/s2region_coverer.cc +514 -0
- package/third_party/s2geometry/src/s2/s2region_coverer.h +356 -0
- package/third_party/s2geometry/src/s2/s2region_coverer_test.cc +509 -0
- package/third_party/s2geometry/src/s2/s2region_intersection.cc +84 -0
- package/third_party/s2geometry/src/s2/s2region_intersection.h +79 -0
- package/third_party/s2geometry/src/s2/s2region_term_indexer.cc +270 -0
- package/third_party/s2geometry/src/s2/s2region_term_indexer.h +299 -0
- package/third_party/s2geometry/src/s2/s2region_term_indexer_test.cc +209 -0
- package/third_party/s2geometry/src/s2/s2region_test.cc +370 -0
- package/third_party/s2geometry/src/s2/s2region_union.cc +90 -0
- package/third_party/s2geometry/src/s2/s2region_union.h +83 -0
- package/third_party/s2geometry/src/s2/s2region_union_test.cc +89 -0
- package/third_party/s2geometry/src/s2/s2shape.h +283 -0
- package/third_party/s2geometry/src/s2/s2shape_index.cc +321 -0
- package/third_party/s2geometry/src/s2/s2shape_index.h +781 -0
- package/third_party/s2geometry/src/s2/s2shape_index_buffered_region.cc +113 -0
- package/third_party/s2geometry/src/s2/s2shape_index_buffered_region.h +135 -0
- package/third_party/s2geometry/src/s2/s2shape_index_buffered_region_test.cc +162 -0
- package/third_party/s2geometry/src/s2/s2shape_index_measures.cc +92 -0
- package/third_party/s2geometry/src/s2/s2shape_index_measures.h +100 -0
- package/third_party/s2geometry/src/s2/s2shape_index_measures_test.cc +136 -0
- package/third_party/s2geometry/src/s2/s2shape_index_region.h +350 -0
- package/third_party/s2geometry/src/s2/s2shape_index_region_test.cc +161 -0
- package/third_party/s2geometry/src/s2/s2shape_index_test.cc +24 -0
- package/third_party/s2geometry/src/s2/s2shape_measures.cc +138 -0
- package/third_party/s2geometry/src/s2/s2shape_measures.h +95 -0
- package/third_party/s2geometry/src/s2/s2shape_measures_test.cc +139 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries.cc +120 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries.h +66 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries_test.cc +170 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_coding.cc +253 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_coding.h +283 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_coding_test.cc +54 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force.cc +40 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force.h +41 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force_test.cc +55 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_count_edges.h +57 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_count_edges_test.cc +43 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator.cc +45 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator.h +72 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator_test.cc +116 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point.cc +107 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point.h +48 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point_test.cc +104 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator.cc +58 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator.h +65 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator_test.cc +61 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_shape_edge.h +58 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_shape_edge_id.h +97 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_testing.cc +104 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_testing.h +36 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs.cc +440 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs.h +72 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs_test.cc +184 -0
- package/third_party/s2geometry/src/s2/s2testing.cc +464 -0
- package/third_party/s2geometry/src/s2/s2testing.h +385 -0
- package/third_party/s2geometry/src/s2/s2testing_test.cc +166 -0
- package/third_party/s2geometry/src/s2/s2text_format.cc +506 -0
- package/third_party/s2geometry/src/s2/s2text_format.h +289 -0
- package/third_party/s2geometry/src/s2/s2text_format_test.cc +417 -0
- package/third_party/s2geometry/src/s2/s2wedge_relations.cc +80 -0
- package/third_party/s2geometry/src/s2/s2wedge_relations.h +64 -0
- package/third_party/s2geometry/src/s2/s2wedge_relations_test.cc +89 -0
- package/third_party/s2geometry/src/s2/sequence_lexicon.h +296 -0
- package/third_party/s2geometry/src/s2/sequence_lexicon_test.cc +113 -0
- package/third_party/s2geometry/src/s2/strings/ostringstream.cc +35 -0
- package/third_party/s2geometry/src/s2/strings/ostringstream.h +105 -0
- package/third_party/s2geometry/src/s2/strings/serialize.cc +46 -0
- package/third_party/s2geometry/src/s2/strings/serialize.h +40 -0
- package/third_party/s2geometry/src/s2/third_party/absl/algorithm/algorithm.h +187 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/attributes.h +666 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/casts.h +189 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/config.h +462 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/dynamic_annotations.cc +129 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/dynamic_annotations.h +394 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/atomic_hook.h +168 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/identity.h +33 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/inline_variable.h +117 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/invoke.h +188 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/raw_logging.cc +254 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/raw_logging.h +205 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/throw_delegate.cc +106 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/throw_delegate.h +71 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/unaligned_access.h +322 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/log_severity.h +77 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/macros.h +236 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/optimization.h +177 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/policy_checks.h +124 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/port.h +97 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/thread_annotations.h +277 -0
- package/third_party/s2geometry/src/s2/third_party/absl/container/fixed_array.h +523 -0
- package/third_party/s2geometry/src/s2/third_party/absl/container/inlined_vector.h +1453 -0
- package/third_party/s2geometry/src/s2/third_party/absl/container/internal/compressed_tuple.h +191 -0
- package/third_party/s2geometry/src/s2/third_party/absl/container/internal/container_memory.h +424 -0
- package/third_party/s2geometry/src/s2/third_party/absl/container/internal/layout.h +739 -0
- package/third_party/s2geometry/src/s2/third_party/absl/memory/memory.h +755 -0
- package/third_party/s2geometry/src/s2/third_party/absl/meta/type_traits.h +436 -0
- package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128.cc +232 -0
- package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128.h +656 -0
- package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128_have_intrinsic.inc +3 -0
- package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128_no_intrinsic.inc +3 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii.cc +198 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii.h +239 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii_ctype.h +66 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/bits.h +53 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/memutil.cc +110 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/memutil.h +146 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/resize_uninitialized.h +72 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/match.cc +38 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/match.h +89 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/numbers.cc +909 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/numbers.h +187 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/str_cat.cc +240 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/str_cat.h +398 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/str_join.h +22 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/str_split.cc +47 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/str_split.h +43 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/string_view.cc +245 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/string_view.h +602 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/strip.cc +42 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/strip.h +130 -0
- package/third_party/s2geometry/src/s2/third_party/absl/types/span.h +793 -0
- package/third_party/s2geometry/src/s2/third_party/absl/utility/utility.h +299 -0
- package/third_party/s2geometry/src/s2/util/bits/bit-interleave.cc +274 -0
- package/third_party/s2geometry/src/s2/util/bits/bit-interleave.h +53 -0
- package/third_party/s2geometry/src/s2/util/bits/bits.cc +155 -0
- package/third_party/s2geometry/src/s2/util/bits/bits.h +745 -0
- package/third_party/s2geometry/src/s2/util/coding/coder.cc +83 -0
- package/third_party/s2geometry/src/s2/util/coding/coder.h +553 -0
- package/third_party/s2geometry/src/s2/util/coding/nth-derivative.h +134 -0
- package/third_party/s2geometry/src/s2/util/coding/transforms.h +62 -0
- package/third_party/s2geometry/src/s2/util/coding/varint.cc +289 -0
- package/third_party/s2geometry/src/s2/util/coding/varint.h +476 -0
- package/third_party/s2geometry/src/s2/util/endian/endian.h +859 -0
- package/third_party/s2geometry/src/s2/util/gtl/btree.h +2471 -0
- package/third_party/s2geometry/src/s2/util/gtl/btree_container.h +411 -0
- package/third_party/s2geometry/src/s2/util/gtl/btree_map.h +79 -0
- package/third_party/s2geometry/src/s2/util/gtl/btree_set.h +73 -0
- package/third_party/s2geometry/src/s2/util/gtl/compact_array.h +653 -0
- package/third_party/s2geometry/src/s2/util/gtl/container_logging.h +291 -0
- package/third_party/s2geometry/src/s2/util/gtl/dense_hash_set.h +358 -0
- package/third_party/s2geometry/src/s2/util/gtl/densehashtable.h +1493 -0
- package/third_party/s2geometry/src/s2/util/gtl/hashtable_common.h +253 -0
- package/third_party/s2geometry/src/s2/util/gtl/layout.h +28 -0
- package/third_party/s2geometry/src/s2/util/gtl/legacy_random_shuffle.h +77 -0
- package/third_party/s2geometry/src/s2/util/hash/mix.h +76 -0
- package/third_party/s2geometry/src/s2/util/math/exactfloat/exactfloat.cc +832 -0
- package/third_party/s2geometry/src/s2/util/math/exactfloat/exactfloat.h +646 -0
- package/third_party/s2geometry/src/s2/util/math/mathutil.cc +75 -0
- package/third_party/s2geometry/src/s2/util/math/mathutil.h +189 -0
- package/third_party/s2geometry/src/s2/util/math/matrix3x3.h +574 -0
- package/third_party/s2geometry/src/s2/util/math/vector.h +569 -0
- package/third_party/s2geometry/src/s2/util/math/vector3_hash.h +54 -0
- package/third_party/s2geometry/src/s2/util/units/length-units.cc +21 -0
- package/third_party/s2geometry/src/s2/util/units/length-units.h +135 -0
- package/third_party/s2geometry/src/s2/util/units/physical-units.h +313 -0
- package/third_party/s2geometry/src/s2/value_lexicon.h +234 -0
- package/third_party/s2geometry/src/s2/value_lexicon_test.cc +121 -0
- package/third_party/s2geometry/third_party/cmake/FindGFlags.cmake +48 -0
- package/third_party/s2geometry/third_party/cmake/FindGlog.cmake +48 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
// Copyright 2005 Google Inc. All Rights Reserved.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS-IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
// Author: ericv@google.com (Eric Veach)
|
|
17
|
+
|
|
18
|
+
#include "s2/s2edge_crossings.h"
|
|
19
|
+
#include "s2/s2edge_crossings_internal.h"
|
|
20
|
+
|
|
21
|
+
#include <cmath>
|
|
22
|
+
|
|
23
|
+
#include "s2/base/logging.h"
|
|
24
|
+
#include "s2/s1angle.h"
|
|
25
|
+
#include "s2/s2edge_crosser.h"
|
|
26
|
+
#include "s2/s2pointutil.h"
|
|
27
|
+
#include "s2/s2predicates.h"
|
|
28
|
+
#include "s2/s2predicates_internal.h"
|
|
29
|
+
#include "s2/util/math/exactfloat/exactfloat.h"
|
|
30
|
+
|
|
31
|
+
namespace S2 {
|
|
32
|
+
|
|
33
|
+
using internal::GetIntersectionExact;
|
|
34
|
+
using internal::IntersectionMethod;
|
|
35
|
+
using internal::intersection_method_tally_;
|
|
36
|
+
using std::fabs;
|
|
37
|
+
using std::sqrt;
|
|
38
|
+
|
|
39
|
+
// All error bounds in this file are expressed in terms of the maximum
|
|
40
|
+
// rounding error for a floating-point type. The rounding error is half of
|
|
41
|
+
// the numeric_limits<T>::epsilon() value.
|
|
42
|
+
static constexpr double DBL_ERR = s2pred::rounding_epsilon<double>();
|
|
43
|
+
|
|
44
|
+
// kIntersectionError can be set somewhat arbitrarily, because the algorithm
|
|
45
|
+
// uses more precision when necessary in order to achieve the specified error.
|
|
46
|
+
// The only strict requirement is that kIntersectionError >= 2 * DBL_ERR
|
|
47
|
+
// radians. However, using a larger error tolerance makes the algorithm more
|
|
48
|
+
// efficient because it reduces the number of cases where exact arithmetic is
|
|
49
|
+
// needed.
|
|
50
|
+
const S1Angle kIntersectionError = S1Angle::Radians(8 * DBL_ERR);
|
|
51
|
+
|
|
52
|
+
const S1Angle kIntersectionMergeRadius = 2 * kIntersectionError;
|
|
53
|
+
|
|
54
|
+
namespace internal {
|
|
55
|
+
|
|
56
|
+
const S1Angle kIntersectionExactError = S1Angle::Radians(2 * DBL_ERR);
|
|
57
|
+
|
|
58
|
+
int* intersection_method_tally_ = nullptr;
|
|
59
|
+
|
|
60
|
+
const char* GetIntersectionMethodName(IntersectionMethod method) {
|
|
61
|
+
switch (method) {
|
|
62
|
+
case IntersectionMethod::SIMPLE: return "Simple";
|
|
63
|
+
case IntersectionMethod::SIMPLE_LD: return "Simple_ld";
|
|
64
|
+
case IntersectionMethod::STABLE: return "Stable";
|
|
65
|
+
case IntersectionMethod::STABLE_LD: return "Stable_ld";
|
|
66
|
+
case IntersectionMethod::EXACT: return "Exact";
|
|
67
|
+
default: return "Unknown";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
} // namespace internal
|
|
72
|
+
|
|
73
|
+
int CrossingSign(const S2Point& a, const S2Point& b,
|
|
74
|
+
const S2Point& c, const S2Point& d) {
|
|
75
|
+
S2EdgeCrosser crosser(&a, &b, &c);
|
|
76
|
+
return crosser.CrossingSign(&d);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
bool VertexCrossing(const S2Point& a, const S2Point& b,
|
|
80
|
+
const S2Point& c, const S2Point& d) {
|
|
81
|
+
// If A == B or C == D there is no intersection. We need to check this
|
|
82
|
+
// case first in case 3 or more input points are identical.
|
|
83
|
+
if (a == b || c == d) return false;
|
|
84
|
+
|
|
85
|
+
// If any other pair of vertices is equal, there is a crossing if and only
|
|
86
|
+
// if OrderedCCW() indicates that the edge AB is further CCW around the
|
|
87
|
+
// shared vertex O (either A or B) than the edge CD, starting from an
|
|
88
|
+
// arbitrary fixed reference point.
|
|
89
|
+
//
|
|
90
|
+
// Optimization: if AB=CD or AB=DC, we can avoid most of the calculations.
|
|
91
|
+
if (a == c) return (b == d) || s2pred::OrderedCCW(S2::Ortho(a), d, b, a);
|
|
92
|
+
if (b == d) return s2pred::OrderedCCW(S2::Ortho(b), c, a, b);
|
|
93
|
+
|
|
94
|
+
if (a == d) return (b == c) || s2pred::OrderedCCW(S2::Ortho(a), c, b, a);
|
|
95
|
+
if (b == c) return s2pred::OrderedCCW(S2::Ortho(b), d, a, b);
|
|
96
|
+
|
|
97
|
+
S2_LOG(DFATAL) << "VertexCrossing called with 4 distinct vertices";
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
bool EdgeOrVertexCrossing(const S2Point& a, const S2Point& b,
|
|
102
|
+
const S2Point& c, const S2Point& d) {
|
|
103
|
+
int crossing = CrossingSign(a, b, c, d);
|
|
104
|
+
if (crossing < 0) return false;
|
|
105
|
+
if (crossing > 0) return true;
|
|
106
|
+
return VertexCrossing(a, b, c, d);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
using Vector3_ld = Vector3<long double>;
|
|
110
|
+
using Vector3_xf = Vector3<ExactFloat>;
|
|
111
|
+
|
|
112
|
+
// Computes the cross product of "x" and "y", normalizes it to be unit length,
|
|
113
|
+
// and stores the result in "result". Also returns the length of the cross
|
|
114
|
+
// product before normalization, which is useful for estimating the amount of
|
|
115
|
+
// error in the result. For numerical stability, "x" and "y" should both be
|
|
116
|
+
// approximately unit length.
|
|
117
|
+
template <class T>
|
|
118
|
+
static T RobustNormalWithLength(const Vector3<T>& x, const Vector3<T>& y,
|
|
119
|
+
Vector3<T>* result) {
|
|
120
|
+
// This computes 2 * (x.CrossProd(y)), but has much better numerical
|
|
121
|
+
// stability when "x" and "y" are unit length.
|
|
122
|
+
Vector3<T> tmp = (x - y).CrossProd(x + y);
|
|
123
|
+
T length = tmp.Norm();
|
|
124
|
+
if (length != 0) {
|
|
125
|
+
*result = (1 / length) * tmp;
|
|
126
|
+
}
|
|
127
|
+
return 0.5 * length; // Since tmp == 2 * (x.CrossProd(y))
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// If the intersection point of the edges (a0,a1) and (b0,b1) can be computed
|
|
131
|
+
// to within an error of at most kIntersectionError by this function, then set
|
|
132
|
+
// "result" to the intersection point and return true.
|
|
133
|
+
//
|
|
134
|
+
// The intersection point is not guaranteed to have the correct sign
|
|
135
|
+
// (i.e., it may be either "result" or "-result").
|
|
136
|
+
template <class T>
|
|
137
|
+
static bool GetIntersectionSimple(const Vector3<T>& a0, const Vector3<T>& a1,
|
|
138
|
+
const Vector3<T>& b0, const Vector3<T>& b1,
|
|
139
|
+
Vector3<T>* result) {
|
|
140
|
+
// The code below computes the intersection point as
|
|
141
|
+
//
|
|
142
|
+
// (a0.CrossProd(a1)).CrossProd(b0.CrossProd(b1))
|
|
143
|
+
//
|
|
144
|
+
// except that it has better numerical stability and also computes a
|
|
145
|
+
// guaranteed error bound.
|
|
146
|
+
//
|
|
147
|
+
// Each cross product is computed as (X-Y).CrossProd(X+Y) using unit-length
|
|
148
|
+
// input vectors, which eliminates most of the cancellation error. However
|
|
149
|
+
// the error in the direction of the cross product can still become large if
|
|
150
|
+
// the two points are extremely close together. We can show that as long as
|
|
151
|
+
// the length of the cross product is at least (16 * sqrt(3) + 24) * DBL_ERR
|
|
152
|
+
// (about 6e-15), then the directional error is at most 5 * T_ERR (about
|
|
153
|
+
// 3e-19 when T == "long double"). (DBL_ERR appears in the first formula
|
|
154
|
+
// because the inputs are assumed to be normalized in double precision
|
|
155
|
+
// rather than in the given type T.)
|
|
156
|
+
//
|
|
157
|
+
// The third cross product is different because its inputs already have some
|
|
158
|
+
// error. Letting "result_len" be the length of the cross product, it can
|
|
159
|
+
// be shown that the error is at most
|
|
160
|
+
//
|
|
161
|
+
// (2 + 2 * sqrt(3) + 12 / result_len) * T_ERR
|
|
162
|
+
//
|
|
163
|
+
// We want this error to be at most kIntersectionError, which is true as
|
|
164
|
+
// long as "result_len" is at least kMinResultLen defined below.
|
|
165
|
+
|
|
166
|
+
constexpr T T_ERR = s2pred::rounding_epsilon<T>();
|
|
167
|
+
static const T kMinNormalLength = (16 * sqrt(3) + 24) * DBL_ERR;
|
|
168
|
+
static const T kMinResultLen =
|
|
169
|
+
12 / (kIntersectionError.radians() / T_ERR - (2 + 2 * sqrt(3)));
|
|
170
|
+
|
|
171
|
+
// On some platforms "long double" is the same as "double", and on these
|
|
172
|
+
// platforms this method always returns false (e.g. ARM, Win32). Rather
|
|
173
|
+
// than testing this directly, instead we look at kMinResultLen since this
|
|
174
|
+
// is a direct measure of whether "long double" has sufficient accuracy to
|
|
175
|
+
// be useful. If kMinResultLen > 0.5, it means that this method will fail
|
|
176
|
+
// even for edges that meet at an angle of 30 degrees. (On Intel platforms
|
|
177
|
+
// kMinResultLen corresponds to an intersection angle of about 0.04
|
|
178
|
+
// degrees.)
|
|
179
|
+
S2_DCHECK_LE(kMinResultLen, 0.5);
|
|
180
|
+
|
|
181
|
+
Vector3<T> a_norm, b_norm;
|
|
182
|
+
if (RobustNormalWithLength(a0, a1, &a_norm) >= kMinNormalLength &&
|
|
183
|
+
RobustNormalWithLength(b0, b1, &b_norm) >= kMinNormalLength &&
|
|
184
|
+
RobustNormalWithLength(a_norm, b_norm, result) >= kMinResultLen) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
static bool GetIntersectionSimpleLD(const S2Point& a0, const S2Point& a1,
|
|
191
|
+
const S2Point& b0, const S2Point& b1,
|
|
192
|
+
S2Point* result) {
|
|
193
|
+
Vector3_ld result_ld;
|
|
194
|
+
if (GetIntersectionSimple(Vector3_ld::Cast(a0), Vector3_ld::Cast(a1),
|
|
195
|
+
Vector3_ld::Cast(b0), Vector3_ld::Cast(b1),
|
|
196
|
+
&result_ld)) {
|
|
197
|
+
*result = S2Point::Cast(result_ld);
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Given a point X and a vector "a_norm" (not necessarily unit length),
|
|
204
|
+
// compute x.DotProd(a_norm) and return a bound on the error in the result.
|
|
205
|
+
// The remaining parameters allow this dot product to be computed more
|
|
206
|
+
// accurately and efficiently. They include the length of "a_norm"
|
|
207
|
+
// ("a_norm_len") and the edge endpoints "a0" and "a1".
|
|
208
|
+
template <class T>
|
|
209
|
+
static T GetProjection(const Vector3<T>& x,
|
|
210
|
+
const Vector3<T>& a_norm, T a_norm_len,
|
|
211
|
+
const Vector3<T>& a0, const Vector3<T>& a1,
|
|
212
|
+
T* error) {
|
|
213
|
+
// The error in the dot product is proportional to the lengths of the input
|
|
214
|
+
// vectors, so rather than using "x" itself (a unit-length vector) we use
|
|
215
|
+
// the vectors from "x" to the closer of the two edge endpoints. This
|
|
216
|
+
// typically reduces the error by a huge factor.
|
|
217
|
+
Vector3<T> x0 = x - a0;
|
|
218
|
+
Vector3<T> x1 = x - a1;
|
|
219
|
+
T x0_dist2 = x0.Norm2();
|
|
220
|
+
T x1_dist2 = x1.Norm2();
|
|
221
|
+
|
|
222
|
+
// If both distances are the same, we need to be careful to choose one
|
|
223
|
+
// endpoint deterministically so that the result does not change if the
|
|
224
|
+
// order of the endpoints is reversed.
|
|
225
|
+
T dist, result;
|
|
226
|
+
if (x0_dist2 < x1_dist2 || (x0_dist2 == x1_dist2 && x0 < x1)) {
|
|
227
|
+
dist = sqrt(x0_dist2);
|
|
228
|
+
result = x0.DotProd(a_norm);
|
|
229
|
+
} else {
|
|
230
|
+
dist = sqrt(x1_dist2);
|
|
231
|
+
result = x1.DotProd(a_norm);
|
|
232
|
+
}
|
|
233
|
+
// This calculation bounds the error from all sources: the computation of
|
|
234
|
+
// the normal, the subtraction of one endpoint, and the dot product itself.
|
|
235
|
+
// (DBL_ERR appears because the input points are assumed to be normalized in
|
|
236
|
+
// double precision rather than in the given type T.)
|
|
237
|
+
//
|
|
238
|
+
// For reference, the bounds that went into this calculation are:
|
|
239
|
+
// ||N'-N|| <= ((1 + 2 * sqrt(3))||N|| + 32 * sqrt(3) * DBL_ERR) * T_ERR
|
|
240
|
+
// |(A.B)'-(A.B)| <= (1.5 * (A.B) + 1.5 * ||A|| * ||B||) * T_ERR
|
|
241
|
+
// ||(X-Y)'-(X-Y)|| <= ||X-Y|| * T_ERR
|
|
242
|
+
constexpr T T_ERR = s2pred::rounding_epsilon<T>();
|
|
243
|
+
*error = (((3.5 + 2 * sqrt(3)) * a_norm_len + 32 * sqrt(3) * DBL_ERR)
|
|
244
|
+
* dist + 1.5 * fabs(result)) * T_ERR;
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Helper function for GetIntersectionStable(). It expects that the edges
|
|
249
|
+
// (a0,a1) and (b0,b1) have been sorted so that the first edge is longer.
|
|
250
|
+
template <class T>
|
|
251
|
+
static bool GetIntersectionStableSorted(
|
|
252
|
+
const Vector3<T>& a0, const Vector3<T>& a1,
|
|
253
|
+
const Vector3<T>& b0, const Vector3<T>& b1, Vector3<T>* result) {
|
|
254
|
+
S2_DCHECK_GE((a1 - a0).Norm2(), (b1 - b0).Norm2());
|
|
255
|
+
|
|
256
|
+
// Compute the normal of the plane through (a0, a1) in a stable way.
|
|
257
|
+
Vector3<T> a_norm = (a0 - a1).CrossProd(a0 + a1);
|
|
258
|
+
T a_norm_len = a_norm.Norm();
|
|
259
|
+
T b_len = (b1 - b0).Norm();
|
|
260
|
+
|
|
261
|
+
// Compute the projection (i.e., signed distance) of b0 and b1 onto the
|
|
262
|
+
// plane through (a0, a1). Distances are scaled by the length of a_norm.
|
|
263
|
+
T b0_error, b1_error;
|
|
264
|
+
T b0_dist = GetProjection(b0, a_norm, a_norm_len, a0, a1, &b0_error);
|
|
265
|
+
T b1_dist = GetProjection(b1, a_norm, a_norm_len, a0, a1, &b1_error);
|
|
266
|
+
|
|
267
|
+
// The total distance from b0 to b1 measured perpendicularly to (a0,a1) is
|
|
268
|
+
// |b0_dist - b1_dist|. Note that b0_dist and b1_dist generally have
|
|
269
|
+
// opposite signs because b0 and b1 are on opposite sides of (a0, a1). The
|
|
270
|
+
// code below finds the intersection point by interpolating along the edge
|
|
271
|
+
// (b0, b1) to a fractional distance of b0_dist / (b0_dist - b1_dist).
|
|
272
|
+
//
|
|
273
|
+
// It can be shown that the maximum error in the interpolation fraction is
|
|
274
|
+
//
|
|
275
|
+
// (b0_dist * b1_error - b1_dist * b0_error) /
|
|
276
|
+
// (dist_sum * (dist_sum - error_sum))
|
|
277
|
+
//
|
|
278
|
+
// We save ourselves some work by scaling the result and the error bound by
|
|
279
|
+
// "dist_sum", since the result is normalized to be unit length anyway.
|
|
280
|
+
T dist_sum = fabs(b0_dist - b1_dist);
|
|
281
|
+
T error_sum = b0_error + b1_error;
|
|
282
|
+
if (dist_sum <= error_sum) {
|
|
283
|
+
return false; // Error is unbounded in this case.
|
|
284
|
+
}
|
|
285
|
+
Vector3<T> x = b0_dist * b1 - b1_dist * b0;
|
|
286
|
+
constexpr T T_ERR = s2pred::rounding_epsilon<T>();
|
|
287
|
+
T error = b_len * fabs(b0_dist * b1_error - b1_dist * b0_error) /
|
|
288
|
+
(dist_sum - error_sum) + 2 * T_ERR * dist_sum;
|
|
289
|
+
|
|
290
|
+
// Finally we normalize the result, compute the corresponding error, and
|
|
291
|
+
// check whether the total error is acceptable.
|
|
292
|
+
T x_len2 = x.Norm2();
|
|
293
|
+
if (x_len2 < std::numeric_limits<T>::min()) {
|
|
294
|
+
// If x.Norm2() is less than the minimum normalized value of T, x_len might
|
|
295
|
+
// lose precision and the result might fail to satisfy S2::IsUnitLength().
|
|
296
|
+
// TODO(ericv): Implement S2::RobustNormalize().
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
T x_len = sqrt(x_len2);
|
|
300
|
+
const T kMaxError = kIntersectionError.radians();
|
|
301
|
+
if (error > (kMaxError - T_ERR) * x_len) {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
*result = (1 / x_len) * x;
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Returns whether (a0,a1) is less than (b0,b1) with respect to a total
|
|
309
|
+
// ordering on edges that is invariant under edge reversals.
|
|
310
|
+
template <class T>
|
|
311
|
+
static bool CompareEdges(const Vector3<T>& a0, const Vector3<T>& a1,
|
|
312
|
+
const Vector3<T>& b0, const Vector3<T>& b1) {
|
|
313
|
+
const Vector3<T> *pa0 = &a0, *pa1 = &a1;
|
|
314
|
+
const Vector3<T> *pb0 = &b0, *pb1 = &b1;
|
|
315
|
+
if (*pa0 >= *pa1) std::swap(pa0, pa1);
|
|
316
|
+
if (*pb0 >= *pb1) std::swap(pb0, pb1);
|
|
317
|
+
return *pa0 < *pb0 || (*pa0 == *pb0 && *pb0 < *pb1);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// If the intersection point of the edges (a0,a1) and (b0,b1) can be computed
|
|
321
|
+
// to within an error of at most kIntersectionError by this function, then set
|
|
322
|
+
// "result" to the intersection point and return true.
|
|
323
|
+
//
|
|
324
|
+
// The intersection point is not guaranteed to have the correct sign
|
|
325
|
+
// (i.e., it may be either "result" or "-result").
|
|
326
|
+
template <class T>
|
|
327
|
+
static bool GetIntersectionStable(const Vector3<T>& a0, const Vector3<T>& a1,
|
|
328
|
+
const Vector3<T>& b0, const Vector3<T>& b1,
|
|
329
|
+
Vector3<T>* result) {
|
|
330
|
+
// Sort the two edges so that (a0,a1) is longer, breaking ties in a
|
|
331
|
+
// deterministic way that does not depend on the ordering of the endpoints.
|
|
332
|
+
// This is desirable for two reasons:
|
|
333
|
+
// - So that the result doesn't change when edges are swapped or reversed.
|
|
334
|
+
// - It reduces error, since the first edge is used to compute the edge
|
|
335
|
+
// normal (where a longer edge means less error), and the second edge
|
|
336
|
+
// is used for interpolation (where a shorter edge means less error).
|
|
337
|
+
T a_len2 = (a1 - a0).Norm2();
|
|
338
|
+
T b_len2 = (b1 - b0).Norm2();
|
|
339
|
+
if (a_len2 < b_len2 || (a_len2 == b_len2 && CompareEdges(a0, a1, b0, b1))) {
|
|
340
|
+
return GetIntersectionStableSorted(b0, b1, a0, a1, result);
|
|
341
|
+
} else {
|
|
342
|
+
return GetIntersectionStableSorted(a0, a1, b0, b1, result);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
static bool GetIntersectionStableLD(const S2Point& a0, const S2Point& a1,
|
|
347
|
+
const S2Point& b0, const S2Point& b1,
|
|
348
|
+
S2Point* result) {
|
|
349
|
+
Vector3_ld result_ld;
|
|
350
|
+
if (GetIntersectionStable(Vector3_ld::Cast(a0), Vector3_ld::Cast(a1),
|
|
351
|
+
Vector3_ld::Cast(b0), Vector3_ld::Cast(b1),
|
|
352
|
+
&result_ld)) {
|
|
353
|
+
*result = S2Point::Cast(result_ld);
|
|
354
|
+
return true;
|
|
355
|
+
}
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
static S2Point S2PointFromExact(const Vector3_xf& xf) {
|
|
360
|
+
// If all components of "x" have absolute value less than about 1e-154,
|
|
361
|
+
// then x.Norm2() is zero in double precision due to underflow. Therefore
|
|
362
|
+
// we need to scale "x" by an appropriate power of 2 before the conversion.
|
|
363
|
+
S2Point x(xf[0].ToDouble(), xf[1].ToDouble(), xf[2].ToDouble());
|
|
364
|
+
if (x.Norm2() > 0) return x.Normalize();
|
|
365
|
+
|
|
366
|
+
// Scale so that the largest component magnitude is in the range [0.5, 1).
|
|
367
|
+
int exp = ExactFloat::kMinExp - 1;
|
|
368
|
+
for (int i = 0; i < 3; ++i) {
|
|
369
|
+
if (xf[i].is_normal()) exp = std::max(exp, xf[i].exp());
|
|
370
|
+
}
|
|
371
|
+
if (exp < ExactFloat::kMinExp) {
|
|
372
|
+
return S2Point(0, 0, 0);
|
|
373
|
+
}
|
|
374
|
+
return S2Point(ldexp(xf[0], -exp).ToDouble(),
|
|
375
|
+
ldexp(xf[1], -exp).ToDouble(),
|
|
376
|
+
ldexp(xf[2], -exp).ToDouble()).Normalize();
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
namespace internal {
|
|
380
|
+
|
|
381
|
+
// Compute the intersection point of (a0, a1) and (b0, b1) using exact
|
|
382
|
+
// arithmetic. Note that the result is not exact because it is rounded to
|
|
383
|
+
// double precision. Also, the intersection point is not guaranteed to have
|
|
384
|
+
// the correct sign (i.e., the return value may need to be negated).
|
|
385
|
+
S2Point GetIntersectionExact(const S2Point& a0, const S2Point& a1,
|
|
386
|
+
const S2Point& b0, const S2Point& b1) {
|
|
387
|
+
// Since we are using exact arithmetic, we don't need to worry about
|
|
388
|
+
// numerical stability.
|
|
389
|
+
Vector3_xf a0_xf = Vector3_xf::Cast(a0);
|
|
390
|
+
Vector3_xf a1_xf = Vector3_xf::Cast(a1);
|
|
391
|
+
Vector3_xf b0_xf = Vector3_xf::Cast(b0);
|
|
392
|
+
Vector3_xf b1_xf = Vector3_xf::Cast(b1);
|
|
393
|
+
Vector3_xf a_norm_xf = a0_xf.CrossProd(a1_xf);
|
|
394
|
+
Vector3_xf b_norm_xf = b0_xf.CrossProd(b1_xf);
|
|
395
|
+
Vector3_xf x_xf = a_norm_xf.CrossProd(b_norm_xf);
|
|
396
|
+
|
|
397
|
+
// The final Normalize() call is done in double precision, which creates a
|
|
398
|
+
// directional error of up to 2 * DBL_ERR. (ToDouble() and Normalize() each
|
|
399
|
+
// contribute up to DBL_ERR of directional error.)
|
|
400
|
+
S2Point x = S2PointFromExact(x_xf);
|
|
401
|
+
|
|
402
|
+
if (x == S2Point(0, 0, 0)) {
|
|
403
|
+
// The two edges are exactly collinear, but we still consider them to be
|
|
404
|
+
// "crossing" because of simulation of simplicity. Out of the four
|
|
405
|
+
// endpoints, exactly two lie in the interior of the other edge. Of
|
|
406
|
+
// those two we return the one that is lexicographically smallest.
|
|
407
|
+
x = S2Point(10, 10, 10); // Greater than any valid S2Point
|
|
408
|
+
S2Point a_norm = S2PointFromExact(a_norm_xf);
|
|
409
|
+
S2Point b_norm = S2PointFromExact(b_norm_xf);
|
|
410
|
+
if (a_norm == S2Point(0, 0, 0) || b_norm == S2Point(0, 0, 0)) {
|
|
411
|
+
// TODO(ericv): To support antipodal edges properly, we would need to
|
|
412
|
+
// add an s2pred::CrossProd() function that computes the cross product
|
|
413
|
+
// using simulation of simplicity and rounds the result to the nearest
|
|
414
|
+
// floating-point representation.
|
|
415
|
+
S2_LOG(DFATAL) << "Exactly antipodal edges not supported by GetIntersection";
|
|
416
|
+
}
|
|
417
|
+
if (s2pred::OrderedCCW(b0, a0, b1, b_norm) && a0 < x) x = a0;
|
|
418
|
+
if (s2pred::OrderedCCW(b0, a1, b1, b_norm) && a1 < x) x = a1;
|
|
419
|
+
if (s2pred::OrderedCCW(a0, b0, a1, a_norm) && b0 < x) x = b0;
|
|
420
|
+
if (s2pred::OrderedCCW(a0, b1, a1, a_norm) && b1 < x) x = b1;
|
|
421
|
+
}
|
|
422
|
+
S2_DCHECK(S2::IsUnitLength(x));
|
|
423
|
+
return x;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
} // namespace internal
|
|
427
|
+
|
|
428
|
+
// Given three points "a", "x", "b", returns true if these three points occur
|
|
429
|
+
// in the given order along the edge (a,b) to within the given tolerance.
|
|
430
|
+
// More precisely, either "x" must be within "tolerance" of "a" or "b", or
|
|
431
|
+
// when "x" is projected onto the great circle through "a" and "b" it must lie
|
|
432
|
+
// along the edge (a,b) (i.e., the shortest path from "a" to "b").
|
|
433
|
+
static bool ApproximatelyOrdered(const S2Point& a, const S2Point& x,
|
|
434
|
+
const S2Point& b, double tolerance) {
|
|
435
|
+
if ((x - a).Norm2() <= tolerance * tolerance) return true;
|
|
436
|
+
if ((x - b).Norm2() <= tolerance * tolerance) return true;
|
|
437
|
+
return s2pred::OrderedCCW(a, x, b, S2::RobustCrossProd(a, b).Normalize());
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
S2Point GetIntersection(const S2Point& a0, const S2Point& a1,
|
|
441
|
+
const S2Point& b0, const S2Point& b1) {
|
|
442
|
+
S2_DCHECK_GT(CrossingSign(a0, a1, b0, b1), 0);
|
|
443
|
+
|
|
444
|
+
// It is difficult to compute the intersection point of two edges accurately
|
|
445
|
+
// when the angle between the edges is very small. Previously we handled
|
|
446
|
+
// this by only guaranteeing that the returned intersection point is within
|
|
447
|
+
// kIntersectionError of each edge. However, this means that when the edges
|
|
448
|
+
// cross at a very small angle, the computed result may be very far from the
|
|
449
|
+
// true intersection point.
|
|
450
|
+
//
|
|
451
|
+
// Instead this function now guarantees that the result is always within
|
|
452
|
+
// kIntersectionError of the true intersection. This requires using more
|
|
453
|
+
// sophisticated techniques and in some cases extended precision.
|
|
454
|
+
//
|
|
455
|
+
// Three different techniques are implemented, but only two are used:
|
|
456
|
+
//
|
|
457
|
+
// - GetIntersectionSimple() computes the intersection point using
|
|
458
|
+
// numerically stable cross products in "long double" precision.
|
|
459
|
+
//
|
|
460
|
+
// - GetIntersectionStable() computes the intersection point using
|
|
461
|
+
// projection and interpolation, taking care to minimize cancellation
|
|
462
|
+
// error. This method exists in "double" and "long double" versions.
|
|
463
|
+
//
|
|
464
|
+
// - GetIntersectionExact() computes the intersection point using exact
|
|
465
|
+
// arithmetic and converts the final result back to an S2Point.
|
|
466
|
+
//
|
|
467
|
+
// We don't actually use the first method (GetIntersectionSimple) because it
|
|
468
|
+
// turns out that GetIntersectionStable() is twice as fast and also much
|
|
469
|
+
// more accurate (even in double precision). The "long double" version
|
|
470
|
+
// (only available on Intel platforms) uses 80-bit precision and is about
|
|
471
|
+
// twice as slow. The exact arithmetic version is about 100x slower.
|
|
472
|
+
//
|
|
473
|
+
// So our strategy is to first call GetIntersectionStable() in double
|
|
474
|
+
// precision; if that doesn't work and this platform supports "long double",
|
|
475
|
+
// then we try again in "long double"; if that doesn't work then we fall
|
|
476
|
+
// back to exact arithmetic.
|
|
477
|
+
|
|
478
|
+
static const bool kUseSimpleMethod = false;
|
|
479
|
+
static const bool kHasLongDouble = (s2pred::rounding_epsilon<long double>() <
|
|
480
|
+
s2pred::rounding_epsilon<double>());
|
|
481
|
+
S2Point result;
|
|
482
|
+
IntersectionMethod method;
|
|
483
|
+
if (kUseSimpleMethod && GetIntersectionSimple(a0, a1, b0, b1, &result)) {
|
|
484
|
+
method = IntersectionMethod::SIMPLE;
|
|
485
|
+
} else if (kUseSimpleMethod && kHasLongDouble &&
|
|
486
|
+
GetIntersectionSimpleLD(a0, a1, b0, b1, &result)) {
|
|
487
|
+
method = IntersectionMethod::SIMPLE_LD;
|
|
488
|
+
} else if (GetIntersectionStable(a0, a1, b0, b1, &result)) {
|
|
489
|
+
method = IntersectionMethod::STABLE;
|
|
490
|
+
} else if (kHasLongDouble &&
|
|
491
|
+
GetIntersectionStableLD(a0, a1, b0, b1, &result)) {
|
|
492
|
+
method = IntersectionMethod::STABLE_LD;
|
|
493
|
+
} else {
|
|
494
|
+
result = GetIntersectionExact(a0, a1, b0, b1);
|
|
495
|
+
method = IntersectionMethod::EXACT;
|
|
496
|
+
}
|
|
497
|
+
if (intersection_method_tally_) {
|
|
498
|
+
++intersection_method_tally_[static_cast<int>(method)];
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Make sure the intersection point is on the correct side of the sphere.
|
|
502
|
+
// Since all vertices are unit length, and edges are less than 180 degrees,
|
|
503
|
+
// (a0 + a1) and (b0 + b1) both have positive dot product with the
|
|
504
|
+
// intersection point. We use the sum of all vertices to make sure that the
|
|
505
|
+
// result is unchanged when the edges are swapped or reversed.
|
|
506
|
+
if (result.DotProd((a0 + a1) + (b0 + b1)) < 0) result = -result;
|
|
507
|
+
|
|
508
|
+
// Make sure that the intersection point lies on both edges.
|
|
509
|
+
S2_DCHECK(ApproximatelyOrdered(a0, result, a1, kIntersectionError.radians()));
|
|
510
|
+
S2_DCHECK(ApproximatelyOrdered(b0, result, b1, kIntersectionError.radians()));
|
|
511
|
+
|
|
512
|
+
return result;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
} // namespace S2
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Copyright 2005 Google Inc. All Rights Reserved.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS-IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
// Author: ericv@google.com (Eric Veach)
|
|
17
|
+
//
|
|
18
|
+
// Defines functions related to determining whether two geodesic edges cross
|
|
19
|
+
// and for computing intersection points.
|
|
20
|
+
//
|
|
21
|
+
// The predicates CrossingSign(), VertexCrossing(), and EdgeOrVertexCrossing()
|
|
22
|
+
// are robust, meaning that they produce correct, consistent results even in
|
|
23
|
+
// pathological cases. See s2predicates.h for additional robust predicates.
|
|
24
|
+
//
|
|
25
|
+
// See also S2EdgeCrosser (which efficiently tests an edge against a sequence
|
|
26
|
+
// of other edges) and S2CrossingEdgeQuery (which uses an index to speed up
|
|
27
|
+
// the process).
|
|
28
|
+
|
|
29
|
+
#ifndef S2_S2EDGE_CROSSINGS_H_
|
|
30
|
+
#define S2_S2EDGE_CROSSINGS_H_
|
|
31
|
+
|
|
32
|
+
#include <cmath>
|
|
33
|
+
|
|
34
|
+
#include "s2/base/logging.h"
|
|
35
|
+
#include "s2/third_party/absl/base/macros.h"
|
|
36
|
+
#include "s2/third_party/absl/container/inlined_vector.h"
|
|
37
|
+
#include "s2/_fp_contract_off.h"
|
|
38
|
+
#include "s2/r2.h"
|
|
39
|
+
#include "s2/r2rect.h"
|
|
40
|
+
#include "s2/s1angle.h"
|
|
41
|
+
#include "s2/s1chord_angle.h"
|
|
42
|
+
#include "s2/s1interval.h"
|
|
43
|
+
#include "s2/s2latlng.h"
|
|
44
|
+
#include "s2/s2latlng_rect.h"
|
|
45
|
+
#include "s2/s2pointutil.h"
|
|
46
|
+
#include "s2/s2predicates.h"
|
|
47
|
+
#include "s2/util/math/vector.h"
|
|
48
|
+
|
|
49
|
+
namespace S2 {
|
|
50
|
+
|
|
51
|
+
// This function determines whether the edge AB intersects the edge CD.
|
|
52
|
+
// Returns +1 if AB crosses CD at a point that is interior to both edges.
|
|
53
|
+
// Returns 0 if any two vertices from different edges are the same.
|
|
54
|
+
// Returns -1 otherwise.
|
|
55
|
+
//
|
|
56
|
+
// Note that if an edge is degenerate (A == B or C == D), the return value
|
|
57
|
+
// is 0 if two vertices from different edges are the same and -1 otherwise.
|
|
58
|
+
//
|
|
59
|
+
// Properties of CrossingSign:
|
|
60
|
+
//
|
|
61
|
+
// (1) CrossingSign(b,a,c,d) == CrossingSign(a,b,c,d)
|
|
62
|
+
// (2) CrossingSign(c,d,a,b) == CrossingSign(a,b,c,d)
|
|
63
|
+
// (3) CrossingSign(a,b,c,d) == 0 if a==c, a==d, b==c, b==d
|
|
64
|
+
// (3) CrossingSign(a,b,c,d) <= 0 if a==b or c==d (see above)
|
|
65
|
+
//
|
|
66
|
+
// This function implements an exact, consistent perturbation model such
|
|
67
|
+
// that no three points are ever considered to be collinear. This means
|
|
68
|
+
// that even if you have 4 points A, B, C, D that lie exactly in a line
|
|
69
|
+
// (say, around the equator), C and D will be treated as being slightly to
|
|
70
|
+
// one side or the other of AB. This is done in a way such that the
|
|
71
|
+
// results are always consistent (see s2pred::Sign).
|
|
72
|
+
//
|
|
73
|
+
// Note that if you want to check an edge against a collection of other edges,
|
|
74
|
+
// it is much more efficient to use an S2EdgeCrosser (see s2edge_crosser.h).
|
|
75
|
+
int CrossingSign(const S2Point& a, const S2Point& b,
|
|
76
|
+
const S2Point& c, const S2Point& d);
|
|
77
|
+
|
|
78
|
+
// Given two edges AB and CD where at least two vertices are identical
|
|
79
|
+
// (i.e. CrossingSign(a,b,c,d) == 0), this function defines whether the
|
|
80
|
+
// two edges "cross" in a such a way that point-in-polygon containment tests
|
|
81
|
+
// can be implemented by counting the number of edge crossings. The basic
|
|
82
|
+
// rule is that a "crossing" occurs if AB is encountered after CD during a
|
|
83
|
+
// CCW sweep around the shared vertex starting from a fixed reference point.
|
|
84
|
+
//
|
|
85
|
+
// Note that according to this rule, if AB crosses CD then in general CD
|
|
86
|
+
// does not cross AB. However, this leads to the correct result when
|
|
87
|
+
// counting polygon edge crossings. For example, suppose that A,B,C are
|
|
88
|
+
// three consecutive vertices of a CCW polygon. If we now consider the edge
|
|
89
|
+
// crossings of a segment BP as P sweeps around B, the crossing number
|
|
90
|
+
// changes parity exactly when BP crosses BA or BC.
|
|
91
|
+
//
|
|
92
|
+
// Useful properties of VertexCrossing (VC):
|
|
93
|
+
//
|
|
94
|
+
// (1) VC(a,a,c,d) == VC(a,b,c,c) == false
|
|
95
|
+
// (2) VC(a,b,a,b) == VC(a,b,b,a) == true
|
|
96
|
+
// (3) VC(a,b,c,d) == VC(a,b,d,c) == VC(b,a,c,d) == VC(b,a,d,c)
|
|
97
|
+
// (3) If exactly one of a,b equals one of c,d, then exactly one of
|
|
98
|
+
// VC(a,b,c,d) and VC(c,d,a,b) is true
|
|
99
|
+
//
|
|
100
|
+
// It is an error to call this method with 4 distinct vertices.
|
|
101
|
+
bool VertexCrossing(const S2Point& a, const S2Point& b,
|
|
102
|
+
const S2Point& c, const S2Point& d);
|
|
103
|
+
|
|
104
|
+
// A convenience function that calls CrossingSign() to handle cases
|
|
105
|
+
// where all four vertices are distinct, and VertexCrossing() to handle
|
|
106
|
+
// cases where two or more vertices are the same. This defines a crossing
|
|
107
|
+
// function such that point-in-polygon containment tests can be implemented
|
|
108
|
+
// by simply counting edge crossings.
|
|
109
|
+
bool EdgeOrVertexCrossing(const S2Point& a, const S2Point& b,
|
|
110
|
+
const S2Point& c, const S2Point& d);
|
|
111
|
+
|
|
112
|
+
// Given two edges AB and CD such that CrossingSign(A, B, C, D) > 0, returns
|
|
113
|
+
// their intersection point. Useful properties of GetIntersection (GI):
|
|
114
|
+
//
|
|
115
|
+
// (1) GI(b,a,c,d) == GI(a,b,d,c) == GI(a,b,c,d)
|
|
116
|
+
// (2) GI(c,d,a,b) == GI(a,b,c,d)
|
|
117
|
+
//
|
|
118
|
+
// The returned intersection point X is guaranteed to be very close to the
|
|
119
|
+
// true intersection point of AB and CD, even if the edges intersect at a
|
|
120
|
+
// very small angle. See "kIntersectionError" below for details.
|
|
121
|
+
S2Point GetIntersection(const S2Point& a, const S2Point& b,
|
|
122
|
+
const S2Point& c, const S2Point& d);
|
|
123
|
+
|
|
124
|
+
// kIntersectionError is an upper bound on the distance from the intersection
|
|
125
|
+
// point returned by GetIntersection() to the true intersection point.
|
|
126
|
+
extern const S1Angle kIntersectionError;
|
|
127
|
+
|
|
128
|
+
// This value can be used as the S2Builder snap_radius() to ensure that edges
|
|
129
|
+
// that have been displaced by up to kIntersectionError are merged back
|
|
130
|
+
// together again. For example this can happen when geometry is intersected
|
|
131
|
+
// with a set of tiles and then unioned. It is equal to twice the
|
|
132
|
+
// intersection error because input edges might have been displaced in
|
|
133
|
+
// opposite directions.
|
|
134
|
+
extern const S1Angle kIntersectionMergeRadius; // 2 * kIntersectionError
|
|
135
|
+
|
|
136
|
+
} // namespace S2
|
|
137
|
+
|
|
138
|
+
#endif // S2_S2EDGE_CROSSINGS_H_
|