chemrust_nasl/coordination_sites/
visualize.rs1use std::f64::consts::FRAC_PI_2;
2
3use castep_periodic_table::element::ElementSymbol;
4use chemrust_core::data::geom::coordinates::CoordData;
5use nalgebra::{Matrix3, Point3, Vector3};
6
7use crate::DelegatePoint;
8
9use super::{CoordCircle, CoordSphere, MultiCoordPoint};
10
11pub trait Visualize {
12 type Output;
13 fn determine_coord(&self) -> Point3<f64>;
14 fn element_by_cn_number(&self) -> ElementSymbol;
15 fn draw_with_element(&self, element_symbol: ElementSymbol) -> Self::Output;
16 fn fractional_coord(&self, cell_tensor: Matrix3<f64>) -> Point3<f64> {
17 cell_tensor.try_inverse().expect("Matrix is not invertible") * self.determine_coord()
18 }
19}
20
21#[derive(Debug, Clone, Copy)]
22pub struct Atom {
23 symbol: ElementSymbol,
24 coord: CoordData,
25}
26
27impl Atom {
28 pub fn new(symbol: ElementSymbol, coord: CoordData) -> Self {
29 Self { symbol, coord }
30 }
31
32 pub fn coord(&self) -> CoordData {
33 self.coord
34 }
35
36 pub fn symbol(&self) -> ElementSymbol {
37 self.symbol
38 }
39}
40
41impl Visualize for CoordSphere {
42 type Output = Atom;
43
44 fn draw_with_element(&self, element_symbol: ElementSymbol) -> Self::Output {
45 let coord = CoordData::Cartesian(self.determine_coord());
46 Atom::new(element_symbol, coord)
47 }
48
49 fn determine_coord(&self) -> Point3<f64> {
50 let center = self.sphere.center();
51 let z_shift = Vector3::z_axis().scale(self.sphere.radius());
52 center + z_shift
53 }
54
55 fn element_by_cn_number(&self) -> ElementSymbol {
56 ElementSymbol::Xe
57 }
58}
59
60impl Visualize for CoordCircle {
61 type Output = Atom;
62
63 fn draw_with_element(&self, element_symbol: ElementSymbol) -> Self::Output {
64 Atom::new(element_symbol, CoordData::Cartesian(self.determine_coord()))
65 }
66
67 fn determine_coord(&self) -> Point3<f64> {
68 self.circle().get_point_on_circle(FRAC_PI_2)
69 }
70
71 fn element_by_cn_number(&self) -> ElementSymbol {
72 ElementSymbol::Ne
73 }
74}
75
76impl Visualize for MultiCoordPoint {
77 type Output = Atom;
78
79 fn draw_with_element(&self, element_symbol: ElementSymbol) -> Self::Output {
80 Atom::new(element_symbol, CoordData::Cartesian(self.determine_coord()))
81 }
82
83 fn determine_coord(&self) -> Point3<f64> {
84 self.point
85 }
86
87 fn element_by_cn_number(&self) -> ElementSymbol {
88 if self.atom_ids().len() < 104 {
89 ElementSymbol::try_from(self.atom_ids().len() as u8).unwrap_or(ElementSymbol::W)
90 } else {
91 ElementSymbol::Np
92 }
93 }
94}
95
96impl<const N: usize> Visualize for DelegatePoint<N> {
97 type Output = Atom;
98
99 fn determine_coord(&self) -> Point3<f64> {
100 self.point
101 }
102
103 fn element_by_cn_number(&self) -> ElementSymbol {
104 ElementSymbol::Xe
105 }
106
107 fn draw_with_element(&self, element_symbol: ElementSymbol) -> Self::Output {
108 Atom::new(element_symbol, CoordData::Cartesian(self.determine_coord()))
109 }
110}