@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.
Files changed (471) hide show
  1. package/.circleci/config.yml +45 -0
  2. package/.dockerignore +1 -0
  3. package/.gitmodules +3 -0
  4. package/CHANGELOG.md +33 -0
  5. package/LICENSE +201 -0
  6. package/README.md +147 -0
  7. package/binding.gyp +170 -0
  8. package/docker/Dockerfile.node20.test +8 -0
  9. package/docker/Dockerfile.node22.test +8 -0
  10. package/docker/Dockerfile.node24.test +8 -0
  11. package/index.d.ts +117 -0
  12. package/index.js +6 -0
  13. package/jest.config.js +184 -0
  14. package/package.json +43 -0
  15. package/publish-linux.sh +18 -0
  16. package/publish-osx.sh +19 -0
  17. package/src/builder.cc +84 -0
  18. package/src/builder.h +29 -0
  19. package/src/cell.cc +71 -0
  20. package/src/cell.h +26 -0
  21. package/src/cell_id.cc +210 -0
  22. package/src/cell_id.h +44 -0
  23. package/src/cell_union.cc +237 -0
  24. package/src/cell_union.h +34 -0
  25. package/src/earth.cc +185 -0
  26. package/src/earth.h +33 -0
  27. package/src/latlng.cc +132 -0
  28. package/src/latlng.h +28 -0
  29. package/src/loop.cc +51 -0
  30. package/src/loop.h +21 -0
  31. package/src/point.cc +69 -0
  32. package/src/point.h +23 -0
  33. package/src/polygon.cc +36 -0
  34. package/src/polygon.h +20 -0
  35. package/src/polyline.cc +186 -0
  36. package/src/polyline.h +34 -0
  37. package/src/region_coverer.cc +450 -0
  38. package/src/region_coverer.h +56 -0
  39. package/src/s2.cc +27 -0
  40. package/test/Cell.test.js +37 -0
  41. package/test/CellId.test.js +135 -0
  42. package/test/CellUnion.test.js +150 -0
  43. package/test/Earth.test.js +62 -0
  44. package/test/LatLng.test.js +45 -0
  45. package/test/Point.test.js +14 -0
  46. package/test/Polyline.test.js +78 -0
  47. package/test/RegionCoverer.test.js +301 -0
  48. package/test.sh +16 -0
  49. package/third_party/s2geometry/.travis.yml +163 -0
  50. package/third_party/s2geometry/AUTHORS +13 -0
  51. package/third_party/s2geometry/CONTRIBUTING.md +65 -0
  52. package/third_party/s2geometry/CONTRIBUTORS +30 -0
  53. package/third_party/s2geometry/LICENSE +202 -0
  54. package/third_party/s2geometry/NOTICE +5 -0
  55. package/third_party/s2geometry/README.md +127 -0
  56. package/third_party/s2geometry/doc/examples/point_index.cc +44 -0
  57. package/third_party/s2geometry/doc/examples/term_index.cc +99 -0
  58. package/third_party/s2geometry/doc/examples/term_index.py +101 -0
  59. package/third_party/s2geometry/src/python/coder.i +125 -0
  60. package/third_party/s2geometry/src/python/pywraps2_test.py +786 -0
  61. package/third_party/s2geometry/src/python/s2.i +37 -0
  62. package/third_party/s2geometry/src/python/s2_common.i +756 -0
  63. package/third_party/s2geometry/src/s2/_fp_contract_off.h +60 -0
  64. package/third_party/s2geometry/src/s2/base/casts.h +318 -0
  65. package/third_party/s2geometry/src/s2/base/commandlineflags.h +67 -0
  66. package/third_party/s2geometry/src/s2/base/integral_types.h +31 -0
  67. package/third_party/s2geometry/src/s2/base/log_severity.h +40 -0
  68. package/third_party/s2geometry/src/s2/base/logging.h +173 -0
  69. package/third_party/s2geometry/src/s2/base/mutex.h +61 -0
  70. package/third_party/s2geometry/src/s2/base/port.h +999 -0
  71. package/third_party/s2geometry/src/s2/base/spinlock.h +60 -0
  72. package/third_party/s2geometry/src/s2/base/stringprintf.cc +107 -0
  73. package/third_party/s2geometry/src/s2/base/stringprintf.h +53 -0
  74. package/third_party/s2geometry/src/s2/base/strtoint.cc +65 -0
  75. package/third_party/s2geometry/src/s2/base/strtoint.h +106 -0
  76. package/third_party/s2geometry/src/s2/base/timer.h +50 -0
  77. package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector.cc +164 -0
  78. package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector.h +110 -0
  79. package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector_test.cc +232 -0
  80. package/third_party/s2geometry/src/s2/encoded_s2point_vector.cc +838 -0
  81. package/third_party/s2geometry/src/s2/encoded_s2point_vector.h +140 -0
  82. package/third_party/s2geometry/src/s2/encoded_s2point_vector_test.cc +344 -0
  83. package/third_party/s2geometry/src/s2/encoded_s2shape_index.cc +181 -0
  84. package/third_party/s2geometry/src/s2/encoded_s2shape_index.h +276 -0
  85. package/third_party/s2geometry/src/s2/encoded_s2shape_index_test.cc +244 -0
  86. package/third_party/s2geometry/src/s2/encoded_string_vector.cc +66 -0
  87. package/third_party/s2geometry/src/s2/encoded_string_vector.h +164 -0
  88. package/third_party/s2geometry/src/s2/encoded_string_vector_test.cc +69 -0
  89. package/third_party/s2geometry/src/s2/encoded_uint_vector.h +299 -0
  90. package/third_party/s2geometry/src/s2/encoded_uint_vector_test.cc +124 -0
  91. package/third_party/s2geometry/src/s2/id_set_lexicon.cc +81 -0
  92. package/third_party/s2geometry/src/s2/id_set_lexicon.h +199 -0
  93. package/third_party/s2geometry/src/s2/id_set_lexicon_test.cc +70 -0
  94. package/third_party/s2geometry/src/s2/mutable_s2shape_index.cc +1585 -0
  95. package/third_party/s2geometry/src/s2/mutable_s2shape_index.h +600 -0
  96. package/third_party/s2geometry/src/s2/mutable_s2shape_index_test.cc +589 -0
  97. package/third_party/s2geometry/src/s2/r1interval.h +220 -0
  98. package/third_party/s2geometry/src/s2/r1interval_test.cc +185 -0
  99. package/third_party/s2geometry/src/s2/r2.h +26 -0
  100. package/third_party/s2geometry/src/s2/r2rect.cc +93 -0
  101. package/third_party/s2geometry/src/s2/r2rect.h +234 -0
  102. package/third_party/s2geometry/src/s2/r2rect_test.cc +228 -0
  103. package/third_party/s2geometry/src/s2/s1angle.cc +54 -0
  104. package/third_party/s2geometry/src/s2/s1angle.h +336 -0
  105. package/third_party/s2geometry/src/s2/s1angle_test.cc +185 -0
  106. package/third_party/s2geometry/src/s2/s1chord_angle.cc +159 -0
  107. package/third_party/s2geometry/src/s2/s1chord_angle.h +369 -0
  108. package/third_party/s2geometry/src/s2/s1chord_angle_test.cc +207 -0
  109. package/third_party/s2geometry/src/s2/s1interval.cc +296 -0
  110. package/third_party/s2geometry/src/s2/s1interval.h +266 -0
  111. package/third_party/s2geometry/src/s2/s1interval_test.cc +469 -0
  112. package/third_party/s2geometry/src/s2/s2boolean_operation.cc +2391 -0
  113. package/third_party/s2geometry/src/s2/s2boolean_operation.h +501 -0
  114. package/third_party/s2geometry/src/s2/s2boolean_operation_test.cc +1400 -0
  115. package/third_party/s2geometry/src/s2/s2builder.cc +1828 -0
  116. package/third_party/s2geometry/src/s2/s2builder.h +1057 -0
  117. package/third_party/s2geometry/src/s2/s2builder_graph.cc +1084 -0
  118. package/third_party/s2geometry/src/s2/s2builder_graph.h +799 -0
  119. package/third_party/s2geometry/src/s2/s2builder_graph_test.cc +462 -0
  120. package/third_party/s2geometry/src/s2/s2builder_layer.h +50 -0
  121. package/third_party/s2geometry/src/s2/s2builder_test.cc +1329 -0
  122. package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer.cc +313 -0
  123. package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer.h +221 -0
  124. package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer_test.cc +261 -0
  125. package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies.cc +392 -0
  126. package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies.h +86 -0
  127. package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies_test.cc +182 -0
  128. package/third_party/s2geometry/src/s2/s2builderutil_graph_shape.h +57 -0
  129. package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer.cc +212 -0
  130. package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer.h +218 -0
  131. package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer_test.cc +367 -0
  132. package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer.cc +74 -0
  133. package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer.h +122 -0
  134. package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer_test.cc +167 -0
  135. package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer.cc +191 -0
  136. package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer.h +211 -0
  137. package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer_test.cc +312 -0
  138. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer.cc +105 -0
  139. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer.h +174 -0
  140. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer_test.cc +220 -0
  141. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer.cc +98 -0
  142. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer.h +292 -0
  143. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer_test.cc +233 -0
  144. package/third_party/s2geometry/src/s2/s2builderutil_snap_functions.cc +354 -0
  145. package/third_party/s2geometry/src/s2/s2builderutil_snap_functions.h +239 -0
  146. package/third_party/s2geometry/src/s2/s2builderutil_snap_functions_test.cc +716 -0
  147. package/third_party/s2geometry/src/s2/s2builderutil_testing.cc +37 -0
  148. package/third_party/s2geometry/src/s2/s2builderutil_testing.h +100 -0
  149. package/third_party/s2geometry/src/s2/s2builderutil_testing_test.cc +85 -0
  150. package/third_party/s2geometry/src/s2/s2cap.cc +347 -0
  151. package/third_party/s2geometry/src/s2/s2cap.h +286 -0
  152. package/third_party/s2geometry/src/s2/s2cap_test.cc +379 -0
  153. package/third_party/s2geometry/src/s2/s2cell.cc +552 -0
  154. package/third_party/s2geometry/src/s2/s2cell.h +249 -0
  155. package/third_party/s2geometry/src/s2/s2cell_id.cc +619 -0
  156. package/third_party/s2geometry/src/s2/s2cell_id.h +705 -0
  157. package/third_party/s2geometry/src/s2/s2cell_id_test.cc +633 -0
  158. package/third_party/s2geometry/src/s2/s2cell_index.cc +149 -0
  159. package/third_party/s2geometry/src/s2/s2cell_index.h +660 -0
  160. package/third_party/s2geometry/src/s2/s2cell_index_test.cc +411 -0
  161. package/third_party/s2geometry/src/s2/s2cell_test.cc +687 -0
  162. package/third_party/s2geometry/src/s2/s2cell_union.cc +515 -0
  163. package/third_party/s2geometry/src/s2/s2cell_union.h +399 -0
  164. package/third_party/s2geometry/src/s2/s2cell_union_test.cc +598 -0
  165. package/third_party/s2geometry/src/s2/s2centroids.cc +84 -0
  166. package/third_party/s2geometry/src/s2/s2centroids.h +87 -0
  167. package/third_party/s2geometry/src/s2/s2centroids_test.cc +82 -0
  168. package/third_party/s2geometry/src/s2/s2closest_cell_query.cc +123 -0
  169. package/third_party/s2geometry/src/s2/s2closest_cell_query.h +385 -0
  170. package/third_party/s2geometry/src/s2/s2closest_cell_query_base.h +841 -0
  171. package/third_party/s2geometry/src/s2/s2closest_cell_query_base_test.cc +63 -0
  172. package/third_party/s2geometry/src/s2/s2closest_cell_query_test.cc +412 -0
  173. package/third_party/s2geometry/src/s2/s2closest_edge_query.cc +106 -0
  174. package/third_party/s2geometry/src/s2/s2closest_edge_query.h +421 -0
  175. package/third_party/s2geometry/src/s2/s2closest_edge_query_base.h +946 -0
  176. package/third_party/s2geometry/src/s2/s2closest_edge_query_base_test.cc +59 -0
  177. package/third_party/s2geometry/src/s2/s2closest_edge_query_test.cc +505 -0
  178. package/third_party/s2geometry/src/s2/s2closest_edge_query_testing.h +91 -0
  179. package/third_party/s2geometry/src/s2/s2closest_point_query.cc +66 -0
  180. package/third_party/s2geometry/src/s2/s2closest_point_query.h +465 -0
  181. package/third_party/s2geometry/src/s2/s2closest_point_query_base.h +767 -0
  182. package/third_party/s2geometry/src/s2/s2closest_point_query_base_test.cc +63 -0
  183. package/third_party/s2geometry/src/s2/s2closest_point_query_test.cc +312 -0
  184. package/third_party/s2geometry/src/s2/s2contains_point_query.h +328 -0
  185. package/third_party/s2geometry/src/s2/s2contains_point_query_test.cc +159 -0
  186. package/third_party/s2geometry/src/s2/s2contains_vertex_query.cc +39 -0
  187. package/third_party/s2geometry/src/s2/s2contains_vertex_query.h +66 -0
  188. package/third_party/s2geometry/src/s2/s2contains_vertex_query_test.cc +67 -0
  189. package/third_party/s2geometry/src/s2/s2convex_hull_query.cc +198 -0
  190. package/third_party/s2geometry/src/s2/s2convex_hull_query.h +110 -0
  191. package/third_party/s2geometry/src/s2/s2convex_hull_query_test.cc +208 -0
  192. package/third_party/s2geometry/src/s2/s2coords.cc +146 -0
  193. package/third_party/s2geometry/src/s2/s2coords.h +459 -0
  194. package/third_party/s2geometry/src/s2/s2coords_internal.h +71 -0
  195. package/third_party/s2geometry/src/s2/s2coords_test.cc +218 -0
  196. package/third_party/s2geometry/src/s2/s2crossing_edge_query.cc +380 -0
  197. package/third_party/s2geometry/src/s2/s2crossing_edge_query.h +220 -0
  198. package/third_party/s2geometry/src/s2/s2crossing_edge_query_test.cc +382 -0
  199. package/third_party/s2geometry/src/s2/s2debug.cc +23 -0
  200. package/third_party/s2geometry/src/s2/s2debug.h +69 -0
  201. package/third_party/s2geometry/src/s2/s2distance_target.h +165 -0
  202. package/third_party/s2geometry/src/s2/s2earth.cc +52 -0
  203. package/third_party/s2geometry/src/s2/s2earth.h +268 -0
  204. package/third_party/s2geometry/src/s2/s2earth_test.cc +146 -0
  205. package/third_party/s2geometry/src/s2/s2edge_clipping.cc +462 -0
  206. package/third_party/s2geometry/src/s2/s2edge_clipping.h +183 -0
  207. package/third_party/s2geometry/src/s2/s2edge_clipping_test.cc +335 -0
  208. package/third_party/s2geometry/src/s2/s2edge_crosser.cc +85 -0
  209. package/third_party/s2geometry/src/s2/s2edge_crosser.h +343 -0
  210. package/third_party/s2geometry/src/s2/s2edge_crosser_test.cc +264 -0
  211. package/third_party/s2geometry/src/s2/s2edge_crossings.cc +515 -0
  212. package/third_party/s2geometry/src/s2/s2edge_crossings.h +138 -0
  213. package/third_party/s2geometry/src/s2/s2edge_crossings_internal.h +59 -0
  214. package/third_party/s2geometry/src/s2/s2edge_crossings_test.cc +246 -0
  215. package/third_party/s2geometry/src/s2/s2edge_distances.cc +419 -0
  216. package/third_party/s2geometry/src/s2/s2edge_distances.h +192 -0
  217. package/third_party/s2geometry/src/s2/s2edge_distances_test.cc +539 -0
  218. package/third_party/s2geometry/src/s2/s2edge_tessellator.cc +276 -0
  219. package/third_party/s2geometry/src/s2/s2edge_tessellator.h +101 -0
  220. package/third_party/s2geometry/src/s2/s2edge_tessellator_test.cc +492 -0
  221. package/third_party/s2geometry/src/s2/s2edge_vector_shape.h +85 -0
  222. package/third_party/s2geometry/src/s2/s2edge_vector_shape_test.cc +66 -0
  223. package/third_party/s2geometry/src/s2/s2error.cc +29 -0
  224. package/third_party/s2geometry/src/s2/s2error.h +147 -0
  225. package/third_party/s2geometry/src/s2/s2error_test.cc +31 -0
  226. package/third_party/s2geometry/src/s2/s2furthest_edge_query.cc +117 -0
  227. package/third_party/s2geometry/src/s2/s2furthest_edge_query.h +439 -0
  228. package/third_party/s2geometry/src/s2/s2furthest_edge_query_test.cc +487 -0
  229. package/third_party/s2geometry/src/s2/s2latlng.cc +90 -0
  230. package/third_party/s2geometry/src/s2/s2latlng.h +234 -0
  231. package/third_party/s2geometry/src/s2/s2latlng_rect.cc +727 -0
  232. package/third_party/s2geometry/src/s2/s2latlng_rect.h +434 -0
  233. package/third_party/s2geometry/src/s2/s2latlng_rect_bounder.cc +344 -0
  234. package/third_party/s2geometry/src/s2/s2latlng_rect_bounder.h +89 -0
  235. package/third_party/s2geometry/src/s2/s2latlng_rect_bounder_test.cc +306 -0
  236. package/third_party/s2geometry/src/s2/s2latlng_rect_test.cc +1030 -0
  237. package/third_party/s2geometry/src/s2/s2latlng_test.cc +165 -0
  238. package/third_party/s2geometry/src/s2/s2lax_loop_shape.cc +104 -0
  239. package/third_party/s2geometry/src/s2/s2lax_loop_shape.h +153 -0
  240. package/third_party/s2geometry/src/s2/s2lax_loop_shape_test.cc +101 -0
  241. package/third_party/s2geometry/src/s2/s2lax_polygon_shape.cc +348 -0
  242. package/third_party/s2geometry/src/s2/s2lax_polygon_shape.h +183 -0
  243. package/third_party/s2geometry/src/s2/s2lax_polygon_shape_test.cc +234 -0
  244. package/third_party/s2geometry/src/s2/s2lax_polyline_shape.cc +118 -0
  245. package/third_party/s2geometry/src/s2/s2lax_polyline_shape.h +124 -0
  246. package/third_party/s2geometry/src/s2/s2lax_polyline_shape_test.cc +62 -0
  247. package/third_party/s2geometry/src/s2/s2loop.cc +1509 -0
  248. package/third_party/s2geometry/src/s2/s2loop.h +711 -0
  249. package/third_party/s2geometry/src/s2/s2loop_measures.cc +313 -0
  250. package/third_party/s2geometry/src/s2/s2loop_measures.h +280 -0
  251. package/third_party/s2geometry/src/s2/s2loop_measures_test.cc +367 -0
  252. package/third_party/s2geometry/src/s2/s2loop_test.cc +1371 -0
  253. package/third_party/s2geometry/src/s2/s2max_distance_targets.cc +265 -0
  254. package/third_party/s2geometry/src/s2/s2max_distance_targets.h +241 -0
  255. package/third_party/s2geometry/src/s2/s2max_distance_targets_test.cc +367 -0
  256. package/third_party/s2geometry/src/s2/s2measures.cc +128 -0
  257. package/third_party/s2geometry/src/s2/s2measures.h +78 -0
  258. package/third_party/s2geometry/src/s2/s2measures_test.cc +135 -0
  259. package/third_party/s2geometry/src/s2/s2metrics.cc +122 -0
  260. package/third_party/s2geometry/src/s2/s2metrics.h +199 -0
  261. package/third_party/s2geometry/src/s2/s2metrics_test.cc +127 -0
  262. package/third_party/s2geometry/src/s2/s2min_distance_targets.cc +295 -0
  263. package/third_party/s2geometry/src/s2/s2min_distance_targets.h +273 -0
  264. package/third_party/s2geometry/src/s2/s2min_distance_targets_test.cc +239 -0
  265. package/third_party/s2geometry/src/s2/s2padded_cell.cc +162 -0
  266. package/third_party/s2geometry/src/s2/s2padded_cell.h +108 -0
  267. package/third_party/s2geometry/src/s2/s2padded_cell_test.cc +138 -0
  268. package/third_party/s2geometry/src/s2/s2point.h +38 -0
  269. package/third_party/s2geometry/src/s2/s2point_compression.cc +388 -0
  270. package/third_party/s2geometry/src/s2/s2point_compression.h +78 -0
  271. package/third_party/s2geometry/src/s2/s2point_compression_test.cc +305 -0
  272. package/third_party/s2geometry/src/s2/s2point_index.h +345 -0
  273. package/third_party/s2geometry/src/s2/s2point_index_test.cc +147 -0
  274. package/third_party/s2geometry/src/s2/s2point_region.cc +72 -0
  275. package/third_party/s2geometry/src/s2/s2point_region.h +76 -0
  276. package/third_party/s2geometry/src/s2/s2point_region_test.cc +100 -0
  277. package/third_party/s2geometry/src/s2/s2point_span.h +57 -0
  278. package/third_party/s2geometry/src/s2/s2point_test.cc +47 -0
  279. package/third_party/s2geometry/src/s2/s2point_vector_shape.h +127 -0
  280. package/third_party/s2geometry/src/s2/s2point_vector_shape_test.cc +59 -0
  281. package/third_party/s2geometry/src/s2/s2pointutil.cc +131 -0
  282. package/third_party/s2geometry/src/s2/s2pointutil.h +138 -0
  283. package/third_party/s2geometry/src/s2/s2pointutil_test.cc +157 -0
  284. package/third_party/s2geometry/src/s2/s2polygon.cc +1569 -0
  285. package/third_party/s2geometry/src/s2/s2polygon.h +934 -0
  286. package/third_party/s2geometry/src/s2/s2polygon_test.cc +3025 -0
  287. package/third_party/s2geometry/src/s2/s2polyline.cc +645 -0
  288. package/third_party/s2geometry/src/s2/s2polyline.h +379 -0
  289. package/third_party/s2geometry/src/s2/s2polyline_alignment.cc +414 -0
  290. package/third_party/s2geometry/src/s2/s2polyline_alignment.h +245 -0
  291. package/third_party/s2geometry/src/s2/s2polyline_alignment_internal.h +158 -0
  292. package/third_party/s2geometry/src/s2/s2polyline_alignment_test.cc +610 -0
  293. package/third_party/s2geometry/src/s2/s2polyline_measures.cc +42 -0
  294. package/third_party/s2geometry/src/s2/s2polyline_measures.h +53 -0
  295. package/third_party/s2geometry/src/s2/s2polyline_measures_test.cc +57 -0
  296. package/third_party/s2geometry/src/s2/s2polyline_simplifier.cc +187 -0
  297. package/third_party/s2geometry/src/s2/s2polyline_simplifier.h +109 -0
  298. package/third_party/s2geometry/src/s2/s2polyline_simplifier_test.cc +165 -0
  299. package/third_party/s2geometry/src/s2/s2polyline_test.cc +554 -0
  300. package/third_party/s2geometry/src/s2/s2predicates.cc +1486 -0
  301. package/third_party/s2geometry/src/s2/s2predicates.h +282 -0
  302. package/third_party/s2geometry/src/s2/s2predicates_internal.h +135 -0
  303. package/third_party/s2geometry/src/s2/s2predicates_test.cc +1427 -0
  304. package/third_party/s2geometry/src/s2/s2projections.cc +109 -0
  305. package/third_party/s2geometry/src/s2/s2projections.h +161 -0
  306. package/third_party/s2geometry/src/s2/s2projections_test.cc +78 -0
  307. package/third_party/s2geometry/src/s2/s2r2rect.cc +88 -0
  308. package/third_party/s2geometry/src/s2/s2r2rect.h +292 -0
  309. package/third_party/s2geometry/src/s2/s2r2rect_test.cc +312 -0
  310. package/third_party/s2geometry/src/s2/s2region.cc +26 -0
  311. package/third_party/s2geometry/src/s2/s2region.h +142 -0
  312. package/third_party/s2geometry/src/s2/s2region_coverer.cc +514 -0
  313. package/third_party/s2geometry/src/s2/s2region_coverer.h +356 -0
  314. package/third_party/s2geometry/src/s2/s2region_coverer_test.cc +509 -0
  315. package/third_party/s2geometry/src/s2/s2region_intersection.cc +84 -0
  316. package/third_party/s2geometry/src/s2/s2region_intersection.h +79 -0
  317. package/third_party/s2geometry/src/s2/s2region_term_indexer.cc +270 -0
  318. package/third_party/s2geometry/src/s2/s2region_term_indexer.h +299 -0
  319. package/third_party/s2geometry/src/s2/s2region_term_indexer_test.cc +209 -0
  320. package/third_party/s2geometry/src/s2/s2region_test.cc +370 -0
  321. package/third_party/s2geometry/src/s2/s2region_union.cc +90 -0
  322. package/third_party/s2geometry/src/s2/s2region_union.h +83 -0
  323. package/third_party/s2geometry/src/s2/s2region_union_test.cc +89 -0
  324. package/third_party/s2geometry/src/s2/s2shape.h +283 -0
  325. package/third_party/s2geometry/src/s2/s2shape_index.cc +321 -0
  326. package/third_party/s2geometry/src/s2/s2shape_index.h +781 -0
  327. package/third_party/s2geometry/src/s2/s2shape_index_buffered_region.cc +113 -0
  328. package/third_party/s2geometry/src/s2/s2shape_index_buffered_region.h +135 -0
  329. package/third_party/s2geometry/src/s2/s2shape_index_buffered_region_test.cc +162 -0
  330. package/third_party/s2geometry/src/s2/s2shape_index_measures.cc +92 -0
  331. package/third_party/s2geometry/src/s2/s2shape_index_measures.h +100 -0
  332. package/third_party/s2geometry/src/s2/s2shape_index_measures_test.cc +136 -0
  333. package/third_party/s2geometry/src/s2/s2shape_index_region.h +350 -0
  334. package/third_party/s2geometry/src/s2/s2shape_index_region_test.cc +161 -0
  335. package/third_party/s2geometry/src/s2/s2shape_index_test.cc +24 -0
  336. package/third_party/s2geometry/src/s2/s2shape_measures.cc +138 -0
  337. package/third_party/s2geometry/src/s2/s2shape_measures.h +95 -0
  338. package/third_party/s2geometry/src/s2/s2shape_measures_test.cc +139 -0
  339. package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries.cc +120 -0
  340. package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries.h +66 -0
  341. package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries_test.cc +170 -0
  342. package/third_party/s2geometry/src/s2/s2shapeutil_coding.cc +253 -0
  343. package/third_party/s2geometry/src/s2/s2shapeutil_coding.h +283 -0
  344. package/third_party/s2geometry/src/s2/s2shapeutil_coding_test.cc +54 -0
  345. package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force.cc +40 -0
  346. package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force.h +41 -0
  347. package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force_test.cc +55 -0
  348. package/third_party/s2geometry/src/s2/s2shapeutil_count_edges.h +57 -0
  349. package/third_party/s2geometry/src/s2/s2shapeutil_count_edges_test.cc +43 -0
  350. package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator.cc +45 -0
  351. package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator.h +72 -0
  352. package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator_test.cc +116 -0
  353. package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point.cc +107 -0
  354. package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point.h +48 -0
  355. package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point_test.cc +104 -0
  356. package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator.cc +58 -0
  357. package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator.h +65 -0
  358. package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator_test.cc +61 -0
  359. package/third_party/s2geometry/src/s2/s2shapeutil_shape_edge.h +58 -0
  360. package/third_party/s2geometry/src/s2/s2shapeutil_shape_edge_id.h +97 -0
  361. package/third_party/s2geometry/src/s2/s2shapeutil_testing.cc +104 -0
  362. package/third_party/s2geometry/src/s2/s2shapeutil_testing.h +36 -0
  363. package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs.cc +440 -0
  364. package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs.h +72 -0
  365. package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs_test.cc +184 -0
  366. package/third_party/s2geometry/src/s2/s2testing.cc +464 -0
  367. package/third_party/s2geometry/src/s2/s2testing.h +385 -0
  368. package/third_party/s2geometry/src/s2/s2testing_test.cc +166 -0
  369. package/third_party/s2geometry/src/s2/s2text_format.cc +506 -0
  370. package/third_party/s2geometry/src/s2/s2text_format.h +289 -0
  371. package/third_party/s2geometry/src/s2/s2text_format_test.cc +417 -0
  372. package/third_party/s2geometry/src/s2/s2wedge_relations.cc +80 -0
  373. package/third_party/s2geometry/src/s2/s2wedge_relations.h +64 -0
  374. package/third_party/s2geometry/src/s2/s2wedge_relations_test.cc +89 -0
  375. package/third_party/s2geometry/src/s2/sequence_lexicon.h +296 -0
  376. package/third_party/s2geometry/src/s2/sequence_lexicon_test.cc +113 -0
  377. package/third_party/s2geometry/src/s2/strings/ostringstream.cc +35 -0
  378. package/third_party/s2geometry/src/s2/strings/ostringstream.h +105 -0
  379. package/third_party/s2geometry/src/s2/strings/serialize.cc +46 -0
  380. package/third_party/s2geometry/src/s2/strings/serialize.h +40 -0
  381. package/third_party/s2geometry/src/s2/third_party/absl/algorithm/algorithm.h +187 -0
  382. package/third_party/s2geometry/src/s2/third_party/absl/base/attributes.h +666 -0
  383. package/third_party/s2geometry/src/s2/third_party/absl/base/casts.h +189 -0
  384. package/third_party/s2geometry/src/s2/third_party/absl/base/config.h +462 -0
  385. package/third_party/s2geometry/src/s2/third_party/absl/base/dynamic_annotations.cc +129 -0
  386. package/third_party/s2geometry/src/s2/third_party/absl/base/dynamic_annotations.h +394 -0
  387. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/atomic_hook.h +168 -0
  388. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/identity.h +33 -0
  389. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/inline_variable.h +117 -0
  390. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/invoke.h +188 -0
  391. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/raw_logging.cc +254 -0
  392. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/raw_logging.h +205 -0
  393. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/throw_delegate.cc +106 -0
  394. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/throw_delegate.h +71 -0
  395. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/unaligned_access.h +322 -0
  396. package/third_party/s2geometry/src/s2/third_party/absl/base/log_severity.h +77 -0
  397. package/third_party/s2geometry/src/s2/third_party/absl/base/macros.h +236 -0
  398. package/third_party/s2geometry/src/s2/third_party/absl/base/optimization.h +177 -0
  399. package/third_party/s2geometry/src/s2/third_party/absl/base/policy_checks.h +124 -0
  400. package/third_party/s2geometry/src/s2/third_party/absl/base/port.h +97 -0
  401. package/third_party/s2geometry/src/s2/third_party/absl/base/thread_annotations.h +277 -0
  402. package/third_party/s2geometry/src/s2/third_party/absl/container/fixed_array.h +523 -0
  403. package/third_party/s2geometry/src/s2/third_party/absl/container/inlined_vector.h +1453 -0
  404. package/third_party/s2geometry/src/s2/third_party/absl/container/internal/compressed_tuple.h +191 -0
  405. package/third_party/s2geometry/src/s2/third_party/absl/container/internal/container_memory.h +424 -0
  406. package/third_party/s2geometry/src/s2/third_party/absl/container/internal/layout.h +739 -0
  407. package/third_party/s2geometry/src/s2/third_party/absl/memory/memory.h +755 -0
  408. package/third_party/s2geometry/src/s2/third_party/absl/meta/type_traits.h +436 -0
  409. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128.cc +232 -0
  410. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128.h +656 -0
  411. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128_have_intrinsic.inc +3 -0
  412. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128_no_intrinsic.inc +3 -0
  413. package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii.cc +198 -0
  414. package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii.h +239 -0
  415. package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii_ctype.h +66 -0
  416. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/bits.h +53 -0
  417. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/memutil.cc +110 -0
  418. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/memutil.h +146 -0
  419. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/resize_uninitialized.h +72 -0
  420. package/third_party/s2geometry/src/s2/third_party/absl/strings/match.cc +38 -0
  421. package/third_party/s2geometry/src/s2/third_party/absl/strings/match.h +89 -0
  422. package/third_party/s2geometry/src/s2/third_party/absl/strings/numbers.cc +909 -0
  423. package/third_party/s2geometry/src/s2/third_party/absl/strings/numbers.h +187 -0
  424. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_cat.cc +240 -0
  425. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_cat.h +398 -0
  426. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_join.h +22 -0
  427. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_split.cc +47 -0
  428. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_split.h +43 -0
  429. package/third_party/s2geometry/src/s2/third_party/absl/strings/string_view.cc +245 -0
  430. package/third_party/s2geometry/src/s2/third_party/absl/strings/string_view.h +602 -0
  431. package/third_party/s2geometry/src/s2/third_party/absl/strings/strip.cc +42 -0
  432. package/third_party/s2geometry/src/s2/third_party/absl/strings/strip.h +130 -0
  433. package/third_party/s2geometry/src/s2/third_party/absl/types/span.h +793 -0
  434. package/third_party/s2geometry/src/s2/third_party/absl/utility/utility.h +299 -0
  435. package/third_party/s2geometry/src/s2/util/bits/bit-interleave.cc +274 -0
  436. package/third_party/s2geometry/src/s2/util/bits/bit-interleave.h +53 -0
  437. package/third_party/s2geometry/src/s2/util/bits/bits.cc +155 -0
  438. package/third_party/s2geometry/src/s2/util/bits/bits.h +745 -0
  439. package/third_party/s2geometry/src/s2/util/coding/coder.cc +83 -0
  440. package/third_party/s2geometry/src/s2/util/coding/coder.h +553 -0
  441. package/third_party/s2geometry/src/s2/util/coding/nth-derivative.h +134 -0
  442. package/third_party/s2geometry/src/s2/util/coding/transforms.h +62 -0
  443. package/third_party/s2geometry/src/s2/util/coding/varint.cc +289 -0
  444. package/third_party/s2geometry/src/s2/util/coding/varint.h +476 -0
  445. package/third_party/s2geometry/src/s2/util/endian/endian.h +859 -0
  446. package/third_party/s2geometry/src/s2/util/gtl/btree.h +2471 -0
  447. package/third_party/s2geometry/src/s2/util/gtl/btree_container.h +411 -0
  448. package/third_party/s2geometry/src/s2/util/gtl/btree_map.h +79 -0
  449. package/third_party/s2geometry/src/s2/util/gtl/btree_set.h +73 -0
  450. package/third_party/s2geometry/src/s2/util/gtl/compact_array.h +653 -0
  451. package/third_party/s2geometry/src/s2/util/gtl/container_logging.h +291 -0
  452. package/third_party/s2geometry/src/s2/util/gtl/dense_hash_set.h +358 -0
  453. package/third_party/s2geometry/src/s2/util/gtl/densehashtable.h +1493 -0
  454. package/third_party/s2geometry/src/s2/util/gtl/hashtable_common.h +253 -0
  455. package/third_party/s2geometry/src/s2/util/gtl/layout.h +28 -0
  456. package/third_party/s2geometry/src/s2/util/gtl/legacy_random_shuffle.h +77 -0
  457. package/third_party/s2geometry/src/s2/util/hash/mix.h +76 -0
  458. package/third_party/s2geometry/src/s2/util/math/exactfloat/exactfloat.cc +832 -0
  459. package/third_party/s2geometry/src/s2/util/math/exactfloat/exactfloat.h +646 -0
  460. package/third_party/s2geometry/src/s2/util/math/mathutil.cc +75 -0
  461. package/third_party/s2geometry/src/s2/util/math/mathutil.h +189 -0
  462. package/third_party/s2geometry/src/s2/util/math/matrix3x3.h +574 -0
  463. package/third_party/s2geometry/src/s2/util/math/vector.h +569 -0
  464. package/third_party/s2geometry/src/s2/util/math/vector3_hash.h +54 -0
  465. package/third_party/s2geometry/src/s2/util/units/length-units.cc +21 -0
  466. package/third_party/s2geometry/src/s2/util/units/length-units.h +135 -0
  467. package/third_party/s2geometry/src/s2/util/units/physical-units.h +313 -0
  468. package/third_party/s2geometry/src/s2/value_lexicon.h +234 -0
  469. package/third_party/s2geometry/src/s2/value_lexicon_test.cc +121 -0
  470. package/third_party/s2geometry/third_party/cmake/FindGFlags.cmake +48 -0
  471. package/third_party/s2geometry/third_party/cmake/FindGlog.cmake +48 -0
@@ -0,0 +1,598 @@
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/s2cell_union.h"
19
+
20
+ #include <algorithm>
21
+ #include <cmath>
22
+ #include <cstdio>
23
+ #include <vector>
24
+
25
+ #include <gtest/gtest.h>
26
+
27
+ #include "s2/base/integral_types.h"
28
+ #include "s2/base/logging.h"
29
+ #include "s2/s1angle.h"
30
+ #include "s2/s2cap.h"
31
+ #include "s2/s2cell.h"
32
+ #include "s2/s2cell_id.h"
33
+ #include "s2/s2edge_distances.h"
34
+ #include "s2/s2metrics.h"
35
+ #include "s2/s2region_coverer.h"
36
+ #include "s2/s2testing.h"
37
+ #include "s2/third_party/absl/strings/str_cat.h"
38
+ #include "s2/util/coding/coder.h"
39
+
40
+ S2_DECLARE_bool(s2debug);
41
+
42
+ using absl::StrCat;
43
+ using std::max;
44
+ using std::min;
45
+ using std::vector;
46
+
47
+ class S2CellUnionTestPeer {
48
+ public:
49
+ // Creates a possibly invalid S2CellUnion without any checks.
50
+ static S2CellUnion FromVerbatimNoChecks(vector<S2CellId> cell_ids) {
51
+ return S2CellUnion(std::move(cell_ids), S2CellUnion::VERBATIM);
52
+ }
53
+ };
54
+
55
+ TEST(S2CellUnion, DefaultConstructor) {
56
+ vector<S2CellId> ids;
57
+ S2CellUnion empty(ids);
58
+ EXPECT_TRUE(empty.empty());
59
+ }
60
+
61
+ TEST(S2CellUnion, S2CellIdConstructor) {
62
+ S2CellId face1_id = S2CellId::FromFace(1);
63
+ S2CellUnion face1_union({face1_id});
64
+ EXPECT_EQ(1, face1_union.num_cells());
65
+ EXPECT_EQ(face1_id, face1_union.cell_id(0));
66
+ }
67
+
68
+ TEST(S2CellUnion, WholeSphere) {
69
+ S2CellUnion whole_sphere = S2CellUnion::WholeSphere();
70
+ EXPECT_EQ(whole_sphere.LeafCellsCovered(), 6 * (1ULL << 60));
71
+ whole_sphere.Expand(0);
72
+ EXPECT_EQ(whole_sphere, S2CellUnion::WholeSphere());
73
+ }
74
+
75
+ TEST(S2CellUnion, DuplicateCellsNotValid) {
76
+ S2CellId id = S2CellId(S2Point(1, 0, 0));
77
+ auto cell_union = S2CellUnionTestPeer::FromVerbatimNoChecks(
78
+ vector<S2CellId>{id, id});
79
+ EXPECT_FALSE(cell_union.IsValid());
80
+ }
81
+
82
+ TEST(S2CellUnion, UnsortedCellsNotValid) {
83
+ S2CellId id = S2CellId(S2Point(1, 0, 0)).parent(10);
84
+ auto cell_union = S2CellUnionTestPeer::FromVerbatimNoChecks(
85
+ vector<S2CellId>{id, id.prev()});
86
+ EXPECT_FALSE(cell_union.IsValid());
87
+ }
88
+
89
+ TEST(S2CellUnion, InvalidCellIdNotValid) {
90
+ ASSERT_FALSE(S2CellId::None().is_valid());
91
+ auto cell_union =
92
+ S2CellUnionTestPeer::FromVerbatimNoChecks({S2CellId::None()});
93
+ EXPECT_FALSE(cell_union.IsValid());
94
+ }
95
+
96
+ TEST(S2CellUnion, InvalidCellIdNotValidWithDebugFlag) {
97
+ // Manually save and restore flag, to preserve test state in opensource
98
+ // without gflags.
99
+ const bool saved_s2debug = FLAGS_s2debug;
100
+ FLAGS_s2debug = false;
101
+ ASSERT_FALSE(S2CellId::None().is_valid());
102
+ auto cell_union = S2CellUnion::FromVerbatim({S2CellId::None()});
103
+ EXPECT_FALSE(cell_union.IsValid());
104
+ FLAGS_s2debug = saved_s2debug;
105
+ }
106
+
107
+ TEST(S2CellUnion, IsNormalized) {
108
+ S2CellId id = S2CellId(S2Point(1, 0, 0)).parent(10);
109
+ auto cell_union = S2CellUnion::FromVerbatim(
110
+ vector<S2CellId>{id.child(0), id.child(1), id.child(2), id.child(3)});
111
+ EXPECT_TRUE(cell_union.IsValid());
112
+ EXPECT_FALSE(cell_union.IsNormalized());
113
+ }
114
+
115
+ static S2Testing::Random& rnd = S2Testing::rnd;
116
+
117
+ static void AddCells(S2CellId id, bool selected,
118
+ vector<S2CellId> *input, vector<S2CellId> *expected) {
119
+ // Decides whether to add "id" and/or some of its descendants to the
120
+ // test case. If "selected" is true, then the region covered by "id"
121
+ // *must* be added to the test case (either by adding "id" itself, or
122
+ // some combination of its descendants, or both). If cell ids are to
123
+ // the test case "input", then the corresponding expected result after
124
+ // simplification is added to "expected".
125
+
126
+ if (id == S2CellId::None()) {
127
+ // Initial call: decide whether to add cell(s) from each face.
128
+ for (int face = 0; face < 6; ++face) {
129
+ AddCells(S2CellId::FromFace(face), false, input, expected);
130
+ }
131
+ return;
132
+ }
133
+ if (id.is_leaf()) {
134
+ // The rnd.OneIn() call below ensures that the parent of a leaf cell
135
+ // will always be selected (if we make it that far down the hierarchy).
136
+ S2_DCHECK(selected);
137
+ input->push_back(id);
138
+ return;
139
+ }
140
+ // The following code ensures that the probability of selecting a cell
141
+ // at each level is approximately the same, i.e. we test normalization
142
+ // of cells at all levels.
143
+ if (!selected && rnd.OneIn(S2CellId::kMaxLevel - id.level())) {
144
+ // Once a cell has been selected, the expected output is predetermined.
145
+ // We then make sure that cells are selected that will normalize to
146
+ // the desired output.
147
+ expected->push_back(id);
148
+ selected = true;
149
+ }
150
+
151
+ // With the rnd.OneIn() constants below, this function adds an average
152
+ // of 5/6 * (kMaxLevel - level) cells to "input" where "level" is the
153
+ // level at which the cell was first selected (level 15 on average).
154
+ // Therefore the average number of input cells in a test case is about
155
+ // (5/6 * 15 * 6) = 75. The average number of output cells is about 6.
156
+
157
+ // If a cell is selected, we add it to "input" with probability 5/6.
158
+ bool added = false;
159
+ if (selected && !rnd.OneIn(6)) {
160
+ input->push_back(id);
161
+ added = true;
162
+ }
163
+ int num_children = 0;
164
+ S2CellId child = id.child_begin();
165
+ for (int pos = 0; pos < 4; ++pos, child = child.next()) {
166
+ // If the cell is selected, on average we recurse on 4/12 = 1/3 child.
167
+ // This intentionally may result in a cell and some of its children
168
+ // being included in the test case.
169
+ //
170
+ // If the cell is not selected, on average we recurse on one child.
171
+ // We also make sure that we do not recurse on all 4 children, since
172
+ // then we might include all 4 children in the input case by accident
173
+ // (in which case the expected output would not be correct).
174
+ if (rnd.OneIn(selected ? 12 : 4) && num_children < 3) {
175
+ AddCells(child, selected, input, expected);
176
+ ++num_children;
177
+ }
178
+ // If this cell was selected but the cell itself was not added, we
179
+ // must ensure that all 4 children (or some combination of their
180
+ // descendants) are added.
181
+ if (selected && !added) AddCells(child, selected, input, expected);
182
+ }
183
+ }
184
+
185
+ TEST(S2CellUnion, Normalize) {
186
+ // Try a bunch of random test cases, and keep track of average
187
+ // statistics for normalization (to see if they agree with the
188
+ // analysis above).
189
+ double in_sum = 0, out_sum = 0;
190
+ static const int kIters = 2000;
191
+ for (int i = 0; i < kIters; ++i) {
192
+ vector<S2CellId> input, expected;
193
+ AddCells(S2CellId::None(), false, &input, &expected);
194
+ in_sum += input.size();
195
+ out_sum += expected.size();
196
+ S2CellUnion cellunion(input);
197
+ EXPECT_EQ(expected.size(), cellunion.size());
198
+ for (int i = 0; i < expected.size(); ++i) {
199
+ EXPECT_EQ(expected[i], cellunion[i]);
200
+ }
201
+
202
+ // Test GetCapBound().
203
+ S2Cap cap = cellunion.GetCapBound();
204
+ for (S2CellId id : cellunion) {
205
+ EXPECT_TRUE(cap.Contains(S2Cell(id)));
206
+ }
207
+
208
+ // Test Contains(S2CellId) and Intersects(S2CellId).
209
+ for (S2CellId input_id : input) {
210
+ EXPECT_TRUE(cellunion.Contains(input_id));
211
+ EXPECT_TRUE(cellunion.Contains(input_id.ToPoint()));
212
+ EXPECT_TRUE(cellunion.Intersects(input_id));
213
+ if (!input_id.is_face()) {
214
+ EXPECT_TRUE(cellunion.Intersects(input_id.parent()));
215
+ if (input_id.level() > 1) {
216
+ EXPECT_TRUE(cellunion.Intersects(input_id.parent().parent()));
217
+ EXPECT_TRUE(cellunion.Intersects(input_id.parent(0)));
218
+ }
219
+ }
220
+ if (!input_id.is_leaf()) {
221
+ EXPECT_TRUE(cellunion.Contains(input_id.child_begin()));
222
+ EXPECT_TRUE(cellunion.Intersects(input_id.child_begin()));
223
+ EXPECT_TRUE(cellunion.Contains(input_id.child_end().prev()));
224
+ EXPECT_TRUE(cellunion.Intersects(input_id.child_end().prev()));
225
+ EXPECT_TRUE(cellunion.Contains(
226
+ input_id.child_begin(S2CellId::kMaxLevel)));
227
+ EXPECT_TRUE(cellunion.Intersects(
228
+ input_id.child_begin(S2CellId::kMaxLevel)));
229
+ }
230
+ }
231
+ for (S2CellId expected_id : expected) {
232
+ if (!expected_id.is_face()) {
233
+ EXPECT_TRUE(!cellunion.Contains(expected_id.parent()));
234
+ EXPECT_TRUE(!cellunion.Contains(expected_id.parent(0)));
235
+ }
236
+ }
237
+
238
+ // Test Contains(S2CellUnion), Intersects(S2CellUnion), Union(),
239
+ // Intersection(), and Difference().
240
+ vector<S2CellId> x, y, x_or_y, x_and_y;
241
+ for (S2CellId input_id : input) {
242
+ bool in_x = rnd.OneIn(2);
243
+ bool in_y = rnd.OneIn(2);
244
+ if (in_x) x.push_back(input_id);
245
+ if (in_y) y.push_back(input_id);
246
+ if (in_x || in_y) x_or_y.push_back(input_id);
247
+ }
248
+ S2CellUnion xcells(std::move(x));
249
+ S2CellUnion ycells(std::move(y));
250
+ S2CellUnion x_or_y_expected(std::move(x_or_y));
251
+ S2CellUnion x_or_y_cells = xcells.Union(ycells);
252
+ EXPECT_TRUE(x_or_y_cells == x_or_y_expected);
253
+
254
+ // Compute the intersection of "x" with each cell of "y",
255
+ // check that this intersection is correct, and append the
256
+ // results to x_and_y_expected.
257
+ for (S2CellId yid : ycells) {
258
+ S2CellUnion ucells = xcells.Intersection(yid);
259
+ for (S2CellId xid : xcells) {
260
+ if (xid.contains(yid)) {
261
+ EXPECT_TRUE(ucells.size() == 1 && ucells[0] == yid);
262
+ } else if (yid.contains(xid)) {
263
+ EXPECT_TRUE(ucells.Contains(xid));
264
+ }
265
+ }
266
+ for (S2CellId uid : ucells) {
267
+ EXPECT_TRUE(xcells.Contains(uid));
268
+ EXPECT_TRUE(yid.contains(uid));
269
+ }
270
+ x_and_y.insert(x_and_y.end(), ucells.begin(), ucells.end());
271
+ }
272
+ S2CellUnion x_and_y_expected(std::move(x_and_y));
273
+ S2CellUnion x_and_y_cells = xcells.Intersection(ycells);
274
+ EXPECT_TRUE(x_and_y_cells == x_and_y_expected);
275
+
276
+ S2CellUnion x_minus_y_cells = xcells.Difference(ycells);
277
+ S2CellUnion y_minus_x_cells = ycells.Difference(xcells);
278
+ EXPECT_TRUE(xcells.Contains(x_minus_y_cells));
279
+ EXPECT_TRUE(!x_minus_y_cells.Intersects(ycells));
280
+ EXPECT_TRUE(ycells.Contains(y_minus_x_cells));
281
+ EXPECT_TRUE(!y_minus_x_cells.Intersects(xcells));
282
+ EXPECT_TRUE(!x_minus_y_cells.Intersects(y_minus_x_cells));
283
+
284
+ S2CellUnion diff_intersection_union =
285
+ x_minus_y_cells.Union(y_minus_x_cells).Union(x_and_y_cells);
286
+ EXPECT_TRUE(diff_intersection_union == x_or_y_cells);
287
+
288
+ vector<S2CellId> test, dummy;
289
+ AddCells(S2CellId::None(), false, &test, &dummy);
290
+ for (S2CellId test_id : test) {
291
+ bool contains = false, intersects = false;
292
+ for (S2CellId expected_id : expected) {
293
+ if (expected_id.contains(test_id)) contains = true;
294
+ if (expected_id.intersects(test_id)) intersects = true;
295
+ }
296
+ EXPECT_EQ(contains, cellunion.Contains(test_id));
297
+ EXPECT_EQ(intersects, cellunion.Intersects(test_id));
298
+ }
299
+ }
300
+ printf("avg in %.2f, avg out %.2f\n", in_sum / kIters, out_sum / kIters);
301
+ }
302
+
303
+ // Return the maximum geodesic distance from "axis" to any point of
304
+ // "covering".
305
+ static double GetRadius(const S2CellUnion& covering, const S2Point& axis) {
306
+ double max_dist = 0;
307
+ for (S2CellId id : covering) {
308
+ S2Cell cell(id);
309
+ for (int j = 0; j < 4; ++j) {
310
+ S2Point a = cell.GetVertex(j);
311
+ S2Point b = cell.GetVertex(j + 1);
312
+ double dist;
313
+ // The maximum distance is not always attained at a cell vertex: if at
314
+ // least one vertex is in the opposite hemisphere from "axis" then the
315
+ // maximum may be attained along an edge. We solve this by computing
316
+ // the minimum distance from the edge to (-axis) instead. We can't
317
+ // simply do this all the time because S2::GetDistance() has
318
+ // poor accuracy when the result is close to Pi.
319
+ //
320
+ // TODO(ericv): Improve S2::GetDistance() accuracy near Pi.
321
+ if (a.Angle(axis) > M_PI_2 || b.Angle(axis) > M_PI_2) {
322
+ dist = M_PI - S2::GetDistance(-axis, a, b).radians();
323
+ } else {
324
+ dist = a.Angle(axis);
325
+ }
326
+ max_dist = max(max_dist, dist);
327
+ }
328
+ }
329
+ return max_dist;
330
+ }
331
+
332
+ TEST(S2CellUnion, Expand) {
333
+ // This test generates coverings for caps of random sizes, expands
334
+ // the coverings by a random radius, and then make sure that the new
335
+ // covering covers the expanded cap. It also makes sure that the
336
+ // new covering is not too much larger than expected.
337
+
338
+ S2RegionCoverer coverer;
339
+ for (int i = 0; i < 1000; ++i) {
340
+ SCOPED_TRACE(StrCat("Iteration ", i));
341
+ S2Cap cap = S2Testing::GetRandomCap(
342
+ S2Cell::AverageArea(S2CellId::kMaxLevel), 4 * M_PI);
343
+
344
+ // Expand the cap area by a random factor whose log is uniformly
345
+ // distributed between 0 and log(1e2).
346
+ S2Cap expanded_cap = S2Cap::FromCenterHeight(
347
+ cap.center(), min(2.0, pow(1e2, rnd.RandDouble()) * cap.height()));
348
+
349
+ double radius = (expanded_cap.GetRadius() - cap.GetRadius()).radians();
350
+ int max_level_diff = rnd.Uniform(8);
351
+
352
+ // Generate a covering for the original cap, and measure the maximum
353
+ // distance from the cap center to any point in the covering.
354
+ coverer.mutable_options()->set_max_cells(1 + rnd.Skewed(10));
355
+ S2CellUnion covering = coverer.GetCovering(cap);
356
+ S2Testing::CheckCovering(cap, covering, true);
357
+ double covering_radius = GetRadius(covering, cap.center());
358
+
359
+ // This code duplicates the logic in Expand(min_radius, max_level_diff)
360
+ // that figures out an appropriate cell level to use for the expansion.
361
+ int min_level = S2CellId::kMaxLevel;
362
+ for (S2CellId id : covering) {
363
+ min_level = min(min_level, id.level());
364
+ }
365
+ int expand_level = min(min_level + max_level_diff,
366
+ S2::kMinWidth.GetLevelForMinValue(radius));
367
+
368
+ // Generate a covering for the expanded cap, and measure the new maximum
369
+ // distance from the cap center to any point in the covering.
370
+ covering.Expand(S1Angle::Radians(radius), max_level_diff);
371
+ S2Testing::CheckCovering(expanded_cap, covering, false);
372
+ double expanded_covering_radius = GetRadius(covering, cap.center());
373
+
374
+ // If the covering includes a tiny cell along the boundary, in theory the
375
+ // maximum angle of the covering from the cap center can increase by up to
376
+ // twice the maximum length of a cell diagonal.
377
+ EXPECT_LE(expanded_covering_radius - covering_radius,
378
+ 2 * S2::kMaxDiag.GetValue(expand_level));
379
+ }
380
+ }
381
+
382
+ TEST(S2CellUnion, EncodeDecode) {
383
+ vector<S2CellId> cell_ids = {S2CellId(0x33),
384
+ S2CellId(0x8e3748fab),
385
+ S2CellId(0x91230abcdef83427)};
386
+ auto cell_union = S2CellUnion::FromVerbatim(std::move(cell_ids));
387
+
388
+ Encoder encoder;
389
+ cell_union.Encode(&encoder);
390
+ Decoder decoder(encoder.base(), encoder.length());
391
+ S2CellUnion decoded_cell_union;
392
+ EXPECT_TRUE(decoded_cell_union.Decode(&decoder));
393
+ EXPECT_EQ(cell_union, decoded_cell_union);
394
+ }
395
+
396
+ TEST(S2CellUnion, EncodeDecodeEmpty) {
397
+ S2CellUnion empty_cell_union;
398
+
399
+ Encoder encoder;
400
+ empty_cell_union.Encode(&encoder);
401
+ Decoder decoder(encoder.base(), encoder.length());
402
+ S2CellUnion decoded_cell_union;
403
+ EXPECT_TRUE(decoded_cell_union.Decode(&decoder));
404
+ EXPECT_EQ(empty_cell_union, decoded_cell_union);
405
+ }
406
+
407
+ static void TestFromMinMax(S2CellId min_id, S2CellId max_id) {
408
+ auto cell_union = S2CellUnion::FromMinMax(min_id, max_id);
409
+ const vector<S2CellId>& cell_ids = cell_union.cell_ids();
410
+
411
+ EXPECT_GT(cell_ids.size(), 0);
412
+ EXPECT_EQ(min_id, cell_ids.front().range_min());
413
+ EXPECT_EQ(max_id, cell_ids.back().range_max());
414
+ for (int i = 1; i < cell_ids.size(); ++i) {
415
+ EXPECT_EQ(cell_ids[i].range_min(), cell_ids[i-1].range_max().next());
416
+ }
417
+ EXPECT_TRUE(cell_union.IsNormalized());
418
+ }
419
+
420
+ TEST(S2CellUnion, FromMinMax) {
421
+ // Check the very first leaf cell and face cell.
422
+ S2CellId face1_id = S2CellId::FromFace(0);
423
+ TestFromMinMax(face1_id.range_min(), face1_id.range_min());
424
+ TestFromMinMax(face1_id.range_min(), face1_id.range_max());
425
+
426
+ // Check the very last leaf cell and face cell.
427
+ S2CellId face5_id = S2CellId::FromFace(5);
428
+ TestFromMinMax(face5_id.range_min(), face5_id.range_max());
429
+ TestFromMinMax(face5_id.range_max(), face5_id.range_max());
430
+
431
+ // Check random ranges of leaf cells.
432
+ for (int iter = 0; iter < 100; ++iter) {
433
+ S2CellId x = S2Testing::GetRandomCellId(S2CellId::kMaxLevel);
434
+ S2CellId y = S2Testing::GetRandomCellId(S2CellId::kMaxLevel);
435
+ using std::swap;
436
+ if (x > y) swap(x, y);
437
+ TestFromMinMax(x, y);
438
+ }
439
+ }
440
+
441
+ TEST(S2CellUnion, FromBeginEnd) {
442
+ // Since FromMinMax() is implemented in terms of FromBeginEnd(), we
443
+ // focus on test cases that generate an empty range.
444
+ S2CellId initial_id = S2CellId::FromFace(3);
445
+
446
+ // Test an empty range before the minimum S2CellId.
447
+ S2CellUnion cell_union({initial_id});
448
+ S2CellId id_begin = S2CellId::Begin(S2CellId::kMaxLevel);
449
+ cell_union.InitFromBeginEnd(id_begin, id_begin);
450
+ EXPECT_TRUE(cell_union.empty());
451
+
452
+ // Test an empty range after the maximum S2CellId.
453
+ cell_union.Init({initial_id});
454
+ S2CellId id_end = S2CellId::End(S2CellId::kMaxLevel);
455
+ cell_union.InitFromBeginEnd(id_end, id_end);
456
+ EXPECT_TRUE(cell_union.empty());
457
+
458
+ // Test the full sphere.
459
+ cell_union = S2CellUnion::FromBeginEnd(id_begin, id_end);
460
+ EXPECT_EQ(6, cell_union.num_cells());
461
+ for (S2CellId id : cell_union) {
462
+ EXPECT_TRUE(id.is_face());
463
+ }
464
+ }
465
+
466
+ TEST(S2CellUnion, Empty) {
467
+ S2CellUnion empty_cell_union;
468
+ S2CellId face1_id = S2CellId::FromFace(1);
469
+
470
+ // Normalize()
471
+ empty_cell_union.Normalize();
472
+ EXPECT_TRUE(empty_cell_union.empty());
473
+
474
+ // Denormalize(...)
475
+ vector<S2CellId> output;
476
+ empty_cell_union.Denormalize(0, 2, &output);
477
+ EXPECT_TRUE(empty_cell_union.empty());
478
+
479
+ // Pack(...)
480
+ empty_cell_union.Pack();
481
+
482
+ // Contains(...)
483
+ EXPECT_FALSE(empty_cell_union.Contains(face1_id));
484
+ EXPECT_TRUE(empty_cell_union.Contains(empty_cell_union));
485
+
486
+ // Intersects(...)
487
+ EXPECT_FALSE(empty_cell_union.Intersects(face1_id));
488
+ EXPECT_FALSE(empty_cell_union.Intersects(empty_cell_union));
489
+
490
+ // Union(...)
491
+ S2CellUnion cell_union = empty_cell_union.Union(empty_cell_union);
492
+ EXPECT_TRUE(cell_union.empty());
493
+
494
+ // Intersection(...)
495
+ S2CellUnion intersection = empty_cell_union.Intersection(face1_id);
496
+ EXPECT_TRUE(intersection.empty());
497
+ intersection = empty_cell_union.Intersection(empty_cell_union);
498
+ EXPECT_TRUE(intersection.empty());
499
+
500
+ // Difference(...)
501
+ S2CellUnion difference = empty_cell_union.Difference(empty_cell_union);
502
+ EXPECT_EQ(0, difference.num_cells());
503
+
504
+ // Expand(...)
505
+ empty_cell_union.Expand(S1Angle::Radians(1), 20);
506
+ EXPECT_TRUE(empty_cell_union.empty());
507
+ empty_cell_union.Expand(10);
508
+ EXPECT_TRUE(empty_cell_union.empty());
509
+ }
510
+
511
+ TEST(S2CellUnion, Clear) {
512
+ S2CellId face1_id = S2CellId::FromFace(1);
513
+ S2CellUnion face1_union({face1_id});
514
+
515
+ ASSERT_EQ(1, face1_union.num_cells());
516
+ EXPECT_EQ(1, face1_union.cell_ids().size());
517
+ EXPECT_LE(1, face1_union.cell_ids().capacity());
518
+
519
+ face1_union.Clear();
520
+ ASSERT_EQ(0, face1_union.num_cells());
521
+ EXPECT_EQ(0, face1_union.cell_ids().size());
522
+ EXPECT_EQ(0, face1_union.cell_ids().capacity());
523
+ }
524
+
525
+ TEST(S2CellUnion, RefuseToDecode) {
526
+ std::vector<S2CellId> cellids;
527
+ S2CellId id = S2CellId::Begin(S2CellId::kMaxLevel);
528
+ for (int i = 0; i <= FLAGS_s2cell_union_decode_max_num_cells; ++i) {
529
+ cellids.push_back(id);
530
+ id = id.next();
531
+ }
532
+ S2CellUnion cell_union = S2CellUnion::FromVerbatim(cellids);
533
+ Encoder encoder;
534
+ cell_union.Encode(&encoder);
535
+ Decoder decoder(encoder.base(), encoder.length());
536
+ S2CellUnion decoded_cell_union;
537
+ EXPECT_FALSE(decoded_cell_union.Decode(&decoder));
538
+ }
539
+
540
+ TEST(S2CellUnion, Release) {
541
+ S2CellId face1_id = S2CellId::FromFace(1);
542
+ S2CellUnion face1_union({face1_id});
543
+ ASSERT_EQ(1, face1_union.num_cells());
544
+ EXPECT_EQ(face1_id, face1_union.cell_id(0));
545
+
546
+ vector<S2CellId> released = face1_union.Release();
547
+ ASSERT_EQ(1, released.size());
548
+ EXPECT_EQ(face1_id, released[0]);
549
+ EXPECT_EQ(0, face1_union.num_cells());
550
+ }
551
+
552
+ TEST(S2CellUnion, LeafCellsCovered) {
553
+ S2CellUnion cell_union;
554
+ EXPECT_EQ(0, cell_union.LeafCellsCovered());
555
+
556
+ vector<S2CellId> ids;
557
+ // One leaf cell on face 0.
558
+ ids.push_back(S2CellId::FromFace(0).child_begin(S2CellId::kMaxLevel));
559
+ cell_union.Init(ids);
560
+ EXPECT_EQ(1ULL, cell_union.LeafCellsCovered());
561
+
562
+ // Face 0 itself (which includes the previous leaf cell).
563
+ ids.push_back(S2CellId::FromFace(0));
564
+ cell_union.Init(ids);
565
+ EXPECT_EQ(1ULL << 60, cell_union.LeafCellsCovered());
566
+ // Five faces.
567
+ cell_union.Expand(0);
568
+ EXPECT_EQ(5ULL << 60, cell_union.LeafCellsCovered());
569
+ // Whole world.
570
+ cell_union.Expand(0);
571
+ EXPECT_EQ(6ULL << 60, cell_union.LeafCellsCovered());
572
+
573
+ // Add some disjoint cells.
574
+ ids.push_back(S2CellId::FromFace(1).child_begin(1));
575
+ ids.push_back(S2CellId::FromFace(2).child_begin(2));
576
+ ids.push_back(S2CellId::FromFace(2).child_end(2).prev());
577
+ ids.push_back(S2CellId::FromFace(3).child_begin(14));
578
+ ids.push_back(S2CellId::FromFace(4).child_begin(27));
579
+ ids.push_back(S2CellId::FromFace(4).child_end(15).prev());
580
+ ids.push_back(S2CellId::FromFace(5).child_begin(30));
581
+ cell_union.Init(ids);
582
+ uint64 expected = 1ULL + (1ULL << 6) + (1ULL << 30) + (1ULL << 32) +
583
+ (2ULL << 56) + (1ULL << 58) + (1ULL << 60);
584
+ EXPECT_EQ(expected, cell_union.LeafCellsCovered());
585
+ }
586
+
587
+ TEST(S2CellUnion, WorksInContainers) {
588
+ vector<S2CellId> ids(1, S2CellId::FromFace(1));
589
+ S2CellUnion cell_union0(ids);
590
+
591
+ // This gives a compilation error if the S2CellUnion is neither movable nor
592
+ // copyable.
593
+ vector<S2CellUnion> union_vector;
594
+ union_vector.push_back(std::move(cell_union0));
595
+
596
+ EXPECT_EQ(ids, union_vector.back().cell_ids());
597
+ }
598
+
@@ -0,0 +1,84 @@
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/s2centroids.h"
19
+
20
+ #include <cmath>
21
+
22
+ #include "s2/s2pointutil.h"
23
+
24
+ namespace S2 {
25
+
26
+ S2Point PlanarCentroid(const S2Point& a, const S2Point& b, const S2Point& c) {
27
+ return (1./3) * (a + b + c);
28
+ }
29
+
30
+ S2Point TrueCentroid(const S2Point& a, const S2Point& b, const S2Point& c) {
31
+ S2_DCHECK(IsUnitLength(a));
32
+ S2_DCHECK(IsUnitLength(b));
33
+ S2_DCHECK(IsUnitLength(c));
34
+
35
+ // I couldn't find any references for computing the true centroid of a
36
+ // spherical triangle... I have a truly marvellous demonstration of this
37
+ // formula which this margin is too narrow to contain :)
38
+
39
+ // Use Angle() in order to get accurate results for small triangles.
40
+ double angle_a = b.Angle(c);
41
+ double angle_b = c.Angle(a);
42
+ double angle_c = a.Angle(b);
43
+ double ra = (angle_a == 0) ? 1 : (angle_a / std::sin(angle_a));
44
+ double rb = (angle_b == 0) ? 1 : (angle_b / std::sin(angle_b));
45
+ double rc = (angle_c == 0) ? 1 : (angle_c / std::sin(angle_c));
46
+
47
+ // Now compute a point M such that:
48
+ //
49
+ // [Ax Ay Az] [Mx] [ra]
50
+ // [Bx By Bz] [My] = 0.5 * det(A,B,C) * [rb]
51
+ // [Cx Cy Cz] [Mz] [rc]
52
+ //
53
+ // To improve the numerical stability we subtract the first row (A) from the
54
+ // other two rows; this reduces the cancellation error when A, B, and C are
55
+ // very close together. Then we solve it using Cramer's rule.
56
+ //
57
+ // The result is the true centroid of the triangle multiplied by the
58
+ // triangle's area.
59
+ //
60
+ // TODO(ericv): This code still isn't as numerically stable as it could be.
61
+ // The biggest potential improvement is to compute B-A and C-A more
62
+ // accurately so that (B-A)x(C-A) is always inside triangle ABC.
63
+ S2Point x(a.x(), b.x() - a.x(), c.x() - a.x());
64
+ S2Point y(a.y(), b.y() - a.y(), c.y() - a.y());
65
+ S2Point z(a.z(), b.z() - a.z(), c.z() - a.z());
66
+ S2Point r(ra, rb - ra, rc - ra);
67
+ return 0.5 * S2Point(y.CrossProd(z).DotProd(r),
68
+ z.CrossProd(x).DotProd(r),
69
+ x.CrossProd(y).DotProd(r));
70
+ }
71
+
72
+ S2Point TrueCentroid(const S2Point& a, const S2Point& b) {
73
+ // The centroid (multiplied by length) is a vector toward the midpoint
74
+ // of the edge, whose length is twice the sine of half the angle between
75
+ // the two vertices. Defining theta to be this angle, we have:
76
+ S2Point vdiff = a - b; // Length == 2*sin(theta)
77
+ S2Point vsum = a + b; // Length == 2*cos(theta)
78
+ double sin2 = vdiff.Norm2();
79
+ double cos2 = vsum.Norm2();
80
+ if (cos2 == 0) return S2Point(); // Ignore antipodal edges.
81
+ return sqrt(sin2 / cos2) * vsum; // Length == 2*sin(theta)
82
+ }
83
+
84
+ } // namespace S2