use crate::road::geometry::param_poly_3_p_range::ParamPoly3pRange;
use std::borrow::Cow;
#[derive(Debug, Clone, PartialEq)]
pub struct ParamPoly3 {
pub a_u: f64,
pub a_v: f64,
pub b_u: f64,
pub b_v: f64,
pub c_u: f64,
pub c_v: f64,
pub d_u: f64,
pub d_v: f64,
pub p_range: ParamPoly3pRange,
}
impl ParamPoly3 {
#[inline]
pub fn u(&self, p: f64) -> f64 {
self.a_u + (self.b_u * p) + (self.c_u * p * p) + (self.d_u * p * p * p)
}
#[inline]
pub fn v(&self, p: f64) -> f64 {
self.a_v + (self.b_v * p) + (self.c_v * p * p) + (self.d_v * p * p * p)
}
pub fn visit_attributes(
&self,
visitor: impl for<'b> FnOnce(
Cow<'b, [xml::attribute::Attribute<'b>]>,
) -> xml::writer::Result<()>,
) -> xml::writer::Result<()> {
visit_attributes!(
visitor,
"aU" => &self.a_u.to_scientific_string(),
"aV" => &self.a_v.to_scientific_string(),
"bU" => &self.b_u.to_scientific_string(),
"bV" => &self.b_v.to_scientific_string(),
"cU" => &self.c_u.to_scientific_string(),
"cV" => &self.c_v.to_scientific_string(),
"dU" => &self.d_u.to_scientific_string(),
"dV" => &self.d_v.to_scientific_string(),
"pRange" => self.p_range.as_str(),
)
}
pub fn visit_children(
&self,
mut visitor: impl FnMut(xml::writer::XmlEvent) -> xml::writer::Result<()>,
) -> xml::writer::Result<()> {
visit_children!(visitor);
Ok(())
}
}
impl<'a, I> TryFrom<crate::parser::ReadContext<'a, I>> for ParamPoly3
where
I: Iterator<Item = xml::reader::Result<xml::reader::XmlEvent>>,
{
type Error = Box<crate::parser::Error>;
fn try_from(mut read: crate::parser::ReadContext<'a, I>) -> Result<Self, Self::Error> {
read.expecting_no_child_elements_for(Self {
a_u: read.attribute("aU")?,
a_v: read.attribute("aV")?,
b_u: read.attribute("bU")?,
b_v: read.attribute("bV")?,
c_u: read.attribute("cU")?,
c_v: read.attribute("cV")?,
d_u: read.attribute("dU")?,
d_v: read.attribute("dV")?,
p_range: if cfg!(feature = "workaround-sumo-issue-10301") {
read.attribute_opt("pRange")?
.unwrap_or(ParamPoly3pRange::Normalized)
} else {
read.attribute("pRange")?
},
})
}
}
#[cfg(feature = "fuzzing")]
impl arbitrary::Arbitrary<'_> for ParamPoly3 {
fn arbitrary(u: &mut arbitrary::Unstructured) -> arbitrary::Result<Self> {
use crate::fuzzing::NotNan;
Ok(Self {
a_u: u.not_nan_f64()?,
a_v: u.not_nan_f64()?,
b_u: u.not_nan_f64()?,
b_v: u.not_nan_f64()?,
c_u: u.not_nan_f64()?,
c_v: u.not_nan_f64()?,
d_u: u.not_nan_f64()?,
d_v: u.not_nan_f64()?,
p_range: u.arbitrary()?,
})
}
}