gistools/geometry/s2/
point.rs1use core::cmp::Ordering;
2use core::fmt::Debug;
3use core::ops::{Add, Div, Mul, Neg, Sub};
4
5use libm::{fabs, sqrt};
6
7use crate::{s2::xyz_to_face_uv, wm::LonLat, xyz_to_face_st};
8
9use super::S2CellId;
10
11#[derive(Debug, Copy, Clone, Default, PartialEq)]
18pub struct S2Point {
19 pub x: f64,
21 pub y: f64,
23 pub z: f64,
25}
26impl S2Point {
27 pub fn new(x: f64, y: f64, z: f64) -> Self {
29 S2Point { x, y, z }
30 }
31
32 pub fn is_empty(&self) -> bool {
34 let zero = f64::default();
35 self.x == zero && self.y == zero && self.z == zero
36 }
37
38 pub fn face(&self, f: u8) -> f64 {
40 if f == 0 {
41 self.x
42 } else if f == 1 {
43 self.y
44 } else {
45 self.z
46 }
47 }
48
49 pub fn to_face_st(&self) -> (u8, f64, f64) {
51 xyz_to_face_st(self)
52 }
53
54 pub fn get_face(&self) -> u8 {
56 xyz_to_face_uv(self).0
57 }
58
59 pub fn dot(&self, b: &Self) -> f64 {
61 self.x * b.x + self.y * b.y + self.z * b.z
62 }
63
64 pub fn abs(&self) -> Self {
66 Self::new(fabs(self.x), fabs(self.y), fabs(self.z))
67 }
68
69 pub fn len(&self) -> f64 {
71 sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
72 }
73
74 pub fn distance(&self, b: &Self) -> f64 {
76 let d = *self - *b;
77 d.len()
78 }
79
80 pub fn largest_abs_component(&self) -> u8 {
82 let tmp = self.abs();
83 if tmp.x > tmp.y {
84 if tmp.x > tmp.z {
85 0
86 } else {
87 2
88 }
89 } else if tmp.y > tmp.z {
90 1
91 } else {
92 2
93 }
94 }
95
96 pub fn normalize(&mut self) {
98 let mut len = self.x * self.x + self.y * self.y + self.z * self.z;
99 if len > 0.0 {
100 len = sqrt(len);
101 self.x /= len;
102 self.y /= len;
103 self.z /= len;
104 }
105 }
106}
107impl From<&LonLat> for S2Point {
108 fn from(lonlat: &LonLat) -> Self {
109 lonlat.to_point()
110 }
111}
112impl From<&S2CellId> for S2Point {
113 fn from(cellid: &S2CellId) -> Self {
114 cellid.to_point()
115 }
116}
117impl Add<S2Point> for S2Point {
119 type Output = Self;
120 fn add(self, other: Self) -> Self::Output {
121 S2Point { x: self.x + other.x, y: self.y + other.y, z: self.z + other.z }
122 }
123}
124impl Add<f64> for S2Point {
125 type Output = Self;
126 fn add(self, other: f64) -> Self::Output {
127 S2Point { x: self.x + other, y: self.y + other, z: self.z + other }
128 }
129}
130impl Sub<S2Point> for S2Point {
132 type Output = Self;
133 fn sub(self, other: Self) -> Self::Output {
134 S2Point { x: self.x - other.x, y: self.y - other.y, z: self.z - other.z }
135 }
136}
137impl Sub<f64> for S2Point {
138 type Output = Self;
139 fn sub(self, other: f64) -> Self::Output {
140 S2Point { x: self.x - other, y: self.y - other, z: self.z - other }
141 }
142}
143impl Neg for S2Point {
145 type Output = Self;
146 fn neg(self) -> Self::Output {
147 S2Point { x: -self.x, y: -self.y, z: -self.z }
148 }
149}
150impl Div<S2Point> for S2Point {
152 type Output = Self;
153 fn div(self, other: Self) -> Self::Output {
154 S2Point { x: self.x / other.x, y: self.y / other.y, z: self.z / other.z }
155 }
156}
157impl Div<f64> for S2Point {
158 type Output = Self;
159 fn div(self, other: f64) -> Self::Output {
160 S2Point { x: self.x / other, y: self.y / other, z: self.z / other }
161 }
162}
163impl Mul<S2Point> for S2Point {
165 type Output = Self;
166 fn mul(self, other: Self) -> Self::Output {
167 S2Point { x: self.x * other.x, y: self.y * other.y, z: self.z * other.z }
168 }
169}
170impl Mul<f64> for S2Point {
171 type Output = Self;
172 fn mul(self, other: f64) -> Self::Output {
173 S2Point { x: self.x * other, y: self.y * other, z: self.z * other }
174 }
175}
176impl Eq for S2Point {}
177impl Ord for S2Point {
178 fn cmp(&self, other: &Self) -> Ordering {
179 match self.x.partial_cmp(&other.x) {
180 Some(Ordering::Equal) => {}
181 other => return other.unwrap(), }
183 match self.y.partial_cmp(&other.y) {
184 Some(Ordering::Equal) => {}
185 other => return other.unwrap(), }
187 match self.z.partial_cmp(&other.z) {
188 Some(order) => order,
189 None => Ordering::Equal, }
191 }
192}
193impl PartialOrd for S2Point {
194 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
195 Some(self.cmp(other))
196 }
197}
198
199