@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,515 @@
1
+ // Copyright 2005 Google Inc. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS-IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+
16
+ // Author: ericv@google.com (Eric Veach)
17
+
18
+ #include "s2/s2edge_crossings.h"
19
+ #include "s2/s2edge_crossings_internal.h"
20
+
21
+ #include <cmath>
22
+
23
+ #include "s2/base/logging.h"
24
+ #include "s2/s1angle.h"
25
+ #include "s2/s2edge_crosser.h"
26
+ #include "s2/s2pointutil.h"
27
+ #include "s2/s2predicates.h"
28
+ #include "s2/s2predicates_internal.h"
29
+ #include "s2/util/math/exactfloat/exactfloat.h"
30
+
31
+ namespace S2 {
32
+
33
+ using internal::GetIntersectionExact;
34
+ using internal::IntersectionMethod;
35
+ using internal::intersection_method_tally_;
36
+ using std::fabs;
37
+ using std::sqrt;
38
+
39
+ // All error bounds in this file are expressed in terms of the maximum
40
+ // rounding error for a floating-point type. The rounding error is half of
41
+ // the numeric_limits<T>::epsilon() value.
42
+ static constexpr double DBL_ERR = s2pred::rounding_epsilon<double>();
43
+
44
+ // kIntersectionError can be set somewhat arbitrarily, because the algorithm
45
+ // uses more precision when necessary in order to achieve the specified error.
46
+ // The only strict requirement is that kIntersectionError >= 2 * DBL_ERR
47
+ // radians. However, using a larger error tolerance makes the algorithm more
48
+ // efficient because it reduces the number of cases where exact arithmetic is
49
+ // needed.
50
+ const S1Angle kIntersectionError = S1Angle::Radians(8 * DBL_ERR);
51
+
52
+ const S1Angle kIntersectionMergeRadius = 2 * kIntersectionError;
53
+
54
+ namespace internal {
55
+
56
+ const S1Angle kIntersectionExactError = S1Angle::Radians(2 * DBL_ERR);
57
+
58
+ int* intersection_method_tally_ = nullptr;
59
+
60
+ const char* GetIntersectionMethodName(IntersectionMethod method) {
61
+ switch (method) {
62
+ case IntersectionMethod::SIMPLE: return "Simple";
63
+ case IntersectionMethod::SIMPLE_LD: return "Simple_ld";
64
+ case IntersectionMethod::STABLE: return "Stable";
65
+ case IntersectionMethod::STABLE_LD: return "Stable_ld";
66
+ case IntersectionMethod::EXACT: return "Exact";
67
+ default: return "Unknown";
68
+ }
69
+ }
70
+
71
+ } // namespace internal
72
+
73
+ int CrossingSign(const S2Point& a, const S2Point& b,
74
+ const S2Point& c, const S2Point& d) {
75
+ S2EdgeCrosser crosser(&a, &b, &c);
76
+ return crosser.CrossingSign(&d);
77
+ }
78
+
79
+ bool VertexCrossing(const S2Point& a, const S2Point& b,
80
+ const S2Point& c, const S2Point& d) {
81
+ // If A == B or C == D there is no intersection. We need to check this
82
+ // case first in case 3 or more input points are identical.
83
+ if (a == b || c == d) return false;
84
+
85
+ // If any other pair of vertices is equal, there is a crossing if and only
86
+ // if OrderedCCW() indicates that the edge AB is further CCW around the
87
+ // shared vertex O (either A or B) than the edge CD, starting from an
88
+ // arbitrary fixed reference point.
89
+ //
90
+ // Optimization: if AB=CD or AB=DC, we can avoid most of the calculations.
91
+ if (a == c) return (b == d) || s2pred::OrderedCCW(S2::Ortho(a), d, b, a);
92
+ if (b == d) return s2pred::OrderedCCW(S2::Ortho(b), c, a, b);
93
+
94
+ if (a == d) return (b == c) || s2pred::OrderedCCW(S2::Ortho(a), c, b, a);
95
+ if (b == c) return s2pred::OrderedCCW(S2::Ortho(b), d, a, b);
96
+
97
+ S2_LOG(DFATAL) << "VertexCrossing called with 4 distinct vertices";
98
+ return false;
99
+ }
100
+
101
+ bool EdgeOrVertexCrossing(const S2Point& a, const S2Point& b,
102
+ const S2Point& c, const S2Point& d) {
103
+ int crossing = CrossingSign(a, b, c, d);
104
+ if (crossing < 0) return false;
105
+ if (crossing > 0) return true;
106
+ return VertexCrossing(a, b, c, d);
107
+ }
108
+
109
+ using Vector3_ld = Vector3<long double>;
110
+ using Vector3_xf = Vector3<ExactFloat>;
111
+
112
+ // Computes the cross product of "x" and "y", normalizes it to be unit length,
113
+ // and stores the result in "result". Also returns the length of the cross
114
+ // product before normalization, which is useful for estimating the amount of
115
+ // error in the result. For numerical stability, "x" and "y" should both be
116
+ // approximately unit length.
117
+ template <class T>
118
+ static T RobustNormalWithLength(const Vector3<T>& x, const Vector3<T>& y,
119
+ Vector3<T>* result) {
120
+ // This computes 2 * (x.CrossProd(y)), but has much better numerical
121
+ // stability when "x" and "y" are unit length.
122
+ Vector3<T> tmp = (x - y).CrossProd(x + y);
123
+ T length = tmp.Norm();
124
+ if (length != 0) {
125
+ *result = (1 / length) * tmp;
126
+ }
127
+ return 0.5 * length; // Since tmp == 2 * (x.CrossProd(y))
128
+ }
129
+
130
+ // If the intersection point of the edges (a0,a1) and (b0,b1) can be computed
131
+ // to within an error of at most kIntersectionError by this function, then set
132
+ // "result" to the intersection point and return true.
133
+ //
134
+ // The intersection point is not guaranteed to have the correct sign
135
+ // (i.e., it may be either "result" or "-result").
136
+ template <class T>
137
+ static bool GetIntersectionSimple(const Vector3<T>& a0, const Vector3<T>& a1,
138
+ const Vector3<T>& b0, const Vector3<T>& b1,
139
+ Vector3<T>* result) {
140
+ // The code below computes the intersection point as
141
+ //
142
+ // (a0.CrossProd(a1)).CrossProd(b0.CrossProd(b1))
143
+ //
144
+ // except that it has better numerical stability and also computes a
145
+ // guaranteed error bound.
146
+ //
147
+ // Each cross product is computed as (X-Y).CrossProd(X+Y) using unit-length
148
+ // input vectors, which eliminates most of the cancellation error. However
149
+ // the error in the direction of the cross product can still become large if
150
+ // the two points are extremely close together. We can show that as long as
151
+ // the length of the cross product is at least (16 * sqrt(3) + 24) * DBL_ERR
152
+ // (about 6e-15), then the directional error is at most 5 * T_ERR (about
153
+ // 3e-19 when T == "long double"). (DBL_ERR appears in the first formula
154
+ // because the inputs are assumed to be normalized in double precision
155
+ // rather than in the given type T.)
156
+ //
157
+ // The third cross product is different because its inputs already have some
158
+ // error. Letting "result_len" be the length of the cross product, it can
159
+ // be shown that the error is at most
160
+ //
161
+ // (2 + 2 * sqrt(3) + 12 / result_len) * T_ERR
162
+ //
163
+ // We want this error to be at most kIntersectionError, which is true as
164
+ // long as "result_len" is at least kMinResultLen defined below.
165
+
166
+ constexpr T T_ERR = s2pred::rounding_epsilon<T>();
167
+ static const T kMinNormalLength = (16 * sqrt(3) + 24) * DBL_ERR;
168
+ static const T kMinResultLen =
169
+ 12 / (kIntersectionError.radians() / T_ERR - (2 + 2 * sqrt(3)));
170
+
171
+ // On some platforms "long double" is the same as "double", and on these
172
+ // platforms this method always returns false (e.g. ARM, Win32). Rather
173
+ // than testing this directly, instead we look at kMinResultLen since this
174
+ // is a direct measure of whether "long double" has sufficient accuracy to
175
+ // be useful. If kMinResultLen > 0.5, it means that this method will fail
176
+ // even for edges that meet at an angle of 30 degrees. (On Intel platforms
177
+ // kMinResultLen corresponds to an intersection angle of about 0.04
178
+ // degrees.)
179
+ S2_DCHECK_LE(kMinResultLen, 0.5);
180
+
181
+ Vector3<T> a_norm, b_norm;
182
+ if (RobustNormalWithLength(a0, a1, &a_norm) >= kMinNormalLength &&
183
+ RobustNormalWithLength(b0, b1, &b_norm) >= kMinNormalLength &&
184
+ RobustNormalWithLength(a_norm, b_norm, result) >= kMinResultLen) {
185
+ return true;
186
+ }
187
+ return false;
188
+ }
189
+
190
+ static bool GetIntersectionSimpleLD(const S2Point& a0, const S2Point& a1,
191
+ const S2Point& b0, const S2Point& b1,
192
+ S2Point* result) {
193
+ Vector3_ld result_ld;
194
+ if (GetIntersectionSimple(Vector3_ld::Cast(a0), Vector3_ld::Cast(a1),
195
+ Vector3_ld::Cast(b0), Vector3_ld::Cast(b1),
196
+ &result_ld)) {
197
+ *result = S2Point::Cast(result_ld);
198
+ return true;
199
+ }
200
+ return false;
201
+ }
202
+
203
+ // Given a point X and a vector "a_norm" (not necessarily unit length),
204
+ // compute x.DotProd(a_norm) and return a bound on the error in the result.
205
+ // The remaining parameters allow this dot product to be computed more
206
+ // accurately and efficiently. They include the length of "a_norm"
207
+ // ("a_norm_len") and the edge endpoints "a0" and "a1".
208
+ template <class T>
209
+ static T GetProjection(const Vector3<T>& x,
210
+ const Vector3<T>& a_norm, T a_norm_len,
211
+ const Vector3<T>& a0, const Vector3<T>& a1,
212
+ T* error) {
213
+ // The error in the dot product is proportional to the lengths of the input
214
+ // vectors, so rather than using "x" itself (a unit-length vector) we use
215
+ // the vectors from "x" to the closer of the two edge endpoints. This
216
+ // typically reduces the error by a huge factor.
217
+ Vector3<T> x0 = x - a0;
218
+ Vector3<T> x1 = x - a1;
219
+ T x0_dist2 = x0.Norm2();
220
+ T x1_dist2 = x1.Norm2();
221
+
222
+ // If both distances are the same, we need to be careful to choose one
223
+ // endpoint deterministically so that the result does not change if the
224
+ // order of the endpoints is reversed.
225
+ T dist, result;
226
+ if (x0_dist2 < x1_dist2 || (x0_dist2 == x1_dist2 && x0 < x1)) {
227
+ dist = sqrt(x0_dist2);
228
+ result = x0.DotProd(a_norm);
229
+ } else {
230
+ dist = sqrt(x1_dist2);
231
+ result = x1.DotProd(a_norm);
232
+ }
233
+ // This calculation bounds the error from all sources: the computation of
234
+ // the normal, the subtraction of one endpoint, and the dot product itself.
235
+ // (DBL_ERR appears because the input points are assumed to be normalized in
236
+ // double precision rather than in the given type T.)
237
+ //
238
+ // For reference, the bounds that went into this calculation are:
239
+ // ||N'-N|| <= ((1 + 2 * sqrt(3))||N|| + 32 * sqrt(3) * DBL_ERR) * T_ERR
240
+ // |(A.B)'-(A.B)| <= (1.5 * (A.B) + 1.5 * ||A|| * ||B||) * T_ERR
241
+ // ||(X-Y)'-(X-Y)|| <= ||X-Y|| * T_ERR
242
+ constexpr T T_ERR = s2pred::rounding_epsilon<T>();
243
+ *error = (((3.5 + 2 * sqrt(3)) * a_norm_len + 32 * sqrt(3) * DBL_ERR)
244
+ * dist + 1.5 * fabs(result)) * T_ERR;
245
+ return result;
246
+ }
247
+
248
+ // Helper function for GetIntersectionStable(). It expects that the edges
249
+ // (a0,a1) and (b0,b1) have been sorted so that the first edge is longer.
250
+ template <class T>
251
+ static bool GetIntersectionStableSorted(
252
+ const Vector3<T>& a0, const Vector3<T>& a1,
253
+ const Vector3<T>& b0, const Vector3<T>& b1, Vector3<T>* result) {
254
+ S2_DCHECK_GE((a1 - a0).Norm2(), (b1 - b0).Norm2());
255
+
256
+ // Compute the normal of the plane through (a0, a1) in a stable way.
257
+ Vector3<T> a_norm = (a0 - a1).CrossProd(a0 + a1);
258
+ T a_norm_len = a_norm.Norm();
259
+ T b_len = (b1 - b0).Norm();
260
+
261
+ // Compute the projection (i.e., signed distance) of b0 and b1 onto the
262
+ // plane through (a0, a1). Distances are scaled by the length of a_norm.
263
+ T b0_error, b1_error;
264
+ T b0_dist = GetProjection(b0, a_norm, a_norm_len, a0, a1, &b0_error);
265
+ T b1_dist = GetProjection(b1, a_norm, a_norm_len, a0, a1, &b1_error);
266
+
267
+ // The total distance from b0 to b1 measured perpendicularly to (a0,a1) is
268
+ // |b0_dist - b1_dist|. Note that b0_dist and b1_dist generally have
269
+ // opposite signs because b0 and b1 are on opposite sides of (a0, a1). The
270
+ // code below finds the intersection point by interpolating along the edge
271
+ // (b0, b1) to a fractional distance of b0_dist / (b0_dist - b1_dist).
272
+ //
273
+ // It can be shown that the maximum error in the interpolation fraction is
274
+ //
275
+ // (b0_dist * b1_error - b1_dist * b0_error) /
276
+ // (dist_sum * (dist_sum - error_sum))
277
+ //
278
+ // We save ourselves some work by scaling the result and the error bound by
279
+ // "dist_sum", since the result is normalized to be unit length anyway.
280
+ T dist_sum = fabs(b0_dist - b1_dist);
281
+ T error_sum = b0_error + b1_error;
282
+ if (dist_sum <= error_sum) {
283
+ return false; // Error is unbounded in this case.
284
+ }
285
+ Vector3<T> x = b0_dist * b1 - b1_dist * b0;
286
+ constexpr T T_ERR = s2pred::rounding_epsilon<T>();
287
+ T error = b_len * fabs(b0_dist * b1_error - b1_dist * b0_error) /
288
+ (dist_sum - error_sum) + 2 * T_ERR * dist_sum;
289
+
290
+ // Finally we normalize the result, compute the corresponding error, and
291
+ // check whether the total error is acceptable.
292
+ T x_len2 = x.Norm2();
293
+ if (x_len2 < std::numeric_limits<T>::min()) {
294
+ // If x.Norm2() is less than the minimum normalized value of T, x_len might
295
+ // lose precision and the result might fail to satisfy S2::IsUnitLength().
296
+ // TODO(ericv): Implement S2::RobustNormalize().
297
+ return false;
298
+ }
299
+ T x_len = sqrt(x_len2);
300
+ const T kMaxError = kIntersectionError.radians();
301
+ if (error > (kMaxError - T_ERR) * x_len) {
302
+ return false;
303
+ }
304
+ *result = (1 / x_len) * x;
305
+ return true;
306
+ }
307
+
308
+ // Returns whether (a0,a1) is less than (b0,b1) with respect to a total
309
+ // ordering on edges that is invariant under edge reversals.
310
+ template <class T>
311
+ static bool CompareEdges(const Vector3<T>& a0, const Vector3<T>& a1,
312
+ const Vector3<T>& b0, const Vector3<T>& b1) {
313
+ const Vector3<T> *pa0 = &a0, *pa1 = &a1;
314
+ const Vector3<T> *pb0 = &b0, *pb1 = &b1;
315
+ if (*pa0 >= *pa1) std::swap(pa0, pa1);
316
+ if (*pb0 >= *pb1) std::swap(pb0, pb1);
317
+ return *pa0 < *pb0 || (*pa0 == *pb0 && *pb0 < *pb1);
318
+ }
319
+
320
+ // If the intersection point of the edges (a0,a1) and (b0,b1) can be computed
321
+ // to within an error of at most kIntersectionError by this function, then set
322
+ // "result" to the intersection point and return true.
323
+ //
324
+ // The intersection point is not guaranteed to have the correct sign
325
+ // (i.e., it may be either "result" or "-result").
326
+ template <class T>
327
+ static bool GetIntersectionStable(const Vector3<T>& a0, const Vector3<T>& a1,
328
+ const Vector3<T>& b0, const Vector3<T>& b1,
329
+ Vector3<T>* result) {
330
+ // Sort the two edges so that (a0,a1) is longer, breaking ties in a
331
+ // deterministic way that does not depend on the ordering of the endpoints.
332
+ // This is desirable for two reasons:
333
+ // - So that the result doesn't change when edges are swapped or reversed.
334
+ // - It reduces error, since the first edge is used to compute the edge
335
+ // normal (where a longer edge means less error), and the second edge
336
+ // is used for interpolation (where a shorter edge means less error).
337
+ T a_len2 = (a1 - a0).Norm2();
338
+ T b_len2 = (b1 - b0).Norm2();
339
+ if (a_len2 < b_len2 || (a_len2 == b_len2 && CompareEdges(a0, a1, b0, b1))) {
340
+ return GetIntersectionStableSorted(b0, b1, a0, a1, result);
341
+ } else {
342
+ return GetIntersectionStableSorted(a0, a1, b0, b1, result);
343
+ }
344
+ }
345
+
346
+ static bool GetIntersectionStableLD(const S2Point& a0, const S2Point& a1,
347
+ const S2Point& b0, const S2Point& b1,
348
+ S2Point* result) {
349
+ Vector3_ld result_ld;
350
+ if (GetIntersectionStable(Vector3_ld::Cast(a0), Vector3_ld::Cast(a1),
351
+ Vector3_ld::Cast(b0), Vector3_ld::Cast(b1),
352
+ &result_ld)) {
353
+ *result = S2Point::Cast(result_ld);
354
+ return true;
355
+ }
356
+ return false;
357
+ }
358
+
359
+ static S2Point S2PointFromExact(const Vector3_xf& xf) {
360
+ // If all components of "x" have absolute value less than about 1e-154,
361
+ // then x.Norm2() is zero in double precision due to underflow. Therefore
362
+ // we need to scale "x" by an appropriate power of 2 before the conversion.
363
+ S2Point x(xf[0].ToDouble(), xf[1].ToDouble(), xf[2].ToDouble());
364
+ if (x.Norm2() > 0) return x.Normalize();
365
+
366
+ // Scale so that the largest component magnitude is in the range [0.5, 1).
367
+ int exp = ExactFloat::kMinExp - 1;
368
+ for (int i = 0; i < 3; ++i) {
369
+ if (xf[i].is_normal()) exp = std::max(exp, xf[i].exp());
370
+ }
371
+ if (exp < ExactFloat::kMinExp) {
372
+ return S2Point(0, 0, 0);
373
+ }
374
+ return S2Point(ldexp(xf[0], -exp).ToDouble(),
375
+ ldexp(xf[1], -exp).ToDouble(),
376
+ ldexp(xf[2], -exp).ToDouble()).Normalize();
377
+ }
378
+
379
+ namespace internal {
380
+
381
+ // Compute the intersection point of (a0, a1) and (b0, b1) using exact
382
+ // arithmetic. Note that the result is not exact because it is rounded to
383
+ // double precision. Also, the intersection point is not guaranteed to have
384
+ // the correct sign (i.e., the return value may need to be negated).
385
+ S2Point GetIntersectionExact(const S2Point& a0, const S2Point& a1,
386
+ const S2Point& b0, const S2Point& b1) {
387
+ // Since we are using exact arithmetic, we don't need to worry about
388
+ // numerical stability.
389
+ Vector3_xf a0_xf = Vector3_xf::Cast(a0);
390
+ Vector3_xf a1_xf = Vector3_xf::Cast(a1);
391
+ Vector3_xf b0_xf = Vector3_xf::Cast(b0);
392
+ Vector3_xf b1_xf = Vector3_xf::Cast(b1);
393
+ Vector3_xf a_norm_xf = a0_xf.CrossProd(a1_xf);
394
+ Vector3_xf b_norm_xf = b0_xf.CrossProd(b1_xf);
395
+ Vector3_xf x_xf = a_norm_xf.CrossProd(b_norm_xf);
396
+
397
+ // The final Normalize() call is done in double precision, which creates a
398
+ // directional error of up to 2 * DBL_ERR. (ToDouble() and Normalize() each
399
+ // contribute up to DBL_ERR of directional error.)
400
+ S2Point x = S2PointFromExact(x_xf);
401
+
402
+ if (x == S2Point(0, 0, 0)) {
403
+ // The two edges are exactly collinear, but we still consider them to be
404
+ // "crossing" because of simulation of simplicity. Out of the four
405
+ // endpoints, exactly two lie in the interior of the other edge. Of
406
+ // those two we return the one that is lexicographically smallest.
407
+ x = S2Point(10, 10, 10); // Greater than any valid S2Point
408
+ S2Point a_norm = S2PointFromExact(a_norm_xf);
409
+ S2Point b_norm = S2PointFromExact(b_norm_xf);
410
+ if (a_norm == S2Point(0, 0, 0) || b_norm == S2Point(0, 0, 0)) {
411
+ // TODO(ericv): To support antipodal edges properly, we would need to
412
+ // add an s2pred::CrossProd() function that computes the cross product
413
+ // using simulation of simplicity and rounds the result to the nearest
414
+ // floating-point representation.
415
+ S2_LOG(DFATAL) << "Exactly antipodal edges not supported by GetIntersection";
416
+ }
417
+ if (s2pred::OrderedCCW(b0, a0, b1, b_norm) && a0 < x) x = a0;
418
+ if (s2pred::OrderedCCW(b0, a1, b1, b_norm) && a1 < x) x = a1;
419
+ if (s2pred::OrderedCCW(a0, b0, a1, a_norm) && b0 < x) x = b0;
420
+ if (s2pred::OrderedCCW(a0, b1, a1, a_norm) && b1 < x) x = b1;
421
+ }
422
+ S2_DCHECK(S2::IsUnitLength(x));
423
+ return x;
424
+ }
425
+
426
+ } // namespace internal
427
+
428
+ // Given three points "a", "x", "b", returns true if these three points occur
429
+ // in the given order along the edge (a,b) to within the given tolerance.
430
+ // More precisely, either "x" must be within "tolerance" of "a" or "b", or
431
+ // when "x" is projected onto the great circle through "a" and "b" it must lie
432
+ // along the edge (a,b) (i.e., the shortest path from "a" to "b").
433
+ static bool ApproximatelyOrdered(const S2Point& a, const S2Point& x,
434
+ const S2Point& b, double tolerance) {
435
+ if ((x - a).Norm2() <= tolerance * tolerance) return true;
436
+ if ((x - b).Norm2() <= tolerance * tolerance) return true;
437
+ return s2pred::OrderedCCW(a, x, b, S2::RobustCrossProd(a, b).Normalize());
438
+ }
439
+
440
+ S2Point GetIntersection(const S2Point& a0, const S2Point& a1,
441
+ const S2Point& b0, const S2Point& b1) {
442
+ S2_DCHECK_GT(CrossingSign(a0, a1, b0, b1), 0);
443
+
444
+ // It is difficult to compute the intersection point of two edges accurately
445
+ // when the angle between the edges is very small. Previously we handled
446
+ // this by only guaranteeing that the returned intersection point is within
447
+ // kIntersectionError of each edge. However, this means that when the edges
448
+ // cross at a very small angle, the computed result may be very far from the
449
+ // true intersection point.
450
+ //
451
+ // Instead this function now guarantees that the result is always within
452
+ // kIntersectionError of the true intersection. This requires using more
453
+ // sophisticated techniques and in some cases extended precision.
454
+ //
455
+ // Three different techniques are implemented, but only two are used:
456
+ //
457
+ // - GetIntersectionSimple() computes the intersection point using
458
+ // numerically stable cross products in "long double" precision.
459
+ //
460
+ // - GetIntersectionStable() computes the intersection point using
461
+ // projection and interpolation, taking care to minimize cancellation
462
+ // error. This method exists in "double" and "long double" versions.
463
+ //
464
+ // - GetIntersectionExact() computes the intersection point using exact
465
+ // arithmetic and converts the final result back to an S2Point.
466
+ //
467
+ // We don't actually use the first method (GetIntersectionSimple) because it
468
+ // turns out that GetIntersectionStable() is twice as fast and also much
469
+ // more accurate (even in double precision). The "long double" version
470
+ // (only available on Intel platforms) uses 80-bit precision and is about
471
+ // twice as slow. The exact arithmetic version is about 100x slower.
472
+ //
473
+ // So our strategy is to first call GetIntersectionStable() in double
474
+ // precision; if that doesn't work and this platform supports "long double",
475
+ // then we try again in "long double"; if that doesn't work then we fall
476
+ // back to exact arithmetic.
477
+
478
+ static const bool kUseSimpleMethod = false;
479
+ static const bool kHasLongDouble = (s2pred::rounding_epsilon<long double>() <
480
+ s2pred::rounding_epsilon<double>());
481
+ S2Point result;
482
+ IntersectionMethod method;
483
+ if (kUseSimpleMethod && GetIntersectionSimple(a0, a1, b0, b1, &result)) {
484
+ method = IntersectionMethod::SIMPLE;
485
+ } else if (kUseSimpleMethod && kHasLongDouble &&
486
+ GetIntersectionSimpleLD(a0, a1, b0, b1, &result)) {
487
+ method = IntersectionMethod::SIMPLE_LD;
488
+ } else if (GetIntersectionStable(a0, a1, b0, b1, &result)) {
489
+ method = IntersectionMethod::STABLE;
490
+ } else if (kHasLongDouble &&
491
+ GetIntersectionStableLD(a0, a1, b0, b1, &result)) {
492
+ method = IntersectionMethod::STABLE_LD;
493
+ } else {
494
+ result = GetIntersectionExact(a0, a1, b0, b1);
495
+ method = IntersectionMethod::EXACT;
496
+ }
497
+ if (intersection_method_tally_) {
498
+ ++intersection_method_tally_[static_cast<int>(method)];
499
+ }
500
+
501
+ // Make sure the intersection point is on the correct side of the sphere.
502
+ // Since all vertices are unit length, and edges are less than 180 degrees,
503
+ // (a0 + a1) and (b0 + b1) both have positive dot product with the
504
+ // intersection point. We use the sum of all vertices to make sure that the
505
+ // result is unchanged when the edges are swapped or reversed.
506
+ if (result.DotProd((a0 + a1) + (b0 + b1)) < 0) result = -result;
507
+
508
+ // Make sure that the intersection point lies on both edges.
509
+ S2_DCHECK(ApproximatelyOrdered(a0, result, a1, kIntersectionError.radians()));
510
+ S2_DCHECK(ApproximatelyOrdered(b0, result, b1, kIntersectionError.radians()));
511
+
512
+ return result;
513
+ }
514
+
515
+ } // namespace S2
@@ -0,0 +1,138 @@
1
+ // Copyright 2005 Google Inc. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS-IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+
16
+ // Author: ericv@google.com (Eric Veach)
17
+ //
18
+ // Defines functions related to determining whether two geodesic edges cross
19
+ // and for computing intersection points.
20
+ //
21
+ // The predicates CrossingSign(), VertexCrossing(), and EdgeOrVertexCrossing()
22
+ // are robust, meaning that they produce correct, consistent results even in
23
+ // pathological cases. See s2predicates.h for additional robust predicates.
24
+ //
25
+ // See also S2EdgeCrosser (which efficiently tests an edge against a sequence
26
+ // of other edges) and S2CrossingEdgeQuery (which uses an index to speed up
27
+ // the process).
28
+
29
+ #ifndef S2_S2EDGE_CROSSINGS_H_
30
+ #define S2_S2EDGE_CROSSINGS_H_
31
+
32
+ #include <cmath>
33
+
34
+ #include "s2/base/logging.h"
35
+ #include "s2/third_party/absl/base/macros.h"
36
+ #include "s2/third_party/absl/container/inlined_vector.h"
37
+ #include "s2/_fp_contract_off.h"
38
+ #include "s2/r2.h"
39
+ #include "s2/r2rect.h"
40
+ #include "s2/s1angle.h"
41
+ #include "s2/s1chord_angle.h"
42
+ #include "s2/s1interval.h"
43
+ #include "s2/s2latlng.h"
44
+ #include "s2/s2latlng_rect.h"
45
+ #include "s2/s2pointutil.h"
46
+ #include "s2/s2predicates.h"
47
+ #include "s2/util/math/vector.h"
48
+
49
+ namespace S2 {
50
+
51
+ // This function determines whether the edge AB intersects the edge CD.
52
+ // Returns +1 if AB crosses CD at a point that is interior to both edges.
53
+ // Returns 0 if any two vertices from different edges are the same.
54
+ // Returns -1 otherwise.
55
+ //
56
+ // Note that if an edge is degenerate (A == B or C == D), the return value
57
+ // is 0 if two vertices from different edges are the same and -1 otherwise.
58
+ //
59
+ // Properties of CrossingSign:
60
+ //
61
+ // (1) CrossingSign(b,a,c,d) == CrossingSign(a,b,c,d)
62
+ // (2) CrossingSign(c,d,a,b) == CrossingSign(a,b,c,d)
63
+ // (3) CrossingSign(a,b,c,d) == 0 if a==c, a==d, b==c, b==d
64
+ // (3) CrossingSign(a,b,c,d) <= 0 if a==b or c==d (see above)
65
+ //
66
+ // This function implements an exact, consistent perturbation model such
67
+ // that no three points are ever considered to be collinear. This means
68
+ // that even if you have 4 points A, B, C, D that lie exactly in a line
69
+ // (say, around the equator), C and D will be treated as being slightly to
70
+ // one side or the other of AB. This is done in a way such that the
71
+ // results are always consistent (see s2pred::Sign).
72
+ //
73
+ // Note that if you want to check an edge against a collection of other edges,
74
+ // it is much more efficient to use an S2EdgeCrosser (see s2edge_crosser.h).
75
+ int CrossingSign(const S2Point& a, const S2Point& b,
76
+ const S2Point& c, const S2Point& d);
77
+
78
+ // Given two edges AB and CD where at least two vertices are identical
79
+ // (i.e. CrossingSign(a,b,c,d) == 0), this function defines whether the
80
+ // two edges "cross" in a such a way that point-in-polygon containment tests
81
+ // can be implemented by counting the number of edge crossings. The basic
82
+ // rule is that a "crossing" occurs if AB is encountered after CD during a
83
+ // CCW sweep around the shared vertex starting from a fixed reference point.
84
+ //
85
+ // Note that according to this rule, if AB crosses CD then in general CD
86
+ // does not cross AB. However, this leads to the correct result when
87
+ // counting polygon edge crossings. For example, suppose that A,B,C are
88
+ // three consecutive vertices of a CCW polygon. If we now consider the edge
89
+ // crossings of a segment BP as P sweeps around B, the crossing number
90
+ // changes parity exactly when BP crosses BA or BC.
91
+ //
92
+ // Useful properties of VertexCrossing (VC):
93
+ //
94
+ // (1) VC(a,a,c,d) == VC(a,b,c,c) == false
95
+ // (2) VC(a,b,a,b) == VC(a,b,b,a) == true
96
+ // (3) VC(a,b,c,d) == VC(a,b,d,c) == VC(b,a,c,d) == VC(b,a,d,c)
97
+ // (3) If exactly one of a,b equals one of c,d, then exactly one of
98
+ // VC(a,b,c,d) and VC(c,d,a,b) is true
99
+ //
100
+ // It is an error to call this method with 4 distinct vertices.
101
+ bool VertexCrossing(const S2Point& a, const S2Point& b,
102
+ const S2Point& c, const S2Point& d);
103
+
104
+ // A convenience function that calls CrossingSign() to handle cases
105
+ // where all four vertices are distinct, and VertexCrossing() to handle
106
+ // cases where two or more vertices are the same. This defines a crossing
107
+ // function such that point-in-polygon containment tests can be implemented
108
+ // by simply counting edge crossings.
109
+ bool EdgeOrVertexCrossing(const S2Point& a, const S2Point& b,
110
+ const S2Point& c, const S2Point& d);
111
+
112
+ // Given two edges AB and CD such that CrossingSign(A, B, C, D) > 0, returns
113
+ // their intersection point. Useful properties of GetIntersection (GI):
114
+ //
115
+ // (1) GI(b,a,c,d) == GI(a,b,d,c) == GI(a,b,c,d)
116
+ // (2) GI(c,d,a,b) == GI(a,b,c,d)
117
+ //
118
+ // The returned intersection point X is guaranteed to be very close to the
119
+ // true intersection point of AB and CD, even if the edges intersect at a
120
+ // very small angle. See "kIntersectionError" below for details.
121
+ S2Point GetIntersection(const S2Point& a, const S2Point& b,
122
+ const S2Point& c, const S2Point& d);
123
+
124
+ // kIntersectionError is an upper bound on the distance from the intersection
125
+ // point returned by GetIntersection() to the true intersection point.
126
+ extern const S1Angle kIntersectionError;
127
+
128
+ // This value can be used as the S2Builder snap_radius() to ensure that edges
129
+ // that have been displaced by up to kIntersectionError are merged back
130
+ // together again. For example this can happen when geometry is intersected
131
+ // with a set of tiles and then unioned. It is equal to twice the
132
+ // intersection error because input edges might have been displaced in
133
+ // opposite directions.
134
+ extern const S1Angle kIntersectionMergeRadius; // 2 * kIntersectionError
135
+
136
+ } // namespace S2
137
+
138
+ #endif // S2_S2EDGE_CROSSINGS_H_