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