use crate::{model_type::ModelInfo, Transformation};
use std::cmp::Ordering;
use na::Point3;
#[derive(Debug, Clone)]
pub struct Atom<T: ModelInfo> {
element_symbol: String,
element_id: u32,
xyz: Point3<f64>,
fractional_xyz: Option<Point3<f64>>,
atom_id: u32,
format_type: T,
}
impl<T> Atom<T>
where
T: ModelInfo,
{
pub fn new(
element_symbol: String,
element_id: u32,
xyz: Point3<f64>,
atom_id: u32,
model_type: T,
) -> Self {
Self {
element_symbol,
element_id,
xyz,
fractional_xyz: None,
atom_id,
format_type: model_type,
}
}
pub fn element_symbol(&self) -> &str {
self.element_symbol.as_ref()
}
pub fn set_element_symbol(&mut self, element_symbol: String) {
self.element_symbol = element_symbol;
}
pub fn element_id(&self) -> u32 {
self.element_id
}
pub fn set_element_id(&mut self, element_id: u32) {
self.element_id = element_id;
}
pub fn xyz(&self) -> &Point3<f64> {
&self.xyz
}
pub fn set_xyz(&mut self, xyz: Point3<f64>) {
self.xyz = xyz;
}
pub fn atom_id(&self) -> u32 {
self.atom_id
}
pub fn set_atom_id(&mut self, atom_id: u32) {
self.atom_id = atom_id;
}
pub fn model_type(&self) -> &T {
&self.format_type
}
pub fn set_model_type(&mut self, model_type: T) {
self.format_type = model_type;
}
pub fn fractional_xyz(&self) -> Option<&Point3<f64>> {
self.fractional_xyz.as_ref()
}
pub fn set_fractional_xyz(&mut self, fractional_xyz: Option<Point3<f64>>) {
self.fractional_xyz = fractional_xyz;
}
}
impl<T> Transformation for Atom<T>
where
T: ModelInfo,
{
fn rotate(&mut self, rotate_quatd: &na::UnitQuaternion<f64>) {
self.set_xyz(rotate_quatd.transform_point(self.xyz()))
}
fn translate(&mut self, translate_matrix: &na::Translation<f64, 3>) {
self.set_xyz(translate_matrix.transform_point(self.xyz()))
}
}
impl<T> Ord for Atom<T>
where
T: ModelInfo,
{
fn cmp(&self, other: &Self) -> Ordering {
self.atom_id.cmp(&other.atom_id)
}
}
impl<T> PartialOrd for Atom<T>
where
T: ModelInfo,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T> PartialEq for Atom<T>
where
T: ModelInfo,
{
fn eq(&self, other: &Self) -> bool {
self.atom_id == other.atom_id
}
}
impl<T> Eq for Atom<T> where T: ModelInfo {}