use crate::{coord, CoordNum, Point};
#[cfg(any(feature = "approx", test))]
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
#[derive(Eq, PartialEq, Clone, Copy, Debug, Hash, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Coord<T: CoordNum = f64> {
pub x: T,
pub y: T,
}
#[deprecated(note = "Renamed to `geo_types::Coord` (or `geo::Coord`)")]
pub type Coordinate<T = f64> = Coord<T>;
impl<T: CoordNum> From<(T, T)> for Coord<T> {
#[inline]
fn from(coords: (T, T)) -> Self {
coord! {
x: coords.0,
y: coords.1,
}
}
}
impl<T: CoordNum> From<[T; 2]> for Coord<T> {
#[inline]
fn from(coords: [T; 2]) -> Self {
coord! {
x: coords[0],
y: coords[1],
}
}
}
impl<T: CoordNum> From<Point<T>> for Coord<T> {
#[inline]
fn from(point: Point<T>) -> Self {
coord! {
x: point.x(),
y: point.y(),
}
}
}
impl<T: CoordNum> From<Coord<T>> for (T, T) {
#[inline]
fn from(coord: Coord<T>) -> Self {
(coord.x, coord.y)
}
}
impl<T: CoordNum> From<Coord<T>> for [T; 2] {
#[inline]
fn from(coord: Coord<T>) -> Self {
[coord.x, coord.y]
}
}
impl<T: CoordNum> Coord<T> {
#[inline]
pub fn x_y(&self) -> (T, T) {
(self.x, self.y)
}
}
use core::ops::{Add, Div, Mul, Neg, Sub};
impl<T> Neg for Coord<T>
where
T: CoordNum + Neg<Output = T>,
{
type Output = Self;
#[inline]
fn neg(self) -> Self {
coord! {
x: -self.x,
y: -self.y,
}
}
}
impl<T: CoordNum> Add for Coord<T> {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self {
coord! {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl<T: CoordNum> Sub for Coord<T> {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self {
coord! {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
impl<T: CoordNum> Mul<T> for Coord<T> {
type Output = Self;
#[inline]
fn mul(self, rhs: T) -> Self {
coord! {
x: self.x * rhs,
y: self.y * rhs,
}
}
}
impl<T: CoordNum> Div<T> for Coord<T> {
type Output = Self;
#[inline]
fn div(self, rhs: T) -> Self {
coord! {
x: self.x / rhs,
y: self.y / rhs,
}
}
}
use num_traits::Zero;
impl<T: CoordNum> Coord<T> {
#[inline]
pub fn zero() -> Self {
coord! {
x: T::zero(),
y: T::zero(),
}
}
}
impl<T: CoordNum> Zero for Coord<T> {
#[inline]
fn zero() -> Self {
Self::zero()
}
#[inline]
fn is_zero(&self) -> bool {
self.x.is_zero() && self.y.is_zero()
}
}
#[cfg(any(feature = "approx", test))]
impl<T: CoordNum + AbsDiffEq> AbsDiffEq for Coord<T>
where
T::Epsilon: Copy,
{
type Epsilon = T::Epsilon;
#[inline]
fn default_epsilon() -> T::Epsilon {
T::default_epsilon()
}
#[inline]
fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
T::abs_diff_eq(&self.x, &other.x, epsilon) && T::abs_diff_eq(&self.y, &other.y, epsilon)
}
}
#[cfg(any(feature = "approx", test))]
impl<T: CoordNum + RelativeEq> RelativeEq for Coord<T>
where
T::Epsilon: Copy,
{
#[inline]
fn default_max_relative() -> T::Epsilon {
T::default_max_relative()
}
#[inline]
fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
T::relative_eq(&self.x, &other.x, epsilon, max_relative)
&& T::relative_eq(&self.y, &other.y, epsilon, max_relative)
}
}
#[cfg(any(feature = "approx", test))]
impl<T: CoordNum + UlpsEq> UlpsEq for Coord<T>
where
T::Epsilon: Copy,
{
#[inline]
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
#[inline]
fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
T::ulps_eq(&self.x, &other.x, epsilon, max_ulps)
&& T::ulps_eq(&self.y, &other.y, epsilon, max_ulps)
}
}
#[cfg(feature = "rstar_0_8")]
impl<T> ::rstar_0_8::Point for Coord<T>
where
T: ::num_traits::Float + ::rstar_0_8::RTreeNum,
{
type Scalar = T;
const DIMENSIONS: usize = 2;
#[inline]
fn generate(generator: impl Fn(usize) -> Self::Scalar) -> Self {
coord! {
x: generator(0),
y: generator(1),
}
}
#[inline]
fn nth(&self, index: usize) -> Self::Scalar {
match index {
0 => self.x,
1 => self.y,
_ => unreachable!(),
}
}
#[inline]
fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
match index {
0 => &mut self.x,
1 => &mut self.y,
_ => unreachable!(),
}
}
}
#[cfg(feature = "rstar_0_9")]
impl<T> ::rstar_0_9::Point for Coord<T>
where
T: ::num_traits::Float + ::rstar_0_9::RTreeNum,
{
type Scalar = T;
const DIMENSIONS: usize = 2;
#[inline]
fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
coord! {
x: generator(0),
y: generator(1),
}
}
#[inline]
fn nth(&self, index: usize) -> Self::Scalar {
match index {
0 => self.x,
1 => self.y,
_ => unreachable!(),
}
}
#[inline]
fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
match index {
0 => &mut self.x,
1 => &mut self.y,
_ => unreachable!(),
}
}
}
#[cfg(feature = "rstar_0_10")]
impl<T> ::rstar_0_10::Point for Coord<T>
where
T: ::num_traits::Float + ::rstar_0_10::RTreeNum,
{
type Scalar = T;
const DIMENSIONS: usize = 2;
#[inline]
fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
coord! {
x: generator(0),
y: generator(1),
}
}
#[inline]
fn nth(&self, index: usize) -> Self::Scalar {
match index {
0 => self.x,
1 => self.y,
_ => unreachable!(),
}
}
#[inline]
fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
match index {
0 => &mut self.x,
1 => &mut self.y,
_ => unreachable!(),
}
}
}
#[cfg(feature = "rstar_0_11")]
impl<T> ::rstar_0_11::Point for Coord<T>
where
T: ::num_traits::Float + ::rstar_0_11::RTreeNum,
{
type Scalar = T;
const DIMENSIONS: usize = 2;
#[inline]
fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
coord! {
x: generator(0),
y: generator(1),
}
}
#[inline]
fn nth(&self, index: usize) -> Self::Scalar {
match index {
0 => self.x,
1 => self.y,
_ => unreachable!(),
}
}
#[inline]
fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
match index {
0 => &mut self.x,
1 => &mut self.y,
_ => unreachable!(),
}
}
}
#[cfg(feature = "rstar_0_12")]
impl<T> ::rstar_0_12::Point for Coord<T>
where
T: ::num_traits::Float + ::rstar_0_12::RTreeNum,
{
type Scalar = T;
const DIMENSIONS: usize = 2;
#[inline]
fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self {
coord! {
x: generator(0),
y: generator(1),
}
}
#[inline]
fn nth(&self, index: usize) -> Self::Scalar {
match index {
0 => self.x,
1 => self.y,
_ => unreachable!(),
}
}
#[inline]
fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
match index {
0 => &mut self.x,
1 => &mut self.y,
_ => unreachable!(),
}
}
}