ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/xyz2pov/src/pov_writer.c
Revision: 60
Committed: Thu Aug 1 21:12:33 2002 UTC (21 years, 11 months ago) by mmeineke
Content type: text/plain
Original Path: branches/mmeineke/xyz2pov/src/pov_writer.c
File size: 7920 byte(s)
Log Message:
A pair of utilities to turn an xyz file into a sequence of povray rendered images.

File Contents

# User Rev Content
1 mmeineke 60 #include <stdio.h>
2     #include <stdlib.h>
3     #include <string.h>
4     #include <math.h>
5    
6     #include "pov_writer.h"
7     #include "atom_parser.h"
8    
9     struct bond{
10     int i;
11     int j;
12     };
13    
14     struct linked_bond_list{
15     struct bond the_bond;
16     struct linked_bond_list *next;
17     };
18    
19     void make_bonds(struct coords *, int);
20    
21     struct linked_bond_list *bl_head;
22    
23     void clean_bonds(void);
24    
25    
26     void pov_write(FILE *out_file, struct coords *the_coords, int n_atoms,
27     int d_hydrogens, int d_bonds, int d_atoms){
28    
29     int i,j; /*loop counters */
30     int skip_atom, skip_bond, test1, test2; /*booleans */
31     double dx, dy, dz; /* used in making the bonds */
32    
33     struct linked_bond_list *current_bond; /*keeps track of the linked list*/
34    
35     for(i = 0; i < n_atoms; i++){
36     update_types(the_coords[i].name);
37     }
38    
39     if(d_atoms){
40    
41     fprintf(out_file,
42     "//************************************************************\n"
43     "// The list of atoms\n"
44     "//************************************************************\n"
45     "\n"
46     "\n");
47    
48     for(i = 0; i < n_atoms; i++){
49    
50     skip_atom = 0;
51    
52     if(!d_hydrogens){
53     skip_atom = !strcmp("H", the_coords[i].name);
54     }
55    
56     if(!skip_atom){
57    
58     fprintf(out_file,
59     "make_%s_atom( %lf, %lf, %lf )\n",
60     the_coords[i].name,
61     the_coords[i].x,
62     the_coords[i].z,
63     the_coords[i].y);
64     }
65     }
66    
67     fprintf(out_file,
68     "\n"
69     "\n");
70    
71     }
72    
73     if(d_bonds){
74    
75     fprintf(out_file,
76     "//************************************************************\n"
77     "// The list of bonds\n"
78     "//************************************************************\n"
79     "\n"
80     "\n");
81    
82     make_bonds(the_coords, n_atoms);
83    
84     current_bond = bl_head->next;
85    
86     while(current_bond != NULL){
87    
88     skip_bond = 0;
89    
90     i = current_bond->the_bond.i;
91     j = current_bond->the_bond.j;
92    
93     if(!d_hydrogens){
94    
95     test1 = !strcmp("H", the_coords[i].name);
96     test2 = !strcmp("H", the_coords[j].name);
97    
98     skip_bond = (test1 || test2);
99     }
100    
101     if(!skip_bond){
102    
103     dx = (the_coords[j].x - the_coords[i].x) / 2.0;
104     dy = (the_coords[j].y - the_coords[i].y) / 2.0;
105     dz = (the_coords[j].z - the_coords[i].z) / 2.0;
106    
107     fprintf(out_file,
108     "make_%s_bond( %lf, %lf, %lf, %lf, %lf, %lf )\n",
109     the_coords[i].name,
110     the_coords[i].x,
111     the_coords[i].z,
112     the_coords[i].y,
113     (the_coords[i].x + dx),
114     (the_coords[i].z + dz),
115     (the_coords[i].y + dy));
116    
117     fprintf(out_file,
118     "make_%s_bond( %lf, %lf, %lf, %lf, %lf, %lf )\n",
119     the_coords[j].name,
120     the_coords[j].x,
121     the_coords[j].z,
122     the_coords[j].y,
123     (the_coords[j].x - dx),
124     (the_coords[j].z - dz),
125     (the_coords[j].y - dy));
126    
127     fprintf(out_file, "\n");
128     }
129    
130     current_bond = current_bond->next;
131     }
132    
133     clean_bonds();
134     }
135     }
136    
137    
138     void make_bonds(struct coords *the_coords, int n_atoms){
139    
140     int i, j; /*counters */
141     struct linked_bond_list *temp_bond; /*bond place holder */
142    
143     const double bond_fudge = 1.12; // a fudge factor
144     struct atom type_i, type_j; /* holds the atom types */
145    
146     int test; /* booleans */
147     double dx, dy, dz, dr2, dcv, dcv2; // used to determine bond existence
148    
149    
150     bl_head = (struct linked_bond_list *)malloc(sizeof(struct linked_bond_list));
151     bl_head->next = NULL;
152    
153     for(i = 0; i < (n_atoms - 1); i++){
154    
155     for(j = (i+1); j < n_atoms; j++){
156    
157     dx = the_coords[j].x - the_coords[i].x;
158     dy = the_coords[j].y - the_coords[i].y;
159     dz = the_coords[j].z - the_coords[i].z;
160    
161     dr2 = dx * dx + dy * dy + dz * dz;
162    
163     test = !findAtomType(the_coords[i].name, &type_i);
164     if(test){
165     fprintf(stderr, "Atom Type %s, not found!\n",
166     the_coords[i].name);
167     exit(8);
168     }
169    
170     test = !findAtomType(the_coords[j].name, &type_j);
171     if(test){
172     fprintf(stderr, "Atom Type %s, not found!\n",
173     the_coords[j].name);
174     exit(8);
175     }
176    
177    
178     dcv = bond_fudge * (type_i.covalentRadii + type_j.covalentRadii);
179     dcv2 = dcv * dcv;
180    
181     if(dr2 <= dcv2){
182    
183     temp_bond =
184     (struct linked_bond_list *)malloc(sizeof(struct linked_bond_list));
185    
186     bl_head->the_bond.i = i;
187     bl_head->the_bond.j = j;
188    
189     temp_bond->next = bl_head;
190     bl_head = temp_bond;
191     }
192     }
193     }
194     }
195    
196    
197     void clean_bonds(){
198     struct linked_bond_list *current_bond;
199     struct linked_bond_list *next_bond; /* place holders */
200    
201    
202     current_bond = bl_head->next;
203    
204     while(current_bond != NULL){
205    
206     next_bond = current_bond->next;
207     free(current_bond);
208     current_bond = next_bond;
209     }
210    
211     bl_head->next = NULL;
212     }
213    
214    
215     void make_header_macros(FILE *out_file){
216    
217     struct linked_atom *type_list; // list of all atom types
218     struct linked_atom *current_type; // current atom type
219    
220     char *name;
221     double red, green, blue;
222     double radius;
223    
224     type_list = get_type_list();
225     current_type = type_list->next;
226    
227     while(current_type != NULL){
228    
229     name = current_type->myAtom.name;
230     radius = current_type->myAtom.vanDerWallRadii;
231     red = ((double)current_type->myAtom.red) / 255.0;
232     green = ((double)current_type->myAtom.green) / 255.0;
233     blue = ((double)current_type->myAtom.blue) / 255.0;
234    
235    
236    
237     fprintf(out_file,
238     "//****************************************************\n"
239     "// DEFINE %s MACROS\n"
240     "//****************************************************\n"
241     "\n"
242     "#macro make_%s_bond "
243     "(end_1x, end_1y, end_1z, end_2x, end_2y, end_2z)\n"
244     "\n"
245     " #local x1 = end_1x;\n"
246     " #local y1 = end_1y;\n"
247     " #local z1 = end_1z;\n"
248     " #local x2 = end_2x;\n"
249     " #local y2 = end_2y;\n"
250     " #local z2 = end_2z;\n"
251     "\n"
252     " #if(ROTATE)\n"
253     " #local x1_new = A11 * x1 + A12 * y1 + A13 * z1;\n"
254     " #local y1_new = A21 * x1 + A22 * y1 + A23 * z1;\n"
255     " #local z1_new = A31 * x1 + A32 * y1 + A33 * z1;\n"
256     "\n"
257     " #local x2_new = A11 * x2 + A12 * y2 + A13 * z2;\n"
258     " #local y2_new = A21 * x2 + A22 * y2 + A23 * z2;\n"
259     " #local z2_new = A31 * x2 + A32 * y2 + A33 * z2;\n"
260     "\n"
261     " #else\n"
262     " #local x1_new = x1;"
263     " #local y1_new = y1;"
264     " #local z1_new = z1;"
265     "\n"
266     " #local x2_new = x2;"
267     " #local y2_new = y2;"
268     " #local z2_new = z2;"
269     "\n"
270     " #end\n"
271     "\n"
272     " cylinder{\n"
273     " < x1_new, y1_new, z1_new >,\n"
274     " < x2_new, y2_new, z2_new >,\n"
275     " BOND_RADIUS\n"
276     " texture{\n"
277     " pigment{ rgb < %lf, %lf, %lf > }\n"
278     " finish{\n"
279     " ambient .2\n"
280     " diffuse .6\n"
281     " specular 1\n"
282     " roughness .001\n"
283     " metallic\n"
284     " }\n"
285     " }\n"
286     " }\n"
287     "#end\n"
288     "#macro make_%s_atom "
289     "(center_x, center_y, center_z)\n"
290     "\n"
291     " #local x1 = center_x;\n"
292     " #local y1 = center_y;\n"
293     " #local z1 = center_z;\n"
294     "\n"
295     " #if(ROTATE)\n"
296     "\n"
297     " #local x1_new = A11 * x1 + A12 * y1 + A13 * z1;\n"
298     " #local y1_new = A21 * x1 + A22 * y1 + A23 * z1;\n"
299     " #local z1_new = A31 * x1 + A32 * y1 + A33 * z1;\n"
300     "\n"
301     " #else\n"
302     "\n"
303     " #local x1_new = x1;"
304     " #local y1_new = y1;"
305     " #local z1_new = z1;"
306     "\n"
307     " #end\n"
308     "\n"
309     " sphere{\n"
310     " < x1_new, y1_new, z1_new >,\n"
311     " ATOM_SPHERE_FACTOR * %lf\n"
312     " texture{\n"
313     " pigment{ rgb < %lf, %lf, %lf > }\n"
314     " finish{\n"
315     " ambient .2\n"
316     " diffuse .6\n"
317     " specular 1\n"
318     " roughness .001\n"
319     " metallic\n"
320     " }\n"
321     " }\n"
322     " }\n"
323     "#end\n"
324     "\n"
325     "\n",
326     name,
327     name,
328     red, green, blue,
329     name,
330     radius,
331     red, green, blue);
332    
333     current_type = current_type->next;
334     }
335     }