cad_cs/libs/cs/math/d2.rs
1// 📃 ./src/libs/cs/math/d2.rs
2
3use crate::libs::cs::{
4 abstracts::{AbstractMathCs2, AbstractSignStrExt},
5 model::Cs,
6};
7
8impl AbstractMathCs2 for Cs<2> {
9 /// 📚 【 POL】: Długość rzutu (promień) na płaszczyznę XY.
10 /// 📚 【 ENG】: Projection length (radius) on the XY plane.
11 #[rustfmt::skip] #[inline] fn rxy(&self) -> f64 { self.0[0].hypot(self.0[1]) }
12
13 /// 📚 【 POL】: Azymut matematyczny (od osi X w stronę Y, CCW).
14 /// 📚 【 ENG】: Mathematical azimuth (from X-axis towards Y, CCW).
15 #[rustfmt::skip] #[inline] fn arctan_y_x(&self) -> f64 { self.0[1].atan2(self.0[0]) }
16
17 /// 📚 【 POL】: Azymut kompasowy/geodezyjny (od osi Y w stronę X, CW).
18 /// 📚 【 ENG】: Compass/geodetic azimuth (from Y-axis towards X, CW).
19 #[rustfmt::skip] #[inline] fn arctan_x_y(&self) -> f64 { self.0[0].atan2(self.0[1]) }
20
21 /// 📚 【 POL】: Konwertuje wektor kartezjański [X, Y] na wektor biegunowy [R, Φ] w obrębie Cs2.
22 /// 📚 【 ENG】: Converts a Cartesian vector [X, Y] to a polar vector [R, Φ] within Cs2.
23 #[rustfmt::skip] #[inline] fn to_rf_from_xy(&self) -> Cs<2> { Cs([self.rxy(), self.arctan_y_x()]) }
24
25 /// 📚 【 POL】: Przekształca współrzędne geograficzne [Szerokość, Długość] w radianach na wektor 3D ECEF (X, Y, Z).
26 /// 📚 【 ENG】: Transforms geographic coordinates [Latitude, Longitude] in radians to a 3D ECEF vector (X, Y, Z).
27 /// ⚙️ 【 POL】: Wykorzystuje zadany promień 'r' (np. promień Ziemi).
28 /// ⚙️ 【 ENG】: Uses the specified radius 'r' (e.g., Earth's radius).
29 fn to_ecef_from_rad_sn_we(&self, r: f64) -> Cs<3> {
30 let (sin_lat, cos_lat) = self.0[0].sin_cos();
31 let (sin_lon, cos_lon) = self.0[1].sin_cos();
32
33 // Oś X: 0°N, 0°E (Greenwich na równiku)
34 // Oś Y: 0°N, 90°E (Ocean Indyjski na równiku)
35 // Oś Z: 90°N (Biegun Północny)
36 // Oś X: 0°N, 0°E | Oś Y: 0°N, 90°E | Oś Z: 90°N
37 Cs([
38 r * cos_lat * cos_lon, // X
39 r * cos_lat * sin_lon, // Y
40 r * sin_lat, // Z
41 ])
42 }
43
44 /// 📚 【 POL】: Zwraca numer ćwiartki na płaszczyźnie XY (1-4).
45 /// 📚 【 ENG】: Returns the quadrant number on the XY plane (1-4).
46 #[rustfmt::skip] #[inline]
47 fn q(&self) -> u8 {
48 match (self.0[0] >= 0.0, self.0[1] >= 0.0) {
49 (true, true) => 1, (false, true) => 2, (false, false) => 3, (true, false) => 4,
50 }
51 }
52
53 /// 📚 【 POL】: Zwraca znaki kierunkowe osi X i Y w formie tablicy stringów (np. ["+", "-"]).
54 /// 📚 【 ENG】: Returns the directional signs of the X and Y axes as an array of strings (e.g., ["+", "-"]).
55 #[rustfmt::skip] #[inline]
56 fn q_sign(&self) -> [&'static str; 2] { [self.0[0].sign_str(), self.0[1].sign_str()] }
57
58 /// 📚 【 POL】: Kwadrat długości rzutu XY (szybsza alternatywa dla rxy).
59 /// 📚 【 ENG】: Squared projection length XY (faster alternative to rxy).
60 #[rustfmt::skip] #[inline] fn rxy_sq(&self) -> f64 { self.0[0] * self.0[0] + self.0[1] * self.0[1] }
61
62 /// 📚 【 POL】: Iloczyn wektorowy 2D (wyznacznik). Znak określa orientację (lewo/prawo).
63 /// 📚 【 ENG】: 2D cross product (determinant). The sign determines orientation (left/right).
64 #[rustfmt::skip] #[inline]
65 fn cross(&self, other: &Cs<2>) -> f64 { self.0[0] * other.0[1] - self.0[1] * other.0[0] }
66
67 /// 📚 【 POL】: Zwraca wektor prostopadły obrócony o 90° w lewo (CCW).
68 /// 📚 【 ENG】: Returns a perpendicular vector rotated 90° to the left (CCW).
69 #[rustfmt::skip] #[inline]
70 fn perp(&self) -> Cs<2> { Cs([-self.0[1], self.0[0]]) }
71}