pub mod projection;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Point {
pub x: f64,
pub y: f64,
}
impl Point {
#[inline]
#[must_use]
pub fn new(x: f64, y: f64) -> Self {
Self { x, y }
}
#[inline]
#[must_use]
pub fn lonlat(lon: f64, lat: f64) -> Self {
Self { x: lon, y: lat }
}
#[inline]
#[must_use]
pub fn origin() -> Self {
Self { x: 0.0, y: 0.0 }
}
#[inline]
#[must_use]
pub fn lon(&self) -> f64 {
self.x
}
#[inline]
#[must_use]
pub fn lat(&self) -> f64 {
self.y
}
#[inline]
#[must_use]
pub fn to_tuple(&self) -> (f64, f64) {
(self.x, self.y)
}
#[inline]
#[must_use]
pub fn distance_to(&self, other: &Point) -> f64 {
let dx = self.x - other.x;
let dy = self.y - other.y;
(dx * dx + dy * dy).sqrt()
}
}
impl Default for Point {
fn default() -> Self {
Self::origin()
}
}
impl From<(f64, f64)> for Point {
#[inline]
fn from((x, y): (f64, f64)) -> Self {
Self::new(x, y)
}
}
impl From<Point> for (f64, f64) {
#[inline]
fn from(p: Point) -> Self {
(p.x, p.y)
}
}
impl From<[f64; 2]> for Point {
#[inline]
fn from([x, y]: [f64; 2]) -> Self {
Self::new(x, y)
}
}
impl From<Point> for [f64; 2] {
#[inline]
fn from(p: Point) -> Self {
[p.x, p.y]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_point_new() {
let p = Point::new(10.0, 20.0);
assert_eq!(p.x, 10.0);
assert_eq!(p.y, 20.0);
}
#[test]
fn test_point_lonlat() {
let p = Point::lonlat(-122.4, 37.8);
assert_eq!(p.lon(), -122.4);
assert_eq!(p.lat(), 37.8);
}
#[test]
fn test_point_origin() {
let p = Point::origin();
assert_eq!(p.x, 0.0);
assert_eq!(p.y, 0.0);
}
#[test]
fn test_point_from_tuple() {
let p: Point = (5.0, 10.0).into();
assert_eq!(p.x, 5.0);
assert_eq!(p.y, 10.0);
}
#[test]
fn test_point_to_tuple() {
let p = Point::new(5.0, 10.0);
let (x, y) = p.to_tuple();
assert_eq!(x, 5.0);
assert_eq!(y, 10.0);
}
#[test]
fn test_point_from_array() {
let p: Point = [3.0, 4.0].into();
assert_eq!(p.x, 3.0);
assert_eq!(p.y, 4.0);
}
#[test]
fn test_point_to_array() {
let p = Point::new(3.0, 4.0);
let arr: [f64; 2] = p.into();
assert_eq!(arr, [3.0, 4.0]);
}
#[test]
fn test_point_distance() {
let p1 = Point::new(0.0, 0.0);
let p2 = Point::new(3.0, 4.0);
assert!((p1.distance_to(&p2) - 5.0).abs() < 1e-10);
}
#[test]
fn test_point_equality() {
let p1 = Point::new(1.0, 2.0);
let p2 = Point::new(1.0, 2.0);
let p3 = Point::new(1.0, 3.0);
assert_eq!(p1, p2);
assert_ne!(p1, p3);
}
#[test]
fn test_point_default() {
let p = Point::default();
assert_eq!(p, Point::origin());
}
}