@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,313 @@
|
|
|
1
|
+
// Copyright 2018 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/s2loop_measures.h"
|
|
19
|
+
|
|
20
|
+
#include <cfloat>
|
|
21
|
+
#include <cmath>
|
|
22
|
+
#include <vector>
|
|
23
|
+
#include "s2/base/logging.h"
|
|
24
|
+
#include "s2/third_party/absl/container/inlined_vector.h"
|
|
25
|
+
#include "s2/s1angle.h"
|
|
26
|
+
#include "s2/s2centroids.h"
|
|
27
|
+
#include "s2/s2edge_distances.h"
|
|
28
|
+
#include "s2/s2measures.h"
|
|
29
|
+
#include "s2/s2pointutil.h"
|
|
30
|
+
|
|
31
|
+
using std::fabs;
|
|
32
|
+
using std::max;
|
|
33
|
+
using std::min;
|
|
34
|
+
using std::vector;
|
|
35
|
+
|
|
36
|
+
namespace S2 {
|
|
37
|
+
|
|
38
|
+
S1Angle GetPerimeter(S2PointLoopSpan loop) {
|
|
39
|
+
S1Angle perimeter = S1Angle::Zero();
|
|
40
|
+
if (loop.size() <= 1) return perimeter;
|
|
41
|
+
for (int i = 0; i < loop.size(); ++i) {
|
|
42
|
+
perimeter += S1Angle(loop[i], loop[i + 1]);
|
|
43
|
+
}
|
|
44
|
+
return perimeter;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
double GetArea(S2PointLoopSpan loop) {
|
|
48
|
+
double area = GetSignedArea(loop);
|
|
49
|
+
S2_DCHECK_LE(fabs(area), 2 * M_PI);
|
|
50
|
+
if (area < 0.0) area += 4 * M_PI;
|
|
51
|
+
return area;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
double GetSignedArea(S2PointLoopSpan loop) {
|
|
55
|
+
// It is suprisingly difficult to compute the area of a loop robustly. The
|
|
56
|
+
// main issues are (1) whether degenerate loops are considered to be CCW or
|
|
57
|
+
// not (i.e., whether their area is close to 0 or 4*Pi), and (2) computing
|
|
58
|
+
// the areas of small loops with good relative accuracy.
|
|
59
|
+
//
|
|
60
|
+
// With respect to degeneracies, we would like GetArea() to be consistent
|
|
61
|
+
// with S2Loop::Contains(S2Point) in that loops that contain many points
|
|
62
|
+
// should have large areas, and loops that contain few points should have
|
|
63
|
+
// small areas. For example, if a degenerate triangle is considered CCW
|
|
64
|
+
// according to s2pred::Sign(), then it will contain very few points and
|
|
65
|
+
// its area should be approximately zero. On the other hand if it is
|
|
66
|
+
// considered clockwise, then it will contain virtually all points and so
|
|
67
|
+
// its area should be approximately 4*Pi.
|
|
68
|
+
//
|
|
69
|
+
// More precisely, let U be the set of S2Points for which S2::IsUnitLength()
|
|
70
|
+
// is true, let P(U) be the projection of those points onto the mathematical
|
|
71
|
+
// unit sphere, and let V(P(U)) be the Voronoi diagram of the projected
|
|
72
|
+
// points. Then for every loop x, we would like GetArea() to approximately
|
|
73
|
+
// equal the sum of the areas of the Voronoi regions of the points p for
|
|
74
|
+
// which x.Contains(p) is true.
|
|
75
|
+
//
|
|
76
|
+
// The second issue is that we want to compute the area of small loops
|
|
77
|
+
// accurately. This requires having good relative precision rather than
|
|
78
|
+
// good absolute precision. For example, if the area of a loop is 1e-12 and
|
|
79
|
+
// the error is 1e-15, then the area only has 3 digits of accuracy. (For
|
|
80
|
+
// reference, 1e-12 is about 40 square meters on the surface of the earth.)
|
|
81
|
+
// We would like to have good relative accuracy even for small loops.
|
|
82
|
+
//
|
|
83
|
+
// To achieve these goals, we combine two different methods of computing the
|
|
84
|
+
// area. This first method is based on the Gauss-Bonnet theorem, which says
|
|
85
|
+
// that the area enclosed by the loop equals 2*Pi minus the total geodesic
|
|
86
|
+
// curvature of the loop (i.e., the sum of the "turning angles" at all the
|
|
87
|
+
// loop vertices). The big advantage of this method is that as long as we
|
|
88
|
+
// use s2pred::Sign() to compute the turning angle at each vertex, then
|
|
89
|
+
// degeneracies are always handled correctly. In other words, if a
|
|
90
|
+
// degenerate loop is CCW according to the symbolic perturbations used by
|
|
91
|
+
// s2pred::Sign(), then its turning angle will be approximately 2*Pi.
|
|
92
|
+
//
|
|
93
|
+
// The disadvantage of the Gauss-Bonnet method is that its absolute error is
|
|
94
|
+
// about 2e-15 times the number of vertices (see GetCurvatureMaxError).
|
|
95
|
+
// So, it cannot compute the area of small loops accurately.
|
|
96
|
+
//
|
|
97
|
+
// The second method is based on splitting the loop into triangles and
|
|
98
|
+
// summing the area of each triangle. To avoid the difficulty and expense
|
|
99
|
+
// of decomposing the loop into a union of non-overlapping triangles,
|
|
100
|
+
// instead we compute a signed sum over triangles that may overlap (see the
|
|
101
|
+
// comments for S2Loop::GetSurfaceIntegral). The advantage of this method
|
|
102
|
+
// is that the area of each triangle can be computed with much better
|
|
103
|
+
// relative accuracy (using l'Huilier's theorem). The disadvantage is that
|
|
104
|
+
// the result is a signed area: CCW loops may yield a small positive value,
|
|
105
|
+
// while CW loops may yield a small negative value (which is converted to a
|
|
106
|
+
// positive area by adding 4*Pi). This means that small errors in computing
|
|
107
|
+
// the signed area may translate into a very large error in the result (if
|
|
108
|
+
// the sign of the sum is incorrect).
|
|
109
|
+
//
|
|
110
|
+
// So, our strategy is to combine these two methods as follows. First we
|
|
111
|
+
// compute the area using the "signed sum over triangles" approach (since it
|
|
112
|
+
// is generally more accurate). We also estimate the maximum error in this
|
|
113
|
+
// result. If the signed area is too close to zero (i.e., zero is within
|
|
114
|
+
// the error bounds), then we double-check the sign of the result using the
|
|
115
|
+
// Gauss-Bonnet method. If the two methods disagree, we return the smallest
|
|
116
|
+
// possible positive or negative area based on the result of GetCurvature().
|
|
117
|
+
// Otherwise we return the area that we computed originally.
|
|
118
|
+
|
|
119
|
+
// The signed area should be between approximately -4*Pi and 4*Pi.
|
|
120
|
+
// Normalize it to be in the range [-2*Pi, 2*Pi].
|
|
121
|
+
double area = GetSurfaceIntegral(loop, S2::SignedArea);
|
|
122
|
+
double max_error = GetCurvatureMaxError(loop);
|
|
123
|
+
S2_DCHECK_LE(fabs(area), 4 * M_PI + max_error);
|
|
124
|
+
area = remainder(area, 4 * M_PI);
|
|
125
|
+
|
|
126
|
+
// If the area is a small negative or positive number, verify that the sign
|
|
127
|
+
// of the result is consistent with the loop orientation.
|
|
128
|
+
if (fabs(area) <= max_error) {
|
|
129
|
+
double curvature = GetCurvature(loop);
|
|
130
|
+
// Zero-area loops should have a curvature of approximately +/- 2*Pi.
|
|
131
|
+
S2_DCHECK(!(area == 0 && curvature == 0));
|
|
132
|
+
if (curvature == 2 * M_PI) return 0.0; // Degenerate
|
|
133
|
+
if (area <= 0 && curvature > 0) {
|
|
134
|
+
return std::numeric_limits<double>::min();
|
|
135
|
+
}
|
|
136
|
+
// Full loops are handled by the case below.
|
|
137
|
+
if (area >= 0 && curvature < 0) {
|
|
138
|
+
return -std::numeric_limits<double>::min();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return area;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
double GetApproxArea(S2PointLoopSpan loop) {
|
|
145
|
+
return 2 * M_PI - GetCurvature(loop);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
S2PointLoopSpan PruneDegeneracies(S2PointLoopSpan loop,
|
|
149
|
+
vector<S2Point>* new_vertices) {
|
|
150
|
+
vector<S2Point>& vertices = *new_vertices;
|
|
151
|
+
vertices.clear();
|
|
152
|
+
vertices.reserve(loop.size());
|
|
153
|
+
for (const S2Point& v : loop) {
|
|
154
|
+
// Remove duplicate vertices.
|
|
155
|
+
if (vertices.empty() || v != vertices.back()) {
|
|
156
|
+
// Remove edge pairs of the form ABA.
|
|
157
|
+
if (vertices.size() >= 2 && v == vertices.end()[-2]) {
|
|
158
|
+
vertices.pop_back();
|
|
159
|
+
} else {
|
|
160
|
+
vertices.push_back(v);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Check whether the loop was completely degenerate.
|
|
165
|
+
if (vertices.size() < 3) return S2PointLoopSpan();
|
|
166
|
+
|
|
167
|
+
// Otherwise some portion of the loop is guaranteed to be non-degenerate.
|
|
168
|
+
// However there may still be some degenerate portions to remove.
|
|
169
|
+
if (vertices[0] == vertices.back()) vertices.pop_back();
|
|
170
|
+
|
|
171
|
+
// If the loop begins with BA and ends with A, then there is an edge pair of
|
|
172
|
+
// the form ABA at the end/start of the loop. Remove all such pairs. As
|
|
173
|
+
// noted above, this is guaranteed to leave a non-degenerate loop.
|
|
174
|
+
int k = 0;
|
|
175
|
+
while (vertices[k + 1] == vertices.end()[-(k + 1)]) ++k;
|
|
176
|
+
return S2PointLoopSpan(vertices.data() + k, vertices.size() - 2 * k);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
double GetCurvature(S2PointLoopSpan loop) {
|
|
180
|
+
// By convention, a loop with no vertices contains all points on the sphere.
|
|
181
|
+
if (loop.empty()) return -2 * M_PI;
|
|
182
|
+
|
|
183
|
+
// Remove any degeneracies from the loop.
|
|
184
|
+
vector<S2Point> vertices;
|
|
185
|
+
loop = PruneDegeneracies(loop, &vertices);
|
|
186
|
+
|
|
187
|
+
// If the entire loop was degenerate, it's turning angle is defined as 2*Pi.
|
|
188
|
+
if (loop.empty()) return 2 * M_PI;
|
|
189
|
+
|
|
190
|
+
// To ensure that we get the same result when the vertex order is rotated,
|
|
191
|
+
// and that the result is negated when the vertex order is reversed, we need
|
|
192
|
+
// to add up the individual turn angles in a consistent order. (In general,
|
|
193
|
+
// adding up a set of numbers in a different order can change the sum due to
|
|
194
|
+
// rounding errors.)
|
|
195
|
+
//
|
|
196
|
+
// Furthermore, if we just accumulate an ordinary sum then the worst-case
|
|
197
|
+
// error is quadratic in the number of vertices. (This can happen with
|
|
198
|
+
// spiral shapes, where the partial sum of the turning angles can be linear
|
|
199
|
+
// in the number of vertices.) To avoid this we use the Kahan summation
|
|
200
|
+
// algorithm (http://en.wikipedia.org/wiki/Kahan_summation_algorithm).
|
|
201
|
+
LoopOrder order = GetCanonicalLoopOrder(loop);
|
|
202
|
+
int i = order.first, dir = order.dir, n = loop.size();
|
|
203
|
+
double sum = S2::TurnAngle(loop[(i + n - dir) % n], loop[i],
|
|
204
|
+
loop[(i + dir) % n]);
|
|
205
|
+
double compensation = 0; // Kahan summation algorithm
|
|
206
|
+
while (--n > 0) {
|
|
207
|
+
i += dir;
|
|
208
|
+
double angle = S2::TurnAngle(loop[i - dir], loop[i], loop[i + dir]);
|
|
209
|
+
double old_sum = sum;
|
|
210
|
+
angle += compensation;
|
|
211
|
+
sum += angle;
|
|
212
|
+
compensation = (old_sum - sum) + angle;
|
|
213
|
+
}
|
|
214
|
+
constexpr double kMaxCurvature = 2 * M_PI - 4 * DBL_EPSILON;
|
|
215
|
+
sum += compensation;
|
|
216
|
+
return max(-kMaxCurvature, min(kMaxCurvature, dir * sum));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
double GetCurvatureMaxError(S2PointLoopSpan loop) {
|
|
220
|
+
// The maximum error can be bounded as follows:
|
|
221
|
+
// 2.24 * DBL_EPSILON for RobustCrossProd(b, a)
|
|
222
|
+
// 2.24 * DBL_EPSILON for RobustCrossProd(c, b)
|
|
223
|
+
// 3.25 * DBL_EPSILON for Angle()
|
|
224
|
+
// 2.00 * DBL_EPSILON for each addition in the Kahan summation
|
|
225
|
+
// ------------------
|
|
226
|
+
// 9.73 * DBL_EPSILON
|
|
227
|
+
//
|
|
228
|
+
// TODO(ericv): This error estimate is approximate. There are two issues:
|
|
229
|
+
// (1) SignedArea needs some improvements to ensure that its error is
|
|
230
|
+
// actually never higher than GirardArea, and (2) although the number of
|
|
231
|
+
// triangles in the sum is typically N-2, in theory it could be as high as
|
|
232
|
+
// 2*N for pathological inputs. But in other respects this error bound is
|
|
233
|
+
// very conservative since it assumes that the maximum error is achieved on
|
|
234
|
+
// every triangle.
|
|
235
|
+
const double kMaxErrorPerVertex = 9.73 * DBL_EPSILON;
|
|
236
|
+
return kMaxErrorPerVertex * loop.size();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
S2Point GetCentroid(S2PointLoopSpan loop) {
|
|
240
|
+
// GetSurfaceIntegral() returns either the integral of position over loop
|
|
241
|
+
// interior, or the negative of the integral of position over the loop
|
|
242
|
+
// exterior. But these two values are the same (!), because the integral of
|
|
243
|
+
// position over the entire sphere is (0, 0, 0).
|
|
244
|
+
return GetSurfaceIntegral(loop, S2::TrueCentroid);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
static inline bool IsOrderLess(LoopOrder order1, LoopOrder order2,
|
|
248
|
+
S2PointLoopSpan loop) {
|
|
249
|
+
if (order1 == order2) return false;
|
|
250
|
+
|
|
251
|
+
int i1 = order1.first, i2 = order2.first;
|
|
252
|
+
int dir1 = order1.dir, dir2 = order2.dir;
|
|
253
|
+
S2_DCHECK_EQ(loop[i1], loop[i2]);
|
|
254
|
+
for (int n = loop.size(); --n > 0; ) {
|
|
255
|
+
i1 += dir1;
|
|
256
|
+
i2 += dir2;
|
|
257
|
+
if (loop[i1] < loop[i2]) return true;
|
|
258
|
+
if (loop[i1] > loop[i2]) return false;
|
|
259
|
+
}
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
LoopOrder GetCanonicalLoopOrder(S2PointLoopSpan loop) {
|
|
264
|
+
// In order to handle loops with duplicate vertices and/or degeneracies, we
|
|
265
|
+
// return the LoopOrder that minimizes the entire corresponding vertex
|
|
266
|
+
// *sequence*. For example, suppose that vertices are sorted
|
|
267
|
+
// alphabetically, and consider the loop CADBAB. The canonical loop order
|
|
268
|
+
// would be (4, 1), corresponding to the vertex sequence ABCADB. (For
|
|
269
|
+
// comparison, loop order (4, -1) yields the sequence ABDACB.)
|
|
270
|
+
//
|
|
271
|
+
// If two or more loop orders yield identical minimal vertex sequences, then
|
|
272
|
+
// it doesn't matter which one we return (since they yield the same result).
|
|
273
|
+
|
|
274
|
+
// For efficiency, we divide the process into two steps. First we find the
|
|
275
|
+
// smallest vertex, and the set of vertex indices where that vertex occurs
|
|
276
|
+
// (noting that the loop may contain duplicate vertices). Then we consider
|
|
277
|
+
// both possible directions starting from each such vertex index, and return
|
|
278
|
+
// the LoopOrder corresponding to the smallest vertex sequence.
|
|
279
|
+
int n = loop.size();
|
|
280
|
+
if (n == 0) return LoopOrder(0, 1);
|
|
281
|
+
|
|
282
|
+
absl::InlinedVector<int, 4> min_indices;
|
|
283
|
+
min_indices.push_back(0);
|
|
284
|
+
for (int i = 1; i < n; ++i) {
|
|
285
|
+
if (loop[i] <= loop[min_indices[0]]) {
|
|
286
|
+
if (loop[i] < loop[min_indices[0]]) min_indices.clear();
|
|
287
|
+
min_indices.push_back(i);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
LoopOrder min_order(min_indices[0], 1);
|
|
291
|
+
for (int min_index : min_indices) {
|
|
292
|
+
LoopOrder order1(min_index, 1);
|
|
293
|
+
LoopOrder order2(min_index + n, -1);
|
|
294
|
+
if (IsOrderLess(order1, min_order, loop)) min_order = order1;
|
|
295
|
+
if (IsOrderLess(order2, min_order, loop)) min_order = order2;
|
|
296
|
+
}
|
|
297
|
+
return min_order;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
bool IsNormalized(S2PointLoopSpan loop) {
|
|
301
|
+
// We allow some error so that hemispheres are always considered normalized.
|
|
302
|
+
//
|
|
303
|
+
// TODO(ericv): This is no longer required by the S2Polygon implementation,
|
|
304
|
+
// so alternatively we could create the invariant that a loop is normalized
|
|
305
|
+
// if and only if its complement is not normalized.
|
|
306
|
+
return GetCurvature(loop) >= -GetCurvatureMaxError(loop);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
std::ostream& operator<<(std::ostream& os, LoopOrder order) {
|
|
310
|
+
return os << "(" << order.first << ", " << order.dir << ")";
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
} // namespace S2
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
// Copyright 2018 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 various angle and area measures for loops on the sphere. These are
|
|
19
|
+
// low-level methods that work directly with arrays of S2Points. They are
|
|
20
|
+
// used to implement the methods in s2shapeindex_measures.h,
|
|
21
|
+
// s2shape_measures.h, s2loop.h, and s2polygon.h.
|
|
22
|
+
//
|
|
23
|
+
// See s2polyline_measures.h, s2edge_distances.h, and s2measures.h for
|
|
24
|
+
// additional low-level methods.
|
|
25
|
+
|
|
26
|
+
#ifndef S2_S2LOOP_MEASURES_H_
|
|
27
|
+
#define S2_S2LOOP_MEASURES_H_
|
|
28
|
+
|
|
29
|
+
#include <cmath>
|
|
30
|
+
#include <ostream>
|
|
31
|
+
#include <vector>
|
|
32
|
+
|
|
33
|
+
#include "s2/s1angle.h"
|
|
34
|
+
#include "s2/s2point.h"
|
|
35
|
+
#include "s2/s2point_span.h"
|
|
36
|
+
#include "s2/s2pointutil.h"
|
|
37
|
+
|
|
38
|
+
namespace S2 {
|
|
39
|
+
|
|
40
|
+
// Returns the perimeter of the loop.
|
|
41
|
+
S1Angle GetPerimeter(S2PointLoopSpan loop);
|
|
42
|
+
|
|
43
|
+
// Returns the area of the loop interior, i.e. the region on the left side of
|
|
44
|
+
// the loop. The result is between 0 and 4*Pi steradians. The implementation
|
|
45
|
+
// ensures that nearly-degenerate clockwise loops have areas close to zero,
|
|
46
|
+
// while nearly-degenerate counter-clockwise loops have areas close to 4*Pi.
|
|
47
|
+
double GetArea(S2PointLoopSpan loop);
|
|
48
|
+
|
|
49
|
+
// Like GetArea(), except that this method is faster and has more error. The
|
|
50
|
+
// result is between 0 and 4*Pi steradians. The maximum error is 2.22e-15
|
|
51
|
+
// steradians per loop vertex, which works out to about 0.09 square meters per
|
|
52
|
+
// vertex on the Earth's surface. For example, a loop with 100 vertices has a
|
|
53
|
+
// maximum error of about 9 square meters. (The actual error is typically
|
|
54
|
+
// much smaller than this.) The error bound can be computed using
|
|
55
|
+
// GetCurvatureMaxError(), which returns the maximum error in steradians.
|
|
56
|
+
double GetApproxArea(S2PointLoopSpan loop);
|
|
57
|
+
|
|
58
|
+
// Returns either the positive area of the region on the left side of the
|
|
59
|
+
// loop, or the negative area of the region on the right side of the loop,
|
|
60
|
+
// whichever is smaller in magnitude. The result is between -2*Pi and 2*Pi
|
|
61
|
+
// steradians. This method is used to accurately compute the area of polygons
|
|
62
|
+
// consisting of multiple loops.
|
|
63
|
+
//
|
|
64
|
+
// The following cases are handled specially:
|
|
65
|
+
//
|
|
66
|
+
// - Counter-clockwise loops are guaranteed to have positive area, and
|
|
67
|
+
// clockwise loops are guaranteed to have negative area.
|
|
68
|
+
//
|
|
69
|
+
// - Degenerate loops (consisting of an isolated vertex or composed entirely
|
|
70
|
+
// of sibling edge pairs) have an area of exactly zero.
|
|
71
|
+
//
|
|
72
|
+
// - The full loop (containing all points, and represented as a loop with no
|
|
73
|
+
// vertices) has a negative area with the minimum possible magnitude.
|
|
74
|
+
// (This is the "signed equivalent" of having an area of 4*Pi.)
|
|
75
|
+
double GetSignedArea(S2PointLoopSpan loop);
|
|
76
|
+
|
|
77
|
+
// Returns the geodesic curvature of the loop, defined as the sum of the turn
|
|
78
|
+
// angles at each vertex (see S2::TurnAngle). The result is positive if the
|
|
79
|
+
// loop is counter-clockwise, negative if the loop is clockwise, and zero if
|
|
80
|
+
// the loop is a great circle. The geodesic curvature is equal to 2*Pi minus
|
|
81
|
+
// the area of the loop.
|
|
82
|
+
//
|
|
83
|
+
// The following cases are handled specially:
|
|
84
|
+
//
|
|
85
|
+
// - Degenerate loops (consisting of an isolated vertex or composed entirely
|
|
86
|
+
// of sibling edge pairs) have a curvature of 2*Pi exactly.
|
|
87
|
+
//
|
|
88
|
+
// - The full loop (containing all points, and represented as a loop with no
|
|
89
|
+
// vertices) has a curvature of -2*Pi exactly.
|
|
90
|
+
//
|
|
91
|
+
// - All other loops have a non-zero curvature in the range (-2*Pi, 2*Pi).
|
|
92
|
+
// For any such loop, reversing the order of the vertices is guaranteed to
|
|
93
|
+
// negate the curvature. This property can be used to define a unique
|
|
94
|
+
// normalized orientation for every loop.
|
|
95
|
+
double GetCurvature(S2PointLoopSpan loop);
|
|
96
|
+
|
|
97
|
+
// Returns the maximum error in GetCurvature() for the given loop. This value
|
|
98
|
+
// is also an upper bound on the error in GetArea(), GetSignedArea(), and
|
|
99
|
+
// GetApproxArea().
|
|
100
|
+
double GetCurvatureMaxError(S2PointLoopSpan loop);
|
|
101
|
+
|
|
102
|
+
// Returns the true centroid of the loop multiplied by the area of the loop
|
|
103
|
+
// (see s2centroids.h for details on centroids). The result is not unit
|
|
104
|
+
// length, so you may want to normalize it. Also note that in general, the
|
|
105
|
+
// centroid may not be contained by the loop.
|
|
106
|
+
//
|
|
107
|
+
// The result is scaled by the loop area for two reasons: (1) it is cheaper to
|
|
108
|
+
// compute this way, and (2) it makes it easier to compute the centroid of
|
|
109
|
+
// more complicated shapes (by splitting them into disjoint regions and adding
|
|
110
|
+
// their centroids).
|
|
111
|
+
S2Point GetCentroid(S2PointLoopSpan loop);
|
|
112
|
+
|
|
113
|
+
// Returns true if the loop area is at most 2*Pi. (A small amount of error is
|
|
114
|
+
// allowed in order to ensure that loops representing an entire hemisphere are
|
|
115
|
+
// always considered normalized.)
|
|
116
|
+
//
|
|
117
|
+
// Degenerate loops are handled consistently with s2pred::Sign(), i.e., if a
|
|
118
|
+
// loop can be expressed as the union of degenerate or nearly-degenerate
|
|
119
|
+
// counter-clockwise triangles then this method will return true.
|
|
120
|
+
bool IsNormalized(S2PointLoopSpan loop);
|
|
121
|
+
|
|
122
|
+
// LoopOrder represents a cyclic ordering of the loop vertices, starting at
|
|
123
|
+
// the index "first" and proceeding in direction "dir" (either +1 or -1).
|
|
124
|
+
// "first" and "dir" must be chosen such that (first, ..., first + n * dir)
|
|
125
|
+
// are all in the range [0, 2*n-1] as required by S2PointLoopSpan::operator[].
|
|
126
|
+
struct LoopOrder {
|
|
127
|
+
LoopOrder(int _first, int _dir) : first(_first), dir(_dir) {}
|
|
128
|
+
int first;
|
|
129
|
+
int dir;
|
|
130
|
+
};
|
|
131
|
+
bool operator==(LoopOrder x, LoopOrder y);
|
|
132
|
+
std::ostream& operator<<(std::ostream& os, LoopOrder order);
|
|
133
|
+
|
|
134
|
+
// Returns an index "first" and a direction "dir" such that the vertex
|
|
135
|
+
// sequence (first, first + dir, ..., first + (n - 1) * dir) does not change
|
|
136
|
+
// when the loop vertex order is rotated or reversed. This allows the loop
|
|
137
|
+
// vertices to be traversed in a canonical order.
|
|
138
|
+
LoopOrder GetCanonicalLoopOrder(S2PointLoopSpan loop);
|
|
139
|
+
|
|
140
|
+
// Returns the oriented surface integral of some quantity f(x) over the loop
|
|
141
|
+
// interior, given a function f_tri(A,B,C) that returns the corresponding
|
|
142
|
+
// integral over the spherical triangle ABC. Here "oriented surface integral"
|
|
143
|
+
// means:
|
|
144
|
+
//
|
|
145
|
+
// (1) f_tri(A,B,C) must be the integral of f if ABC is counterclockwise,
|
|
146
|
+
// and the integral of -f if ABC is clockwise.
|
|
147
|
+
//
|
|
148
|
+
// (2) The result of this function is *either* the integral of f over the
|
|
149
|
+
// loop interior, or the integral of (-f) over the loop exterior.
|
|
150
|
+
//
|
|
151
|
+
// Note that there are at least two common situations where property (2) above
|
|
152
|
+
// is not a limitation:
|
|
153
|
+
//
|
|
154
|
+
// - If the integral of f over the entire sphere is zero, then it doesn't
|
|
155
|
+
// matter which case is returned because they are always equal.
|
|
156
|
+
//
|
|
157
|
+
// - If f is non-negative, then it is easy to detect when the integral over
|
|
158
|
+
// the loop exterior has been returned, and the integral over the loop
|
|
159
|
+
// interior can be obtained by adding the integral of f over the entire
|
|
160
|
+
// unit sphere (a constant) to the result.
|
|
161
|
+
//
|
|
162
|
+
// REQUIRES: The default constructor for T must initialize the value to zero.
|
|
163
|
+
// (This is true for built-in types such as "double".)
|
|
164
|
+
template <class T>
|
|
165
|
+
T GetSurfaceIntegral(S2PointLoopSpan loop,
|
|
166
|
+
T f_tri(const S2Point&, const S2Point&, const S2Point&));
|
|
167
|
+
|
|
168
|
+
// Returns a new loop obtained by removing all degeneracies from "loop". In
|
|
169
|
+
// particular, the result will not contain any adjacent duplicate vertices or
|
|
170
|
+
// sibling edge pairs, i.e. vertex sequences of the form (A, A) or (A, B, A).
|
|
171
|
+
//
|
|
172
|
+
// "new_vertices" represents storage where new loop vertices may be written.
|
|
173
|
+
// Note that the S2PointLoopSpan result may be a subsequence of either "loop"
|
|
174
|
+
// or "new_vertices", and therefore "new_vertices" must persist until the
|
|
175
|
+
// result of this method is no longer needed.
|
|
176
|
+
S2PointLoopSpan PruneDegeneracies(S2PointLoopSpan loop,
|
|
177
|
+
std::vector<S2Point>* new_vertices);
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
//////////////////// Implementation details follow ////////////////////////
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
inline bool operator==(LoopOrder x, LoopOrder y) {
|
|
184
|
+
return x.first == y.first && x.dir == y.dir;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
template <class T>
|
|
188
|
+
T GetSurfaceIntegral(S2PointLoopSpan loop,
|
|
189
|
+
T f_tri(const S2Point&, const S2Point&, const S2Point&)) {
|
|
190
|
+
// We sum "f_tri" over a collection T of oriented triangles, possibly
|
|
191
|
+
// overlapping. Let the sign of a triangle be +1 if it is CCW and -1
|
|
192
|
+
// otherwise, and let the sign of a point "x" be the sum of the signs of the
|
|
193
|
+
// triangles containing "x". Then the collection of triangles T is chosen
|
|
194
|
+
// such that either:
|
|
195
|
+
//
|
|
196
|
+
// (1) Each point in the loop interior has sign +1, and sign 0 otherwise; or
|
|
197
|
+
// (2) Each point in the loop exterior has sign -1, and sign 0 otherwise.
|
|
198
|
+
//
|
|
199
|
+
// The triangles basically consist of a "fan" from vertex 0 to every loop
|
|
200
|
+
// edge that does not include vertex 0. These triangles will always satisfy
|
|
201
|
+
// either (1) or (2). However, what makes this a bit tricky is that
|
|
202
|
+
// spherical edges become numerically unstable as their length approaches
|
|
203
|
+
// 180 degrees. Of course there is not much we can do if the loop itself
|
|
204
|
+
// contains such edges, but we would like to make sure that all the triangle
|
|
205
|
+
// edges under our control (i.e., the non-loop edges) are stable. For
|
|
206
|
+
// example, consider a loop around the equator consisting of four equally
|
|
207
|
+
// spaced points. This is a well-defined loop, but we cannot just split it
|
|
208
|
+
// into two triangles by connecting vertex 0 to vertex 2.
|
|
209
|
+
//
|
|
210
|
+
// We handle this type of situation by moving the origin of the triangle fan
|
|
211
|
+
// whenever we are about to create an unstable edge. We choose a new
|
|
212
|
+
// location for the origin such that all relevant edges are stable. We also
|
|
213
|
+
// create extra triangles with the appropriate orientation so that the sum
|
|
214
|
+
// of the triangle signs is still correct at every point.
|
|
215
|
+
|
|
216
|
+
// The maximum length of an edge for it to be considered numerically stable.
|
|
217
|
+
// The exact value is fairly arbitrary since it depends on the stability of
|
|
218
|
+
// the "f_tri" function. The value below is quite conservative but could be
|
|
219
|
+
// reduced further if desired.
|
|
220
|
+
static const double kMaxLength = M_PI - 1e-5;
|
|
221
|
+
|
|
222
|
+
// The default constructor for T must initialize the value to zero.
|
|
223
|
+
// (This is true for built-in types such as "double".)
|
|
224
|
+
T sum = T();
|
|
225
|
+
if (loop.size() < 3) return sum;
|
|
226
|
+
|
|
227
|
+
S2Point origin = loop[0];
|
|
228
|
+
for (int i = 1; i + 1 < loop.size(); ++i) {
|
|
229
|
+
// Let V_i be loop[i], let O be the current origin, and let length(A,B)
|
|
230
|
+
// be the length of edge (A,B). At the start of each loop iteration, the
|
|
231
|
+
// "leading edge" of the triangle fan is (O,V_i), and we want to extend
|
|
232
|
+
// the triangle fan so that the leading edge is (O,V_i+1).
|
|
233
|
+
//
|
|
234
|
+
// Invariants:
|
|
235
|
+
// 1. length(O,V_i) < kMaxLength for all (i > 1).
|
|
236
|
+
// 2. Either O == V_0, or O is approximately perpendicular to V_0.
|
|
237
|
+
// 3. "sum" is the oriented integral of f over the area defined by
|
|
238
|
+
// (O, V_0, V_1, ..., V_i).
|
|
239
|
+
S2_DCHECK(i == 1 || origin.Angle(loop[i]) < kMaxLength);
|
|
240
|
+
S2_DCHECK(origin == loop[0] || std::fabs(origin.DotProd(loop[0])) < 1e-15);
|
|
241
|
+
|
|
242
|
+
if (loop[i + 1].Angle(origin) > kMaxLength) {
|
|
243
|
+
// We are about to create an unstable edge, so choose a new origin O'
|
|
244
|
+
// for the triangle fan.
|
|
245
|
+
S2Point old_origin = origin;
|
|
246
|
+
if (origin == loop[0]) {
|
|
247
|
+
// The following point is well-separated from V_i and V_0 (and
|
|
248
|
+
// therefore V_i+1 as well).
|
|
249
|
+
origin = S2::RobustCrossProd(loop[0], loop[i]).Normalize();
|
|
250
|
+
} else if (loop[i].Angle(loop[0]) < kMaxLength) {
|
|
251
|
+
// All edges of the triangle (O, V_0, V_i) are stable, so we can
|
|
252
|
+
// revert to using V_0 as the origin.
|
|
253
|
+
origin = loop[0];
|
|
254
|
+
} else {
|
|
255
|
+
// (O, V_i+1) and (V_0, V_i) are antipodal pairs, and O and V_0 are
|
|
256
|
+
// perpendicular. Therefore V_0.CrossProd(O) is approximately
|
|
257
|
+
// perpendicular to all of {O, V_0, V_i, V_i+1}, and we can choose
|
|
258
|
+
// this point O' as the new origin.
|
|
259
|
+
origin = loop[0].CrossProd(old_origin);
|
|
260
|
+
|
|
261
|
+
// Advance the edge (V_0,O) to (V_0,O').
|
|
262
|
+
sum += f_tri(loop[0], old_origin, origin);
|
|
263
|
+
}
|
|
264
|
+
// Advance the edge (O,V_i) to (O',V_i).
|
|
265
|
+
sum += f_tri(old_origin, loop[i], origin);
|
|
266
|
+
}
|
|
267
|
+
// Advance the edge (O,V_i) to (O,V_i+1).
|
|
268
|
+
sum += f_tri(origin, loop[i], loop[i+1]);
|
|
269
|
+
}
|
|
270
|
+
// If the origin is not V_0, we need to sum one more triangle.
|
|
271
|
+
if (origin != loop[0]) {
|
|
272
|
+
// Advance the edge (O,V_n-1) to (O,V_0).
|
|
273
|
+
sum += f_tri(origin, loop[loop.size() - 1], loop[0]);
|
|
274
|
+
}
|
|
275
|
+
return sum;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
} // namespace S2
|
|
279
|
+
|
|
280
|
+
#endif // S2_S2LOOP_MEASURES_H_
|