Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the coordinate tree #108

Merged
merged 3 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- CoordinateSet: xyz(), set_xyz(), xyzt(), set_xyzt() methods
- Vector space operators (Add, Sub, Mul, Div) for all built
in coordinate tuple types (Coor4D, Coor3D, Coor2D, Coor32)

### Changed

- `CoordinateTuple` trait now requires implementation of the constructor
method `new(fill: f64)`, returning an object of `dim()` copies of `fill`.

### Removed

- CHANGES.md
Expand Down
42 changes: 19 additions & 23 deletions src/coordinate/coor2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,36 @@ use crate::math::angular;
#[derive(Debug, Default, PartialEq, Copy, Clone)]
pub struct Coor2D(pub [f64; 2]);

use std::ops::{Index, IndexMut};
impl CoordinateTuple for Coor2D {
fn new(fill: f64) -> Self {
Coor2D([fill; 2])
}

impl Index<usize> for Coor2D {
type Output = f64;
fn index(&self, i: usize) -> &Self::Output {
&self.0[i]
fn dim(&self) -> usize {
2
}

fn nth_unchecked(&self, n: usize) -> f64 {
self.0[n]
}
}

impl IndexMut<usize> for Coor2D {
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
&mut self.0[i]
fn set_nth_unchecked(&mut self, n: usize, value: f64) {
self.0[n] = value;
}
}

// ----- C O N S T R U C T O R S ---------------------------------------------

/// Constructors
impl Coor2D {
/// A `Coor2D` from latitude/longitude/height/time, with the angular input in degrees,
/// and height and time ignored.
/// A `Coor2D` from latitude/longitude in degrees
#[must_use]
pub fn geo(latitude: f64, longitude: f64) -> Coor2D {
Coor2D([longitude.to_radians(), latitude.to_radians()])
}

/// A `Coor2D` from longitude/latitude/height/time, with the angular input in seconds
/// of arc. Mostly for handling grid shift elements.
/// A `Coor2D` from longitude/latitude in seconds of arc.
/// Mostly for handling grid shift elements.
#[must_use]
pub fn arcsec(longitude: f64, latitude: f64) -> Coor2D {
Coor2D([
Expand All @@ -41,33 +43,27 @@ impl Coor2D {
])
}

/// A `Coor2D` from longitude/latitude/height/time, with the angular input in degrees.
/// and height and time ignored.
/// A `Coor2D` from longitude/latitude in degrees.
#[must_use]
pub fn gis(longitude: f64, latitude: f64) -> Coor2D {
Coor2D([longitude.to_radians(), latitude.to_radians()])
}

/// A `Coor2D` from longitude/latitude/height/time, with the angular input in radians,
/// and third and fourth arguments ignored.
/// A `Coor2D` from e.g. longitude/latitude in radians,
#[must_use]
pub fn raw(first: f64, second: f64) -> Coor2D {
Coor2D([first, second])
}

/// A `Coor2D` from latitude/longitude/height/time, with
/// the angular input in the ISO-6709 DDDMM.mmmmm format,
/// and height and time ignored.
/// A `Coor2D` from latitude/longitude in the ISO-6709 DDDMM.mmmmm format.
#[must_use]
pub fn iso_dm(latitude: f64, longitude: f64) -> Coor2D {
let longitude = angular::iso_dm_to_dd(longitude);
let latitude = angular::iso_dm_to_dd(latitude);
Coor2D([longitude.to_radians(), latitude.to_radians()])
}

/// A `Coor2D` from latitude/longitude/height/time, with the
/// angular input in the ISO-6709 DDDMMSS.sssss format,
/// and height and time ignored.
/// A `Coor2D` from latitude/longitude in the ISO-6709 DDDMMSS.sssss format.
#[must_use]
pub fn iso_dms(latitude: f64, longitude: f64) -> Coor2D {
let longitude = angular::iso_dms_to_dd(longitude);
Expand Down
24 changes: 13 additions & 11 deletions src/coordinate/coor32.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
use crate::math::angular;
use std::ops::{Index, IndexMut};
use super::*;

/// Generic 2D Coordinate tuple, with no fixed interpretation of the elements.
/// A tiny coordinate type: Just one fourth the weight of a [`Coor4D`](crate::Coor4D).
/// Probably only useful for small scale world maps, without too much zoom.
#[derive(Debug, Default, PartialEq, Copy, Clone)]
pub struct Coor32(pub [f32; 2]);

// ----- O P E R A T O R T R A I T S -------------------------------------------------
impl CoordinateTuple for Coor32 {
fn new(fill: f64) -> Self {
Coor32([fill as f32; 2])
}

impl Index<usize> for Coor32 {
type Output = f32;
fn index(&self, i: usize) -> &Self::Output {
&self.0[i]
fn dim(&self) -> usize {
2
}

fn nth_unchecked(&self, n: usize) -> f64 {
self.0[n] as f64
}
}

impl IndexMut<usize> for Coor32 {
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
&mut self.0[i]
fn set_nth_unchecked(&mut self, n: usize, value: f64) {
self.0[n] = value as f32;
}
}

Expand Down
87 changes: 17 additions & 70 deletions src/coordinate/coor3d.rs
Original file line number Diff line number Diff line change
@@ -1,91 +1,38 @@
use crate::math::angular;
use std::ops::{Add, Div, Index, IndexMut, Mul, Sub};
use super::*;

/// Generic 3D coordinate tuple, with no fixed interpretation of the elements
#[derive(Debug, Default, PartialEq, Copy, Clone)]
pub struct Coor3D(pub [f64; 3]);

// ----- O P E R A T O R T R A I T S -------------------------------------------------

impl Index<usize> for Coor3D {
type Output = f64;
fn index(&self, i: usize) -> &Self::Output {
&self.0[i]
}
}

impl IndexMut<usize> for Coor3D {
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
&mut self.0[i]
impl CoordinateTuple for Coor3D {
fn new(fill: f64) -> Self {
Coor3D([fill; 3])
}
}

impl Add for Coor3D {
type Output = Self;
fn add(self, other: Self) -> Self {
Coor3D([
self.0[0] + other.0[0],
self.0[1] + other.0[1],
self.0[2] + other.0[2],
])
fn dim(&self) -> usize {
3
}
}

impl Add<&Coor3D> for Coor3D {
type Output = Self;
fn add(self, other: &Self) -> Self {
Coor3D([
self.0[0] + other.0[0],
self.0[1] + other.0[1],
self.0[2] + other.0[2],
])
fn nth_unchecked(&self, n: usize) -> f64 {
self.0[n]
}
}

impl Sub for Coor3D {
type Output = Self;
fn sub(self, other: Self) -> Self {
Coor3D([
self.0[0] - other.0[0],
self.0[1] - other.0[1],
self.0[2] - other.0[2],
])
}
}

impl Mul for Coor3D {
type Output = Self;
fn mul(self, other: Self) -> Self {
Coor3D([
self.0[0] * other.0[0],
self.0[1] * other.0[1],
self.0[2] * other.0[2],
])
}
}

impl Div for Coor3D {
type Output = Self;
fn div(self, other: Self) -> Self {
Coor3D([
self.0[0] / other.0[0],
self.0[1] / other.0[1],
self.0[2] / other.0[2],
])
fn set_nth_unchecked(&mut self, n: usize, value: f64) {
self.0[n] = value;
}
}

// ----- C O N S T R U C T O R S ---------------------------------------------

/// Constructors
impl Coor3D {
/// A `Coor3D` from latitude/longitude/height/time, with the angular input in degrees
/// A `Coor3D` from latitude/longitude/height, with the angular input in degrees
#[must_use]
pub fn geo(latitude: f64, longitude: f64, height: f64) -> Coor3D {
Coor3D([longitude.to_radians(), latitude.to_radians(), height])
}

/// A `Coor3D` from longitude/latitude/height/time, with the angular input in seconds
/// A `Coor3D` from longitude/latitude/height, with the angular input in seconds
/// of arc. Mostly for handling grid shift elements.
#[must_use]
pub fn arcsec(longitude: f64, latitude: f64, height: f64) -> Coor3D {
Expand All @@ -96,7 +43,7 @@ impl Coor3D {
])
}

/// A `Coor3D` from longitude/latitude/height/time, with the angular input in degrees
/// A `Coor3D` from longitude/latitude/height, with the angular input in degrees
#[must_use]
pub fn gis(longitude: f64, latitude: f64, height: f64) -> Coor3D {
Coor3D([longitude.to_radians(), latitude.to_radians(), height])
Expand All @@ -108,7 +55,7 @@ impl Coor3D {
Coor3D([first, second, third])
}

/// A `Coor3D` from latitude/longitude/height/time,
/// A `Coor3D` from latitude/longitude/height,
/// with the angular input in the ISO-6709 DDDMM.mmmmm format
#[must_use]
pub fn iso_dm(latitude: f64, longitude: f64, height: f64) -> Coor3D {
Expand All @@ -117,7 +64,7 @@ impl Coor3D {
Coor3D([longitude.to_radians(), latitude.to_radians(), height])
}

/// A `Coor3D` from latitude/longitude/height/time, with
/// A `Coor3D` from latitude/longitude/height, with
/// the angular input in the ISO-6709 DDDMMSS.sssss format
#[must_use]
pub fn iso_dms(latitude: f64, longitude: f64, height: f64) -> Coor3D {
Expand All @@ -129,7 +76,7 @@ impl Coor3D {
/// A `Coor3D` consisting of 3 `NaN`s
#[must_use]
pub fn nan() -> Coor3D {
Coor3D([f64::NAN, f64::NAN, f64::NAN])
Coor3D::new(f64::NAN) //([f64::NAN, f64::NAN, f64::NAN])
}

/// A `Coor3D` consisting of 3 `0`s
Expand Down Expand Up @@ -172,7 +119,7 @@ impl Coor3D {
#[cfg(test)]
mod tests {
use super::*;
use crate::prelude::*;
use std::ops::{Add, Div, Mul};

#[test]
fn distances() {
Expand Down
82 changes: 11 additions & 71 deletions src/coordinate/coor4d.rs
Original file line number Diff line number Diff line change
@@ -1,84 +1,24 @@
use crate::math::angular;
use std::ops::{Add, Div, Mul, Sub};
use crate::coordinate::*;

/// Generic 4D coordinate tuple, with no fixed interpretation of the elements
#[derive(Debug, Default, PartialEq, Copy, Clone)]
pub struct Coor4D(pub [f64; 4]);

// ----- O P E R A T O R T R A I T S -------------------------------------------------

use std::ops::{Index, IndexMut};

impl Index<usize> for Coor4D {
type Output = f64;
fn index(&self, i: usize) -> &Self::Output {
&self.0[i]
}
}

impl IndexMut<usize> for Coor4D {
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
&mut self.0[i]
}
}

impl Add for Coor4D {
type Output = Self;
fn add(self, other: Self) -> Self {
Coor4D([
self.0[0] + other.0[0],
self.0[1] + other.0[1],
self.0[2] + other.0[2],
self.0[3] + other.0[3],
])
}
}

impl Add<&Coor4D> for Coor4D {
type Output = Self;
fn add(self, other: &Self) -> Self {
Coor4D([
self.0[0] + other.0[0],
self.0[1] + other.0[1],
self.0[2] + other.0[2],
self.0[3] + other.0[3],
])
impl CoordinateTuple for Coor4D {
fn new(fill: f64) -> Self {
Coor4D([fill; 4])
}
}

impl Sub for Coor4D {
type Output = Self;
fn sub(self, other: Self) -> Self {
Coor4D([
self.0[0] - other.0[0],
self.0[1] - other.0[1],
self.0[2] - other.0[2],
self.0[3] - other.0[3],
])
fn dim(&self) -> usize {
4
}
}

impl Mul for Coor4D {
type Output = Self;
fn mul(self, other: Self) -> Self {
Coor4D([
self.0[0] * other.0[0],
self.0[1] * other.0[1],
self.0[2] * other.0[2],
self.0[3] * other.0[3],
])
fn nth_unchecked(&self, n: usize) -> f64 {
self.0[n]
}
}

impl Div for Coor4D {
type Output = Self;
fn div(self, other: Self) -> Self {
Coor4D([
self.0[0] / other.0[0],
self.0[1] / other.0[1],
self.0[2] / other.0[2],
self.0[3] / other.0[3],
])
fn set_nth_unchecked(&mut self, n: usize, value: f64) {
self.0[n] = value;
}
}

Expand Down Expand Up @@ -158,7 +98,7 @@ impl Coor4D {
#[cfg(test)]
mod tests {
use super::*;
use crate::prelude::*;
use std::ops::{Add, Div, Mul};

#[test]
fn distances() {
Expand Down
Loading
Loading