/src/h3/src/h3lib/include/vec3d.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2018, 2020-2021, 2026 Uber Technologies, Inc. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | /** @file vec3d.h |
17 | | * @brief 3D floating point vector functions. |
18 | | * |
19 | | * Header-only (static inline) so callers in other translation units |
20 | | * can inline these without requiring LTO. |
21 | | */ |
22 | | |
23 | | #ifndef VEC3D_H |
24 | | #define VEC3D_H |
25 | | |
26 | | #include <math.h> |
27 | | |
28 | | #include "h3api.h" |
29 | | #include "latLng.h" |
30 | | |
31 | | /** @struct Vec3d |
32 | | * @brief 3D floating point structure |
33 | | * |
34 | | * For geodesic calculations represents a point on the surface of the Earth |
35 | | * as a unit vector in 3D Cartesian space (ECEF-like coordinates). |
36 | | */ |
37 | | typedef struct { |
38 | | double x; /// towards 0deg lat, 0deg lon |
39 | | double y; /// towards 0deg lat, 90deg lon |
40 | | double z; /// towards north pole |
41 | | } Vec3d; |
42 | | |
43 | | /** Convert latitude and longitude to a unit Vec3d on the sphere. */ |
44 | 0 | static inline Vec3d latLngToVec3(LatLng geo) { |
45 | 0 | double r = cos(geo.lat); |
46 | 0 | Vec3d out = { |
47 | 0 | .x = cos(geo.lng) * r, |
48 | 0 | .y = sin(geo.lng) * r, |
49 | 0 | .z = sin(geo.lat), |
50 | 0 | }; |
51 | 0 | return out; |
52 | 0 | } Unexecuted instantiation: directedEdge.c:latLngToVec3 Unexecuted instantiation: faceijk.c:latLngToVec3 Unexecuted instantiation: algos.c:latLngToVec3 Unexecuted instantiation: bbox.c:latLngToVec3 Unexecuted instantiation: h3Index.c:latLngToVec3 Unexecuted instantiation: vertex.c:latLngToVec3 Unexecuted instantiation: iterators.c:latLngToVec3 Unexecuted instantiation: baseCells.c:latLngToVec3 |
53 | | |
54 | 2.47k | static inline LatLng vec3ToLatLng(Vec3d v) { |
55 | 2.47k | LatLng out = { |
56 | 2.47k | .lat = asin(v.z), |
57 | 2.47k | .lng = atan2(v.y, v.x), |
58 | 2.47k | }; |
59 | 2.47k | return out; |
60 | 2.47k | } Unexecuted instantiation: directedEdge.c:vec3ToLatLng Line | Count | Source | 54 | 2.47k | static inline LatLng vec3ToLatLng(Vec3d v) { | 55 | 2.47k | LatLng out = { | 56 | 2.47k | .lat = asin(v.z), | 57 | 2.47k | .lng = atan2(v.y, v.x), | 58 | 2.47k | }; | 59 | 2.47k | return out; | 60 | 2.47k | } |
Unexecuted instantiation: algos.c:vec3ToLatLng Unexecuted instantiation: bbox.c:vec3ToLatLng Unexecuted instantiation: h3Index.c:vec3ToLatLng Unexecuted instantiation: vertex.c:vec3ToLatLng Unexecuted instantiation: iterators.c:vec3ToLatLng Unexecuted instantiation: baseCells.c:vec3ToLatLng |
61 | | |
62 | 7.42k | static inline Vec3d vec3LinComb(double a, Vec3d v1, double b, Vec3d v2) { |
63 | 7.42k | Vec3d out = { |
64 | 7.42k | .x = a * v1.x + b * v2.x, |
65 | 7.42k | .y = a * v1.y + b * v2.y, |
66 | 7.42k | .z = a * v1.z + b * v2.z, |
67 | 7.42k | }; |
68 | 7.42k | return out; |
69 | 7.42k | } Unexecuted instantiation: directedEdge.c:vec3LinComb Line | Count | Source | 62 | 7.42k | static inline Vec3d vec3LinComb(double a, Vec3d v1, double b, Vec3d v2) { | 63 | 7.42k | Vec3d out = { | 64 | 7.42k | .x = a * v1.x + b * v2.x, | 65 | 7.42k | .y = a * v1.y + b * v2.y, | 66 | 7.42k | .z = a * v1.z + b * v2.z, | 67 | 7.42k | }; | 68 | 7.42k | return out; | 69 | 7.42k | } |
Unexecuted instantiation: algos.c:vec3LinComb Unexecuted instantiation: bbox.c:vec3LinComb Unexecuted instantiation: h3Index.c:vec3LinComb Unexecuted instantiation: vertex.c:vec3LinComb Unexecuted instantiation: iterators.c:vec3LinComb Unexecuted instantiation: baseCells.c:vec3LinComb |
70 | | |
71 | 2.47k | static inline Vec3d vec3Cross(Vec3d v1, Vec3d v2) { |
72 | 2.47k | Vec3d out = { |
73 | 2.47k | .x = v1.y * v2.z - v1.z * v2.y, |
74 | 2.47k | .y = v1.z * v2.x - v1.x * v2.z, |
75 | 2.47k | .z = v1.x * v2.y - v1.y * v2.x, |
76 | 2.47k | }; |
77 | 2.47k | return out; |
78 | 2.47k | } Unexecuted instantiation: directedEdge.c:vec3Cross Line | Count | Source | 71 | 2.47k | static inline Vec3d vec3Cross(Vec3d v1, Vec3d v2) { | 72 | 2.47k | Vec3d out = { | 73 | 2.47k | .x = v1.y * v2.z - v1.z * v2.y, | 74 | 2.47k | .y = v1.z * v2.x - v1.x * v2.z, | 75 | 2.47k | .z = v1.x * v2.y - v1.y * v2.x, | 76 | 2.47k | }; | 77 | 2.47k | return out; | 78 | 2.47k | } |
Unexecuted instantiation: algos.c:vec3Cross Unexecuted instantiation: bbox.c:vec3Cross Unexecuted instantiation: h3Index.c:vec3Cross Unexecuted instantiation: vertex.c:vec3Cross Unexecuted instantiation: iterators.c:vec3Cross Unexecuted instantiation: baseCells.c:vec3Cross |
79 | | |
80 | 7.42k | static inline double vec3Dot(Vec3d v1, Vec3d v2) { |
81 | 7.42k | return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; |
82 | 7.42k | } Unexecuted instantiation: directedEdge.c:vec3Dot Line | Count | Source | 80 | 7.42k | static inline double vec3Dot(Vec3d v1, Vec3d v2) { | 81 | 7.42k | return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; | 82 | 7.42k | } |
Unexecuted instantiation: algos.c:vec3Dot Unexecuted instantiation: bbox.c:vec3Dot Unexecuted instantiation: h3Index.c:vec3Dot Unexecuted instantiation: vertex.c:vec3Dot Unexecuted instantiation: iterators.c:vec3Dot Unexecuted instantiation: baseCells.c:vec3Dot |
83 | | |
84 | 4.95k | static inline double vec3NormSq(Vec3d v) { return vec3Dot(v, v); }Unexecuted instantiation: directedEdge.c:vec3NormSq Line | Count | Source | 84 | 4.95k | static inline double vec3NormSq(Vec3d v) { return vec3Dot(v, v); } |
Unexecuted instantiation: algos.c:vec3NormSq Unexecuted instantiation: bbox.c:vec3NormSq Unexecuted instantiation: h3Index.c:vec3NormSq Unexecuted instantiation: vertex.c:vec3NormSq Unexecuted instantiation: iterators.c:vec3NormSq Unexecuted instantiation: baseCells.c:vec3NormSq |
85 | | |
86 | 4.95k | static inline double vec3Norm(Vec3d v) { return sqrt(vec3NormSq(v)); }Unexecuted instantiation: directedEdge.c:vec3Norm Line | Count | Source | 86 | 4.95k | static inline double vec3Norm(Vec3d v) { return sqrt(vec3NormSq(v)); } |
Unexecuted instantiation: algos.c:vec3Norm Unexecuted instantiation: bbox.c:vec3Norm Unexecuted instantiation: h3Index.c:vec3Norm Unexecuted instantiation: vertex.c:vec3Norm Unexecuted instantiation: iterators.c:vec3Norm Unexecuted instantiation: baseCells.c:vec3Norm |
87 | | |
88 | 4.95k | static inline void vec3Normalize(Vec3d *v) { |
89 | 4.95k | double norm = vec3Norm(*v); |
90 | | |
91 | | // Norm can be zero either from true zero vector, or from squaring |
92 | | // underflowing to zero. |
93 | | // If the norm is nonzero, we normalize v using it. |
94 | | // If the norm is zero, we set the vector to be exactly zero. |
95 | 4.95k | double s = 0.0; |
96 | 4.95k | if (norm > 0.0) { |
97 | 4.95k | s = 1.0 / norm; |
98 | 4.95k | } |
99 | | |
100 | 4.95k | v->x *= s; |
101 | 4.95k | v->y *= s; |
102 | 4.95k | v->z *= s; |
103 | 4.95k | } Unexecuted instantiation: directedEdge.c:vec3Normalize Line | Count | Source | 88 | 4.95k | static inline void vec3Normalize(Vec3d *v) { | 89 | 4.95k | double norm = vec3Norm(*v); | 90 | | | 91 | | // Norm can be zero either from true zero vector, or from squaring | 92 | | // underflowing to zero. | 93 | | // If the norm is nonzero, we normalize v using it. | 94 | | // If the norm is zero, we set the vector to be exactly zero. | 95 | 4.95k | double s = 0.0; | 96 | 4.95k | if (norm > 0.0) { | 97 | 4.95k | s = 1.0 / norm; | 98 | 4.95k | } | 99 | | | 100 | 4.95k | v->x *= s; | 101 | 4.95k | v->y *= s; | 102 | 4.95k | v->z *= s; | 103 | 4.95k | } |
Unexecuted instantiation: algos.c:vec3Normalize Unexecuted instantiation: bbox.c:vec3Normalize Unexecuted instantiation: h3Index.c:vec3Normalize Unexecuted instantiation: vertex.c:vec3Normalize Unexecuted instantiation: iterators.c:vec3Normalize Unexecuted instantiation: baseCells.c:vec3Normalize |
104 | | |
105 | 0 | static inline double vec3DistSq(Vec3d v1, Vec3d v2) { |
106 | 0 | Vec3d d = vec3LinComb(1.0, v1, -1.0, v2); |
107 | 0 | return vec3NormSq(d); |
108 | 0 | } Unexecuted instantiation: directedEdge.c:vec3DistSq Unexecuted instantiation: faceijk.c:vec3DistSq Unexecuted instantiation: algos.c:vec3DistSq Unexecuted instantiation: bbox.c:vec3DistSq Unexecuted instantiation: h3Index.c:vec3DistSq Unexecuted instantiation: vertex.c:vec3DistSq Unexecuted instantiation: iterators.c:vec3DistSq Unexecuted instantiation: baseCells.c:vec3DistSq |
109 | | |
110 | | #endif |