@@ -20,6 +20,7 @@ use hexasphere::{shapes::IcoSphereBase, AdjacencyBuilder, Subdivided};
2020use itertools:: Itertools ;
2121use nalgebra:: Matrix3 ;
2222use std:: io:: Write ;
23+ use std:: path:: Path ;
2324use std:: sync:: OnceLock ;
2425
2526/// A icotable where each vertex holds an icotable of floats
@@ -119,6 +120,32 @@ pub struct IcoTable<T: Clone + GetSize> {
119120 pub vertices : Vec < Vertex < T > > ,
120121}
121122
123+ /// Draw icosahedron to a Visual Molecular Dynamics (VMD) TCL script
124+ /// Visialize with: `vmd -e script.vmd`
125+ pub ( crate ) fn vmd_draw (
126+ path : & Path ,
127+ icosphere : Subdivided < ( ) , IcoSphereBase > ,
128+ color : & str ,
129+ scale : Option < f32 > ,
130+ ) -> anyhow:: Result < ( ) > {
131+ let num_faces = icosphere. get_all_indices ( ) . len ( ) / 3 ;
132+ let path = path. with_extension ( format ! ( "faces{}.vmd" , num_faces) ) ;
133+ let mut stream = std:: fs:: File :: create ( path) ?;
134+ icosphere. get_all_indices ( ) . chunks ( 3 ) . try_for_each ( |c| {
135+ let scale = scale. unwrap_or ( 1.0 ) ;
136+ let a = icosphere. raw_points ( ) [ c[ 0 ] as usize ] * scale;
137+ let b = icosphere. raw_points ( ) [ c[ 1 ] as usize ] * scale;
138+ let c = icosphere. raw_points ( ) [ c[ 2 ] as usize ] * scale;
139+ writeln ! ( stream, "draw color {}" , color) ?;
140+ writeln ! (
141+ stream,
142+ "draw triangle {{{:.3} {:.3} {:.3}}} {{{:.3} {:.3} {:.3}}} {{{:.3} {:.3} {:.3}}}" ,
143+ a. x, a. y, a. z, b. x, b. y, b. z, c. x, c. y, c. z
144+ )
145+ } ) ?;
146+ Ok ( ( ) )
147+ }
148+
122149impl < T : Clone + GetSize > IcoTable < T > {
123150 /// Generate table based on an existing subdivided icosaedron
124151 pub fn from_icosphere_without_data ( icosphere : Subdivided < ( ) , IcoSphereBase > ) -> Self {
@@ -132,6 +159,8 @@ impl<T: Clone + GetSize> IcoTable<T> {
132159 . map ( |p| Vector3 :: new ( p. x as f64 , p. y as f64 , p. z as f64 ) )
133160 . collect ( ) ;
134161
162+ vmd_draw ( Path :: new ( "icosphere.vmd" ) , icosphere, "green" , Some ( 10.0 ) ) . unwrap ( ) ;
163+
135164 let vertices = ( 0 ..vertex_positions. len ( ) )
136165 . map ( |i| {
137166 Vertex :: without_data (
@@ -433,23 +462,6 @@ impl IcoTableOfSpheres {
433462 }
434463}
435464
436- /// Draw a triangle in VMD format
437- fn _vmd_draw_triangle (
438- stream : & mut impl Write ,
439- a : & Vector3 ,
440- b : & Vector3 ,
441- c : & Vector3 ,
442- color : & str ,
443- ) -> Result < ( ) > {
444- writeln ! ( stream, "draw color {}" , color) ?;
445- writeln ! (
446- stream,
447- "draw triangle {{{:.3} {:.3} {:.3}}} {{{:.3} {:.3} {:.3}}} {{{:.3} {:.3} {:.3}}}" ,
448- a. x, a. y, a. z, b. x, b. y, b. z, c. x, c. y, c. z
449- ) ?;
450- Ok ( ( ) )
451- }
452-
453465#[ cfg( test) ]
454466mod tests {
455467 use super :: * ;
0 commit comments