@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,146 @@
|
|
|
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/s2earth.h"
|
|
19
|
+
|
|
20
|
+
#include <cmath>
|
|
21
|
+
|
|
22
|
+
#include <gtest/gtest.h>
|
|
23
|
+
#include "s2/util/units/physical-units.h"
|
|
24
|
+
|
|
25
|
+
TEST(S2EarthTest, TestAngleConversion) {
|
|
26
|
+
ASSERT_DOUBLE_EQ(S2Earth::ToAngle(S2Earth::Radius()).radians(), 1);
|
|
27
|
+
ASSERT_DOUBLE_EQ(S2Earth::ToChordAngle(S2Earth::Radius()).radians(), 1);
|
|
28
|
+
ASSERT_FLOAT_EQ(
|
|
29
|
+
util::units::Meters(S2Earth::ToDistance(S1Angle::Radians(2))).value(),
|
|
30
|
+
2 * S2Earth::RadiusMeters());
|
|
31
|
+
ASSERT_FLOAT_EQ(
|
|
32
|
+
util::units::Meters(S2Earth::ToDistance(S1ChordAngle::Radians(2)))
|
|
33
|
+
.value(),
|
|
34
|
+
2 * S2Earth::RadiusMeters());
|
|
35
|
+
ASSERT_DOUBLE_EQ(
|
|
36
|
+
S2Earth::ToRadians(util::units::Meters(S2Earth::RadiusMeters())), 1);
|
|
37
|
+
ASSERT_DOUBLE_EQ(S2Earth::ToMeters(S1Angle::Degrees(180)),
|
|
38
|
+
S2Earth::RadiusMeters() * M_PI);
|
|
39
|
+
ASSERT_DOUBLE_EQ(S2Earth::ToMeters(S1ChordAngle::Degrees(180)),
|
|
40
|
+
S2Earth::RadiusMeters() * M_PI);
|
|
41
|
+
ASSERT_DOUBLE_EQ(S2Earth::ToKm(S1Angle::Radians(0.5)),
|
|
42
|
+
0.5 * S2Earth::RadiusKm());
|
|
43
|
+
ASSERT_DOUBLE_EQ(S2Earth::ToKm(S1ChordAngle::Radians(0.5)),
|
|
44
|
+
0.5 * S2Earth::RadiusKm());
|
|
45
|
+
ASSERT_DOUBLE_EQ(S2Earth::KmToRadians(S2Earth::RadiusMeters() / 1000), 1);
|
|
46
|
+
ASSERT_DOUBLE_EQ(S2Earth::RadiansToKm(0.5), 0.5 * S2Earth::RadiusKm());
|
|
47
|
+
ASSERT_DOUBLE_EQ(S2Earth::MetersToRadians(S2Earth::RadiansToKm(0.3) * 1000),
|
|
48
|
+
0.3);
|
|
49
|
+
ASSERT_DOUBLE_EQ(S2Earth::RadiansToMeters(S2Earth::KmToRadians(2.5)), 2500);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
TEST(S2EarthTest, TestSolidAngleConversion) {
|
|
53
|
+
ASSERT_DOUBLE_EQ(1,
|
|
54
|
+
S2Earth::SquareKmToSteradians(
|
|
55
|
+
std::pow(S2Earth::RadiusMeters() / 1000, 2)));
|
|
56
|
+
ASSERT_DOUBLE_EQ(std::pow(0.5 * S2Earth::RadiusKm(), 2),
|
|
57
|
+
S2Earth::SteradiansToSquareKm(std::pow(0.5, 2)));
|
|
58
|
+
ASSERT_DOUBLE_EQ(std::pow(0.3, 2),
|
|
59
|
+
S2Earth::SquareMetersToSteradians(
|
|
60
|
+
std::pow(S2Earth::RadiansToKm(0.3) * 1000, 2)));
|
|
61
|
+
ASSERT_DOUBLE_EQ(std::pow(2500, 2),
|
|
62
|
+
S2Earth::SteradiansToSquareMeters(
|
|
63
|
+
std::pow(S2Earth::KmToRadians(2.5), 2)));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
TEST(S2EarthTest, TestToLongitudeRadians) {
|
|
67
|
+
const util::units::Meters earth_radius =
|
|
68
|
+
util::units::Meters(S2Earth::RadiusMeters());
|
|
69
|
+
|
|
70
|
+
// At the equator, ToLongitudeRadians behaves exactly like ToRadians.
|
|
71
|
+
ASSERT_DOUBLE_EQ(S2Earth::ToLongitudeRadians(earth_radius, 0), 1);
|
|
72
|
+
|
|
73
|
+
// The closer we get to the poles, the more radians we need to go the same
|
|
74
|
+
// distance.
|
|
75
|
+
ASSERT_GT(S2Earth::ToLongitudeRadians(earth_radius, 0.5),
|
|
76
|
+
S2Earth::ToLongitudeRadians(earth_radius, 0.4));
|
|
77
|
+
|
|
78
|
+
// At the poles, we should return 2PI radians instead of dividing by 0.
|
|
79
|
+
ASSERT_DOUBLE_EQ(S2Earth::ToLongitudeRadians(earth_radius, M_PI_2), M_PI * 2);
|
|
80
|
+
|
|
81
|
+
// Within epsilon of the poles, we should still return 2PI radians instead
|
|
82
|
+
// of directing the caller to take thousands of radians around.
|
|
83
|
+
ASSERT_DOUBLE_EQ(S2Earth::ToLongitudeRadians(earth_radius, M_PI_2 - 1e-4),
|
|
84
|
+
M_PI * 2);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
TEST(S2EarthTest, TestGetInitialBearing) {
|
|
88
|
+
struct TestConfig {
|
|
89
|
+
string description;
|
|
90
|
+
S2LatLng a;
|
|
91
|
+
S2LatLng b;
|
|
92
|
+
S1Angle bearing;
|
|
93
|
+
} test_configs[] = {
|
|
94
|
+
{"Westward on equator", S2LatLng::FromDegrees(0, 50),
|
|
95
|
+
S2LatLng::FromDegrees(0, 100), S1Angle::Degrees(90)},
|
|
96
|
+
{"Eastward on equator", S2LatLng::FromDegrees(0, 50),
|
|
97
|
+
S2LatLng::FromDegrees(0, 0), S1Angle::Degrees(-90)},
|
|
98
|
+
{"Northward on meridian", S2LatLng::FromDegrees(16, 28),
|
|
99
|
+
S2LatLng::FromDegrees(81, 28), S1Angle::Degrees(0)},
|
|
100
|
+
{"Southward on meridian", S2LatLng::FromDegrees(24, 64),
|
|
101
|
+
S2LatLng::FromDegrees(-27, 64), S1Angle::Degrees(180)},
|
|
102
|
+
{"Towards north pole", S2LatLng::FromDegrees(12, 76),
|
|
103
|
+
S2LatLng::FromDegrees(90, 50), S1Angle::Degrees(0)},
|
|
104
|
+
{"Towards south pole", S2LatLng::FromDegrees(-35, 105),
|
|
105
|
+
S2LatLng::FromDegrees(-90, -120), S1Angle::Degrees(180)},
|
|
106
|
+
{"Spain to Japan", S2LatLng::FromDegrees(40.4379332, -3.749576),
|
|
107
|
+
S2LatLng::FromDegrees(35.6733227, 139.6403486), S1Angle::Degrees(29.2)},
|
|
108
|
+
{"Japan to Spain", S2LatLng::FromDegrees(35.6733227, 139.6403486),
|
|
109
|
+
S2LatLng::FromDegrees(40.4379332, -3.749576), S1Angle::Degrees(-27.2)},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
for (const TestConfig& config : test_configs) {
|
|
113
|
+
const S1Angle bearing = S2Earth::GetInitialBearing(config.a, config.b);
|
|
114
|
+
const S1Angle angle_diff = (bearing - config.bearing).Normalized().abs();
|
|
115
|
+
EXPECT_LE(angle_diff.degrees(), 1e-2)
|
|
116
|
+
<< "GetInitialBearing() test failed on: " << config.description
|
|
117
|
+
<< ". Expected " << config.bearing << ", got " << bearing;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
TEST(S2EarthTest, TestGetDistance) {
|
|
122
|
+
S2Point north(0, 0, 1);
|
|
123
|
+
S2Point south(0, 0, -1);
|
|
124
|
+
S2Point west(0, -1, 0);
|
|
125
|
+
|
|
126
|
+
ASSERT_FLOAT_EQ(
|
|
127
|
+
util::units::Miles(S2Earth::GetDistance(north, south)).value(),
|
|
128
|
+
util::units::Miles(M_PI * S2Earth::Radius()).value());
|
|
129
|
+
ASSERT_DOUBLE_EQ(S2Earth::GetDistanceKm(west, west), 0);
|
|
130
|
+
ASSERT_DOUBLE_EQ(S2Earth::GetDistanceMeters(north, west),
|
|
131
|
+
M_PI_2 * S2Earth::RadiusMeters());
|
|
132
|
+
|
|
133
|
+
ASSERT_FLOAT_EQ(
|
|
134
|
+
util::units::Feet(S2Earth::GetDistance(S2LatLng::FromDegrees(0, -90),
|
|
135
|
+
S2LatLng::FromDegrees(-90, -38)))
|
|
136
|
+
.value(),
|
|
137
|
+
util::units::Feet(S2Earth::GetDistance(west, south)).value());
|
|
138
|
+
|
|
139
|
+
ASSERT_DOUBLE_EQ(S2Earth::GetDistanceKm(S2LatLng::FromRadians(0, 0.6),
|
|
140
|
+
S2LatLng::FromRadians(0, -0.4)),
|
|
141
|
+
S2Earth::RadiusKm());
|
|
142
|
+
|
|
143
|
+
ASSERT_DOUBLE_EQ(S2Earth::GetDistanceMeters(S2LatLng::FromDegrees(80, 27),
|
|
144
|
+
S2LatLng::FromDegrees(55, -153)),
|
|
145
|
+
1000 * S2Earth::RadiusKm() * M_PI / 4);
|
|
146
|
+
}
|
|
@@ -0,0 +1,462 @@
|
|
|
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_clipping.h"
|
|
19
|
+
|
|
20
|
+
#include <cfloat>
|
|
21
|
+
#include <cmath>
|
|
22
|
+
|
|
23
|
+
#include "s2/base/logging.h"
|
|
24
|
+
#include "s2/r1interval.h"
|
|
25
|
+
#include "s2/s2coords.h"
|
|
26
|
+
#include "s2/s2pointutil.h"
|
|
27
|
+
#include "s2/util/math/vector.h"
|
|
28
|
+
|
|
29
|
+
namespace S2 {
|
|
30
|
+
|
|
31
|
+
using std::fabs;
|
|
32
|
+
using std::max;
|
|
33
|
+
using std::min;
|
|
34
|
+
|
|
35
|
+
// Error constant definitions. See the header file for details.
|
|
36
|
+
const double kFaceClipErrorRadians = 3 * DBL_EPSILON;
|
|
37
|
+
const double kFaceClipErrorUVDist = 9 * DBL_EPSILON;
|
|
38
|
+
const double kFaceClipErrorUVCoord = 9 * M_SQRT1_2 * DBL_EPSILON;
|
|
39
|
+
const double kIntersectsRectErrorUVDist = 3 * M_SQRT2 * DBL_EPSILON;
|
|
40
|
+
const double kEdgeClipErrorUVCoord = 2.25 * DBL_EPSILON;
|
|
41
|
+
const double kEdgeClipErrorUVDist = 2.25 * DBL_EPSILON;
|
|
42
|
+
|
|
43
|
+
// S2PointUVW is used to document that a given S2Point is expressed in the
|
|
44
|
+
// (u,v,w) coordinates of some cube face.
|
|
45
|
+
using S2PointUVW = S2Point;
|
|
46
|
+
|
|
47
|
+
// The three functions below all compare a sum (u + v) to a third value w.
|
|
48
|
+
// They are implemented in such a way that they produce an exact result even
|
|
49
|
+
// though all calculations are done with ordinary floating-point operations.
|
|
50
|
+
// Here are the principles on which these functions are based:
|
|
51
|
+
//
|
|
52
|
+
// A. If u + v < w in floating-point, then u + v < w in exact arithmetic.
|
|
53
|
+
//
|
|
54
|
+
// B. If u + v < w in exact arithmetic, then at least one of the following
|
|
55
|
+
// expressions is true in floating-point:
|
|
56
|
+
// u + v < w
|
|
57
|
+
// u < w - v
|
|
58
|
+
// v < w - u
|
|
59
|
+
//
|
|
60
|
+
// Proof: By rearranging terms and substituting ">" for "<", we can assume
|
|
61
|
+
// that all values are non-negative. Now clearly "w" is not the smallest
|
|
62
|
+
// value, so assume WLOG that "u" is the smallest. We want to show that
|
|
63
|
+
// u < w - v in floating-point. If v >= w/2, the calculation of w - v is
|
|
64
|
+
// exact since the result is smaller in magnitude than either input value,
|
|
65
|
+
// so the result holds. Otherwise we have u <= v < w/2 and w - v >= w/2
|
|
66
|
+
// (even in floating point), so the result also holds.
|
|
67
|
+
|
|
68
|
+
// Return true if u + v == w exactly.
|
|
69
|
+
inline static bool SumEquals(double u, double v, double w) {
|
|
70
|
+
return (u + v == w) && (u == w - v) && (v == w - u);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Return true if a given directed line L intersects the cube face F. The
|
|
74
|
+
// line L is defined by its normal N in the (u,v,w) coordinates of F.
|
|
75
|
+
inline static bool IntersectsFace(const S2PointUVW& n) {
|
|
76
|
+
// L intersects the [-1,1]x[-1,1] square in (u,v) if and only if the dot
|
|
77
|
+
// products of N with the four corner vertices (-1,-1,1), (1,-1,1), (1,1,1),
|
|
78
|
+
// and (-1,1,1) do not all have the same sign. This is true exactly when
|
|
79
|
+
// |Nu| + |Nv| >= |Nw|. The code below evaluates this expression exactly
|
|
80
|
+
// (see comments above).
|
|
81
|
+
double u = fabs(n[0]), v = fabs(n[1]), w = fabs(n[2]);
|
|
82
|
+
// We only need to consider the cases where u or v is the smallest value,
|
|
83
|
+
// since if w is the smallest then both expressions below will have a
|
|
84
|
+
// positive LHS and a negative RHS.
|
|
85
|
+
return (v >= w - u) && (u >= w - v);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Given a directed line L intersecting a cube face F, return true if L
|
|
89
|
+
// intersects two opposite edges of F (including the case where L passes
|
|
90
|
+
// exactly through a corner vertex of F). The line L is defined by its
|
|
91
|
+
// normal N in the (u,v,w) coordinates of F.
|
|
92
|
+
inline static bool IntersectsOppositeEdges(const S2PointUVW& n) {
|
|
93
|
+
// The line L intersects opposite edges of the [-1,1]x[-1,1] (u,v) square if
|
|
94
|
+
// and only exactly two of the corner vertices lie on each side of L. This
|
|
95
|
+
// is true exactly when ||Nu| - |Nv|| >= |Nw|. The code below evaluates this
|
|
96
|
+
// expression exactly (see comments above).
|
|
97
|
+
double u = fabs(n[0]), v = fabs(n[1]), w = fabs(n[2]);
|
|
98
|
+
// If w is the smallest, the following line returns an exact result.
|
|
99
|
+
if (fabs(u - v) != w) return fabs(u - v) >= w;
|
|
100
|
+
// Otherwise u - v = w exactly, or w is not the smallest value. In either
|
|
101
|
+
// case the following line returns the correct result.
|
|
102
|
+
return (u >= v) ? (u - w >= v) : (v - w >= u);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Given cube face F and a directed line L (represented by its CCW normal N in
|
|
106
|
+
// the (u,v,w) coordinates of F), compute the axis of the cube face edge where
|
|
107
|
+
// L exits the face: return 0 if L exits through the u=-1 or u=+1 edge, and 1
|
|
108
|
+
// if L exits through the v=-1 or v=+1 edge. Either result is acceptable if L
|
|
109
|
+
// exits exactly through a corner vertex of the cube face.
|
|
110
|
+
static int GetExitAxis(const S2PointUVW& n) {
|
|
111
|
+
S2_DCHECK(IntersectsFace(n));
|
|
112
|
+
if (IntersectsOppositeEdges(n)) {
|
|
113
|
+
// The line passes through through opposite edges of the face.
|
|
114
|
+
// It exits through the v=+1 or v=-1 edge if the u-component of N has a
|
|
115
|
+
// larger absolute magnitude than the v-component.
|
|
116
|
+
return (fabs(n[0]) >= fabs(n[1])) ? 1 : 0;
|
|
117
|
+
} else {
|
|
118
|
+
// The line passes through through two adjacent edges of the face.
|
|
119
|
+
// It exits the v=+1 or v=-1 edge if an even number of the components of N
|
|
120
|
+
// are negative. We test this using signbit() rather than multiplication
|
|
121
|
+
// to avoid the possibility of underflow.
|
|
122
|
+
S2_DCHECK(n[0] != 0 && n[1] != 0 && n[2] != 0);
|
|
123
|
+
using std::signbit;
|
|
124
|
+
return ((signbit(n[0]) ^ signbit(n[1]) ^ signbit(n[2])) == 0) ? 1 : 0;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Given a cube face F, a directed line L (represented by its CCW normal N in
|
|
129
|
+
// the (u,v,w) coordinates of F), and result of GetExitAxis(N), return the
|
|
130
|
+
// (u,v) coordinates of the point where L exits the cube face.
|
|
131
|
+
static R2Point GetExitPoint(const S2PointUVW& n, int axis) {
|
|
132
|
+
if (axis == 0) {
|
|
133
|
+
double u = (n[1] > 0) ? 1.0 : -1.0;
|
|
134
|
+
return R2Point(u, (-u * n[0] - n[2]) / n[1]);
|
|
135
|
+
} else {
|
|
136
|
+
double v = (n[0] < 0) ? 1.0 : -1.0;
|
|
137
|
+
return R2Point((-v * n[1] - n[2]) / n[0], v);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Given a line segment AB whose origin A has been projected onto a given cube
|
|
142
|
+
// face, determine whether it is necessary to project A onto a different face
|
|
143
|
+
// instead. This can happen because the normal of the line AB is not computed
|
|
144
|
+
// exactly, so that the line AB (defined as the set of points perpendicular to
|
|
145
|
+
// the normal) may not intersect the cube face containing A. Even if it does
|
|
146
|
+
// intersect the face, the "exit point" of the line from that face may be on
|
|
147
|
+
// the wrong side of A (i.e., in the direction away from B). If this happens,
|
|
148
|
+
// we reproject A onto the adjacent face where the line AB approaches A most
|
|
149
|
+
// closely. This moves the origin by a small amount, but never more than the
|
|
150
|
+
// error tolerances documented in the header file.
|
|
151
|
+
static int MoveOriginToValidFace(int face, const S2Point& a,
|
|
152
|
+
const S2Point& ab, R2Point* a_uv) {
|
|
153
|
+
// Fast path: if the origin is sufficiently far inside the face, it is
|
|
154
|
+
// always safe to use it.
|
|
155
|
+
const double kMaxSafeUVCoord = 1 - kFaceClipErrorUVCoord;
|
|
156
|
+
if (max(fabs((*a_uv)[0]), fabs((*a_uv)[1])) <= kMaxSafeUVCoord) {
|
|
157
|
+
return face;
|
|
158
|
+
}
|
|
159
|
+
// Otherwise check whether the normal AB even intersects this face.
|
|
160
|
+
S2PointUVW n = S2::FaceXYZtoUVW(face, ab);
|
|
161
|
+
if (IntersectsFace(n)) {
|
|
162
|
+
// Check whether the point where the line AB exits this face is on the
|
|
163
|
+
// wrong side of A (by more than the acceptable error tolerance).
|
|
164
|
+
S2Point exit = S2::FaceUVtoXYZ(face, GetExitPoint(n, GetExitAxis(n)));
|
|
165
|
+
S2Point a_tangent = ab.Normalize().CrossProd(a);
|
|
166
|
+
if ((exit - a).DotProd(a_tangent) >= -kFaceClipErrorRadians) {
|
|
167
|
+
return face; // We can use the given face.
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Otherwise we reproject A to the nearest adjacent face. (If line AB does
|
|
171
|
+
// not pass through a given face, it must pass through all adjacent faces.)
|
|
172
|
+
if (fabs((*a_uv)[0]) >= fabs((*a_uv)[1])) {
|
|
173
|
+
face = S2::GetUVWFace(face, 0 /*U axis*/, (*a_uv)[0] > 0);
|
|
174
|
+
} else {
|
|
175
|
+
face = S2::GetUVWFace(face, 1 /*V axis*/, (*a_uv)[1] > 0);
|
|
176
|
+
}
|
|
177
|
+
S2_DCHECK(IntersectsFace(S2::FaceXYZtoUVW(face, ab)));
|
|
178
|
+
S2::ValidFaceXYZtoUV(face, a, a_uv);
|
|
179
|
+
(*a_uv)[0] = max(-1.0, min(1.0, (*a_uv)[0]));
|
|
180
|
+
(*a_uv)[1] = max(-1.0, min(1.0, (*a_uv)[1]));
|
|
181
|
+
return face;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Return the next face that should be visited by GetFaceSegments, given that
|
|
185
|
+
// we have just visited "face" and we are following the line AB (represented
|
|
186
|
+
// by its normal N in the (u,v,w) coordinates of that face). The other
|
|
187
|
+
// arguments include the point where AB exits "face", the corresponding
|
|
188
|
+
// exit axis, and the "target face" containing the destination point B.
|
|
189
|
+
static int GetNextFace(int face, const R2Point& exit, int axis,
|
|
190
|
+
const S2PointUVW& n, int target_face) {
|
|
191
|
+
// We return the face that is adjacent to the exit point along the given
|
|
192
|
+
// axis. If line AB exits *exactly* through a corner of the face, there are
|
|
193
|
+
// two possible next faces. If one is the "target face" containing B, then
|
|
194
|
+
// we guarantee that we advance to that face directly.
|
|
195
|
+
//
|
|
196
|
+
// The three conditions below check that (1) AB exits approximately through
|
|
197
|
+
// a corner, (2) the adjacent face along the non-exit axis is the target
|
|
198
|
+
// face, and (3) AB exits *exactly* through the corner. (The SumEquals()
|
|
199
|
+
// code checks whether the dot product of (u,v,1) and "n" is exactly zero.)
|
|
200
|
+
if (fabs(exit[1 - axis]) == 1 &&
|
|
201
|
+
S2::GetUVWFace(face, 1 - axis, exit[1 - axis] > 0) == target_face &&
|
|
202
|
+
SumEquals(exit[0] * n[0], exit[1] * n[1], -n[2])) {
|
|
203
|
+
return target_face;
|
|
204
|
+
}
|
|
205
|
+
// Otherwise return the face that is adjacent to the exit point in the
|
|
206
|
+
// direction of the exit axis.
|
|
207
|
+
return S2::GetUVWFace(face, axis, exit[axis] > 0);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
void GetFaceSegments(const S2Point& a, const S2Point& b,
|
|
211
|
+
FaceSegmentVector* segments) {
|
|
212
|
+
S2_DCHECK(S2::IsUnitLength(a));
|
|
213
|
+
S2_DCHECK(S2::IsUnitLength(b));
|
|
214
|
+
segments->clear();
|
|
215
|
+
|
|
216
|
+
// Fast path: both endpoints are on the same face.
|
|
217
|
+
FaceSegment segment;
|
|
218
|
+
int a_face = S2::XYZtoFaceUV(a, &segment.a);
|
|
219
|
+
int b_face = S2::XYZtoFaceUV(b, &segment.b);
|
|
220
|
+
if (a_face == b_face) {
|
|
221
|
+
segment.face = a_face;
|
|
222
|
+
segments->push_back(segment);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// Starting at A, we follow AB from face to face until we reach the face
|
|
226
|
+
// containing B. The following code is designed to ensure that we always
|
|
227
|
+
// reach B, even in the presence of numerical errors.
|
|
228
|
+
//
|
|
229
|
+
// First we compute the normal to the plane containing A and B. This normal
|
|
230
|
+
// becomes the ultimate definition of the line AB; it is used to resolve all
|
|
231
|
+
// questions regarding where exactly the line goes. Unfortunately due to
|
|
232
|
+
// numerical errors, the line may not quite intersect the faces containing
|
|
233
|
+
// the original endpoints. We handle this by moving A and/or B slightly if
|
|
234
|
+
// necessary so that they are on faces intersected by the line AB.
|
|
235
|
+
S2Point ab = S2::RobustCrossProd(a, b);
|
|
236
|
+
a_face = MoveOriginToValidFace(a_face, a, ab, &segment.a);
|
|
237
|
+
b_face = MoveOriginToValidFace(b_face, b, -ab, &segment.b);
|
|
238
|
+
|
|
239
|
+
// Now we simply follow AB from face to face until we reach B.
|
|
240
|
+
segment.face = a_face;
|
|
241
|
+
R2Point b_saved = segment.b;
|
|
242
|
+
for (int face = a_face; face != b_face; ) {
|
|
243
|
+
// Complete the current segment by finding the point where AB exits the
|
|
244
|
+
// current face.
|
|
245
|
+
S2PointUVW n = S2::FaceXYZtoUVW(face, ab);
|
|
246
|
+
int exit_axis = GetExitAxis(n);
|
|
247
|
+
segment.b = GetExitPoint(n, exit_axis);
|
|
248
|
+
segments->push_back(segment);
|
|
249
|
+
|
|
250
|
+
// Compute the next face intersected by AB, and translate the exit point
|
|
251
|
+
// of the current segment into the (u,v) coordinates of the next face.
|
|
252
|
+
// This becomes the first point of the next segment.
|
|
253
|
+
S2Point exit_xyz = S2::FaceUVtoXYZ(face, segment.b);
|
|
254
|
+
face = GetNextFace(face, segment.b, exit_axis, n, b_face);
|
|
255
|
+
S2PointUVW exit_uvw = S2::FaceXYZtoUVW(face, exit_xyz);
|
|
256
|
+
segment.face = face;
|
|
257
|
+
segment.a = R2Point(exit_uvw[0], exit_uvw[1]);
|
|
258
|
+
}
|
|
259
|
+
// Finish the last segment.
|
|
260
|
+
segment.b = b_saved;
|
|
261
|
+
segments->push_back(segment);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// This helper function does two things. First, it clips the line segment AB
|
|
265
|
+
// to find the clipped destination B' on a given face. (The face is specified
|
|
266
|
+
// implicitly by expressing *all arguments* in the (u,v,w) coordinates of that
|
|
267
|
+
// face.) Second, it partially computes whether the segment AB intersects
|
|
268
|
+
// this face at all. The actual condition is fairly complicated, but it turns
|
|
269
|
+
// out that it can be expressed as a "score" that can be computed
|
|
270
|
+
// independently when clipping the two endpoints A and B. This function
|
|
271
|
+
// returns the score for the given endpoint, which is an integer ranging from
|
|
272
|
+
// 0 to 3. If the sum of the two scores is 3 or more, then AB does not
|
|
273
|
+
// intersect this face. See the calling function for the meaning of the
|
|
274
|
+
// various parameters.
|
|
275
|
+
static int ClipDestination(
|
|
276
|
+
const S2PointUVW& a, const S2PointUVW& b, const S2PointUVW& scaled_n,
|
|
277
|
+
const S2PointUVW& a_tangent, const S2PointUVW& b_tangent, double scale_uv,
|
|
278
|
+
R2Point* uv) {
|
|
279
|
+
S2_DCHECK(IntersectsFace(scaled_n));
|
|
280
|
+
|
|
281
|
+
// Optimization: if B is within the safe region of the face, use it.
|
|
282
|
+
const double kMaxSafeUVCoord = 1 - kFaceClipErrorUVCoord;
|
|
283
|
+
if (b[2] > 0) {
|
|
284
|
+
*uv = R2Point(b[0] / b[2], b[1] / b[2]);
|
|
285
|
+
if (max(fabs((*uv)[0]), fabs((*uv)[1])) <= kMaxSafeUVCoord)
|
|
286
|
+
return 0;
|
|
287
|
+
}
|
|
288
|
+
// Otherwise find the point B' where the line AB exits the face.
|
|
289
|
+
*uv = scale_uv * GetExitPoint(scaled_n, GetExitAxis(scaled_n));
|
|
290
|
+
S2PointUVW p((*uv)[0], (*uv)[1], 1.0);
|
|
291
|
+
|
|
292
|
+
// Determine if the exit point B' is contained within the segment. We do this
|
|
293
|
+
// by computing the dot products with two inward-facing tangent vectors at A
|
|
294
|
+
// and B. If either dot product is negative, we say that B' is on the "wrong
|
|
295
|
+
// side" of that point. As the point B' moves around the great circle AB past
|
|
296
|
+
// the segment endpoint B, it is initially on the wrong side of B only; as it
|
|
297
|
+
// moves further it is on the wrong side of both endpoints; and then it is on
|
|
298
|
+
// the wrong side of A only. If the exit point B' is on the wrong side of
|
|
299
|
+
// either endpoint, we can't use it; instead the segment is clipped at the
|
|
300
|
+
// original endpoint B.
|
|
301
|
+
//
|
|
302
|
+
// We reject the segment if the sum of the scores of the two endpoints is 3
|
|
303
|
+
// or more. Here is what that rule encodes:
|
|
304
|
+
// - If B' is on the wrong side of A, then the other clipped endpoint A'
|
|
305
|
+
// must be in the interior of AB (otherwise AB' would go the wrong way
|
|
306
|
+
// around the circle). There is a similar rule for A'.
|
|
307
|
+
// - If B' is on the wrong side of either endpoint (and therefore we must
|
|
308
|
+
// use the original endpoint B instead), then it must be possible to
|
|
309
|
+
// project B onto this face (i.e., its w-coordinate must be positive).
|
|
310
|
+
// This rule is only necessary to handle certain zero-length edges (A=B).
|
|
311
|
+
int score = 0;
|
|
312
|
+
if ((p - a).DotProd(a_tangent) < 0) {
|
|
313
|
+
score = 2; // B' is on wrong side of A.
|
|
314
|
+
} else if ((p - b).DotProd(b_tangent) < 0) {
|
|
315
|
+
score = 1; // B' is on wrong side of B.
|
|
316
|
+
}
|
|
317
|
+
if (score > 0) { // B' is not in the interior of AB.
|
|
318
|
+
if (b[2] <= 0) {
|
|
319
|
+
score = 3; // B cannot be projected onto this face.
|
|
320
|
+
} else {
|
|
321
|
+
*uv = R2Point(b[0] / b[2], b[1] / b[2]);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return score;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
bool ClipToPaddedFace(const S2Point& a_xyz, const S2Point& b_xyz, int face,
|
|
328
|
+
double padding, R2Point* a_uv, R2Point* b_uv) {
|
|
329
|
+
S2_DCHECK_GE(padding, 0);
|
|
330
|
+
// Fast path: both endpoints are on the given face.
|
|
331
|
+
if (S2::GetFace(a_xyz) == face && S2::GetFace(b_xyz) == face) {
|
|
332
|
+
S2::ValidFaceXYZtoUV(face, a_xyz, a_uv);
|
|
333
|
+
S2::ValidFaceXYZtoUV(face, b_xyz, b_uv);
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
// Convert everything into the (u,v,w) coordinates of the given face. Note
|
|
337
|
+
// that the cross product *must* be computed in the original (x,y,z)
|
|
338
|
+
// coordinate system because RobustCrossProd (unlike the mathematical cross
|
|
339
|
+
// product) can produce different results in different coordinate systems
|
|
340
|
+
// when one argument is a linear multiple of the other, due to the use of
|
|
341
|
+
// symbolic perturbations.
|
|
342
|
+
S2PointUVW n = S2::FaceXYZtoUVW(face, S2::RobustCrossProd(a_xyz, b_xyz));
|
|
343
|
+
S2PointUVW a = S2::FaceXYZtoUVW(face, a_xyz);
|
|
344
|
+
S2PointUVW b = S2::FaceXYZtoUVW(face, b_xyz);
|
|
345
|
+
|
|
346
|
+
// Padding is handled by scaling the u- and v-components of the normal.
|
|
347
|
+
// Letting R=1+padding, this means that when we compute the dot product of
|
|
348
|
+
// the normal with a cube face vertex (such as (-1,-1,1)), we will actually
|
|
349
|
+
// compute the dot product with the scaled vertex (-R,-R,1). This allows
|
|
350
|
+
// methods such as IntersectsFace(), GetExitAxis(), etc, to handle padding
|
|
351
|
+
// with no further modifications.
|
|
352
|
+
const double scale_uv = 1 + padding;
|
|
353
|
+
S2PointUVW scaled_n(scale_uv * n[0], scale_uv * n[1], n[2]);
|
|
354
|
+
if (!IntersectsFace(scaled_n)) return false;
|
|
355
|
+
|
|
356
|
+
// TODO(ericv): This is a temporary hack until I rewrite S2::RobustCrossProd;
|
|
357
|
+
// it avoids loss of precision in Normalize() when the vector is so small
|
|
358
|
+
// that it underflows.
|
|
359
|
+
if (max(fabs(n[0]), max(fabs(n[1]), fabs(n[2]))) < ldexp(1, -511)) {
|
|
360
|
+
n *= ldexp(1, 563);
|
|
361
|
+
} // END OF HACK
|
|
362
|
+
n = n.Normalize();
|
|
363
|
+
S2PointUVW a_tangent = n.CrossProd(a);
|
|
364
|
+
S2PointUVW b_tangent = b.CrossProd(n);
|
|
365
|
+
// As described above, if the sum of the scores from clipping the two
|
|
366
|
+
// endpoints is 3 or more, then the segment does not intersect this face.
|
|
367
|
+
int a_score = ClipDestination(b, a, -scaled_n, b_tangent, a_tangent,
|
|
368
|
+
scale_uv, a_uv);
|
|
369
|
+
int b_score = ClipDestination(a, b, scaled_n, a_tangent, b_tangent,
|
|
370
|
+
scale_uv, b_uv);
|
|
371
|
+
return a_score + b_score < 3;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
bool IntersectsRect(const R2Point& a, const R2Point& b, const R2Rect& rect) {
|
|
375
|
+
// First check whether the bound of AB intersects "rect".
|
|
376
|
+
R2Rect bound = R2Rect::FromPointPair(a, b);
|
|
377
|
+
if (!rect.Intersects(bound)) return false;
|
|
378
|
+
|
|
379
|
+
// Otherwise AB intersects "rect" if and only if all four vertices of "rect"
|
|
380
|
+
// do not lie on the same side of the extended line AB. We test this by
|
|
381
|
+
// finding the two vertices of "rect" with minimum and maximum projections
|
|
382
|
+
// onto the normal of AB, and computing their dot products with the edge
|
|
383
|
+
// normal.
|
|
384
|
+
R2Point n = (b - a).Ortho();
|
|
385
|
+
int i = (n[0] >= 0) ? 1 : 0;
|
|
386
|
+
int j = (n[1] >= 0) ? 1 : 0;
|
|
387
|
+
double max = n.DotProd(rect.GetVertex(i, j) - a);
|
|
388
|
+
double min = n.DotProd(rect.GetVertex(1-i, 1-j) - a);
|
|
389
|
+
return (max >= 0) && (min <= 0);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
inline static bool UpdateEndpoint(R1Interval* bound, int end, double value) {
|
|
393
|
+
if (end == 0) {
|
|
394
|
+
if (bound->hi() < value) return false;
|
|
395
|
+
if (bound->lo() < value) bound->set_lo(value);
|
|
396
|
+
} else {
|
|
397
|
+
if (bound->lo() > value) return false;
|
|
398
|
+
if (bound->hi() > value) bound->set_hi(value);
|
|
399
|
+
}
|
|
400
|
+
return true;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Given a line segment from (a0,a1) to (b0,b1) and a bounding interval for
|
|
404
|
+
// each axis, clip the segment further if necessary so that "bound0" does not
|
|
405
|
+
// extend outside the given interval "clip". "diag" is a a precomputed helper
|
|
406
|
+
// variable that indicates which diagonal of the bounding box is spanned by AB:
|
|
407
|
+
// it is 0 if AB has positive slope, and 1 if AB has negative slope.
|
|
408
|
+
inline static bool ClipBoundAxis(double a0, double b0, R1Interval* bound0,
|
|
409
|
+
double a1, double b1, R1Interval* bound1,
|
|
410
|
+
int diag, const R1Interval& clip0) {
|
|
411
|
+
if (bound0->lo() < clip0.lo()) {
|
|
412
|
+
if (bound0->hi() < clip0.lo()) return false;
|
|
413
|
+
(*bound0)[0] = clip0.lo();
|
|
414
|
+
if (!UpdateEndpoint(bound1, diag,
|
|
415
|
+
InterpolateDouble(clip0.lo(), a0, b0, a1, b1)))
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
if (bound0->hi() > clip0.hi()) {
|
|
419
|
+
if (bound0->lo() > clip0.hi()) return false;
|
|
420
|
+
(*bound0)[1] = clip0.hi();
|
|
421
|
+
if (!UpdateEndpoint(bound1, 1-diag,
|
|
422
|
+
InterpolateDouble(clip0.hi(), a0, b0, a1, b1)))
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
return true;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
R2Rect GetClippedEdgeBound(const R2Point& a, const R2Point& b,
|
|
429
|
+
const R2Rect& clip) {
|
|
430
|
+
R2Rect bound = R2Rect::FromPointPair(a, b);
|
|
431
|
+
if (ClipEdgeBound(a, b, clip, &bound)) return bound;
|
|
432
|
+
return R2Rect::Empty();
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
bool ClipEdgeBound(const R2Point& a, const R2Point& b, const R2Rect& clip,
|
|
436
|
+
R2Rect* bound) {
|
|
437
|
+
// "diag" indicates which diagonal of the bounding box is spanned by AB: it
|
|
438
|
+
// is 0 if AB has positive slope, and 1 if AB has negative slope. This is
|
|
439
|
+
// used to determine which interval endpoints need to be updated each time
|
|
440
|
+
// the edge is clipped.
|
|
441
|
+
int diag = (a[0] > b[0]) != (a[1] > b[1]);
|
|
442
|
+
return (ClipBoundAxis(a[0], b[0], &(*bound)[0], a[1], b[1], &(*bound)[1],
|
|
443
|
+
diag, clip[0]) &&
|
|
444
|
+
ClipBoundAxis(a[1], b[1], &(*bound)[1], a[0], b[0], &(*bound)[0],
|
|
445
|
+
diag, clip[1]));
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
bool ClipEdge(const R2Point& a, const R2Point& b, const R2Rect& clip,
|
|
449
|
+
R2Point* a_clipped, R2Point* b_clipped) {
|
|
450
|
+
// Compute the bounding rectangle of AB, clip it, and then extract the new
|
|
451
|
+
// endpoints from the clipped bound.
|
|
452
|
+
R2Rect bound = R2Rect::FromPointPair(a, b);
|
|
453
|
+
if (ClipEdgeBound(a, b, clip, &bound)) {
|
|
454
|
+
int ai = (a[0] > b[0]), aj = (a[1] > b[1]);
|
|
455
|
+
*a_clipped = bound.GetVertex(ai, aj);
|
|
456
|
+
*b_clipped = bound.GetVertex(1-ai, 1-aj);
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
} // namespace S2
|