use std::fmt::Display;
use crate::core::{math::Vector2, traits::Real};
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
pub struct PlineVertex<T = f64> {
pub x: T,
pub y: T,
pub bulge: T,
}
impl<T> Display for PlineVertex<T>
where
T: Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[{}, {}, {}]", self.x, self.y, self.bulge)
}
}
#[cfg(feature = "serde")]
mod serde_impl {
use super::PlineVertex;
use serde::{Deserialize, Serialize, ser::SerializeTuple};
impl<T> Serialize for PlineVertex<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut tuple = serializer.serialize_tuple(3)?;
tuple.serialize_element(&self.x)?;
tuple.serialize_element(&self.y)?;
tuple.serialize_element(&self.bulge)?;
tuple.end()
}
}
impl<'de, T> Deserialize<'de> for PlineVertex<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let [x, y, bulge]: [T; 3] = Deserialize::deserialize(deserializer)?;
Ok(PlineVertex { x, y, bulge })
}
}
}
#[cfg(feature = "serde")]
#[allow(unused_imports)]
pub use serde_impl::*;
impl<T> PlineVertex<T>
where
T: Real,
{
#[inline]
pub fn new(x: T, y: T, bulge: T) -> Self {
PlineVertex { x, y, bulge }
}
#[inline]
pub fn from_slice(slice: &[T]) -> Option<Self> {
if let [x, y, bulge] = *slice {
Some(PlineVertex::new(x, y, bulge))
} else {
None
}
}
#[inline]
pub fn from_vector2(vector2: Vector2<T>, bulge: T) -> Self {
PlineVertex::new(vector2.x, vector2.y, bulge)
}
#[inline]
pub fn with_bulge(&self, bulge: T) -> Self {
PlineVertex::new(self.x, self.y, bulge)
}
#[inline]
pub fn pos(&self) -> Vector2<T> {
Vector2::new(self.x, self.y)
}
#[inline]
pub fn bulge_is_zero(&self) -> bool {
self.bulge.fuzzy_eq_zero()
}
#[inline]
pub fn bulge_is_pos(&self) -> bool {
self.bulge > T::zero()
}
#[inline]
pub fn bulge_is_neg(&self) -> bool {
self.bulge < T::zero()
}
#[inline]
pub fn fuzzy_eq_eps(&self, other: Self, fuzzy_epsilon: T) -> bool {
self.x.fuzzy_eq_eps(other.x, fuzzy_epsilon)
&& self.y.fuzzy_eq_eps(other.y, fuzzy_epsilon)
&& self.bulge.fuzzy_eq_eps(other.bulge, fuzzy_epsilon)
}
#[inline]
pub fn fuzzy_eq(&self, other: Self) -> bool {
self.fuzzy_eq_eps(other, T::fuzzy_epsilon())
}
}