| Bsoft 2.0.5 Bernard's software package

model_poly_spiral.cpp
Go to the documentation of this file.
1
9 #include "rwmodel.h"
10 #include "model_poly.h"
11 #include "model_poly_spiral.h"
12 #include "model_mechanics.h"
13 #include "model_links.h"
14 #include "model_transform.h"
15 #include "model_util.h"
16 #include "Matrix.h"
17 #include "math_util.h"
18 #include "linked_list.h"
19 #include "Vector3.h"
20 #include "utilities.h"
21
22 #include <sys/stat.h>
23 #include <fcntl.h>
24
25 // Declaration of global variables
26 extern int verbose; // Level of output to the screen
27
28 /*
29 @brief Adds a polygon to a model based on the spiral algorithm.
30
31 If there are no components, a new polygon is generated.
32 The next polygon is attached to the last component.
33
34 @param n polygon order = number of vertices.
35 @param valence vertex valence.
36 @param *model model structure.
37 @return int number of components saturated with respect to polygons.
38 **/
39 int polygon_add(int n, int valence, Bmodel* model)
40 {
41 int i, j, mid = 0, unsat, nsat;
42 int sat = valence - 1;
43 Bstring id;
44 Bstring comptype = "VER";
45 Bcomponent* comp = model->comp;
46 Bcomponent* comp2 = NULL;
47 Bcomponent* comp3 = NULL;
48 Bcomponent* complist[10];
49 Blink* link = model->link;
50
51 if ( verbose & VERB_PROCESS )
52 cout << "Adding polygon: " << n << ":" << endl;
53 Bpolygon* poly = (Bpolygon *) add_item((char **) &model->poly, sizeof(Bpolygon));
54
55 poly->sel = 1;
56
57 for ( comp2 = model->comp, comp = NULL; comp2; comp2 = comp2->next )
58 if ( !comp2->link[sat] ) comp = comp2; // Find the last vertex with unsaturated valency
59
60 if ( !model->comp ) { // Create the first polygon
61 for ( i=mid=0; i<n; i++ ) {
62 id = Bstring(++mid, "%d");
63 comp = component_add(&comp, id);
64 if ( !model->comp ) model->comp = comp;
65 comp->type = model_add_type_by_id(model, comptype);
66 comp->sel = 1; // Member of one polygon
67 if ( verbose & VERB_FULL )
68 cout << "Adding vertex: " << id << endl;
69 poly->comp[i] = comp;
70 poly->number++;
71 if ( i ) {
72 link = link_add(&link, comp2, comp, 1, 1);
73 if ( !model->link ) model->link = link;
74 if ( verbose & VERB_FULL )
75 cout << "Adding link: " << comp2->id << " - " << comp->id << endl;
76 }
77 comp2 = comp;
78 }
79 link = link_add(&link, model->comp, comp, 1, 1);
80 poly->closed = 1;
81 if ( verbose & VERB_FULL )
82 cout << "Adding link: " << model->comp->id << " - " << comp->id << endl;
83 } else if ( !comp ) { // Add the last polygon
84 for ( comp = model->comp; comp && comp->sel > sat; comp = comp->next ) ; // Find the first vertex with less than 3 polygons
85 if ( comp ) {
86 poly->comp[0] = comp;
87 poly->number++;
88 comp->sel++;
89 for ( i = 1; i<n && comp; i++ ) {
90 for ( j=0; comp->link[j] && comp->link[j]->sel > sat; j++ ) ; // Find the next vertex with less than 3 polygons
91 if ( j < valence ) {
92 comp = comp->link[j];
93 poly->comp[i] = comp;
94 poly->number++;
95 comp->sel++;
96 } else comp = NULL; // Polygon not complete
97 }
98 if ( comp ) {
99 poly->closed = 1;
100 }
101 }
102 } else {
103 // for ( mid=0, comp2 = model->comp; comp2; comp2 = comp2->next ) mid++;
104 for ( mid=0, comp2 = model->comp; comp2; comp2 = comp2->next ) {
105 i = comp2->id.integer();
106 if ( mid < i ) mid = i;
107 }
108 comp2 = comp; // Polygon end component
109 complist[0] = comp;
110 for ( j=0; comp2->link[j]; j++ ) ; // Find the last link of the last vertex
111 j--;
112 if ( j < 0 ) {
113 cerr << "Error: " << comp2->id << " does not have any links!" << endl;
114 bexit(-1);
115 }
116 if ( verbose & VERB_FULL )
117 cout << "Trace:\t\t" << comp2->id;
118 for ( unsat = 0, i = 1; i<n && unsat == 0 && comp2; i++ ) { // Trace to the start component
119 if ( i > 1 )
120 for ( j=0; comp2->link[j]; j++ ) // Find the next vertex with less than 3 polygons
121 if ( comp2->link[j] != comp3 && comp2->link[j]->sel < valence ) break;
122 if ( j > sat ) {
123 if ( verbose & VERB_FULL ) {
124 cerr << endl << "Error: No link with the required properties" << endl;
125 cerr << "Component: " << comp2->id << endl;
126 for ( j=0; comp2->link[j]; j++ )
127 cerr << "Link: " << comp2->link[j]->id << " Flag: "
128 << comp2->flag[j] << " Select: " << comp2->link[j]->sel << endl;
129 }
130 comp2 = NULL;
131 } else {
132 comp3 = comp2;
133 comp2 = comp2->link[j];
134 complist[i] = comp2;
135 if ( !comp2->link[sat] ) unsat = 1; // Finish when a vertex with unsaturated valency is found
136 if ( verbose & VERB_FULL )
137 cout << tab << comp2->id;
138 }
139 }
140 if ( verbose & VERB_FULL )
141 cout << endl;
142 if ( comp2 ) {
143 if ( verbose & VERB_FULL )
144 cout << "Backtrace:";
145 for ( j=i-1, i=0; j>=0; j--, i++ ) {
146 poly->comp[i] = complist[j];
147 poly->number++;
148 poly->comp[i]->sel++;
149 if ( verbose & VERB_FULL )
150 cout << tab << poly->comp[i]->id;
151 }
152 if ( verbose & VERB_FULL )
153 cout << endl;
154 comp3 = comp;
155 for ( ; i<n; i++ ) { // New vertices
156 id = Bstring(++mid, "%d");
157 comp3 = component_add(&comp3, id);
158 comp3->type = model_add_type_by_id(model, comptype);
159 comp3->sel = 1; // Member of one polygon
160 if ( verbose & VERB_FULL )
161 cout << "Adding vertex: " << id << endl;
162 poly->comp[i] = comp3;
163 poly->number++;
164 link = link_add(&link, comp, comp3, 1, 1);
165 if ( verbose & VERB_FULL )
166 cout << "Adding link: " << comp->id << " - " << comp3->id << endl;
167 comp = comp3;
168 }
169 link = link_add(&link, comp, comp2, 1, 1);
170 poly->closed = 1;
171 if ( verbose & VERB_FULL )
172 cout << "Adding link: " << comp->id << " - " << comp2->id << endl;
173 }
174 }
175
176 for ( nsat=0, comp = model->comp; comp; comp = comp->next ) {
177 if ( comp->sel == valence ) nsat++;
178 else if ( comp->sel > valence ) {
179 if ( verbose & VERB_FULL )
180 cerr << "Error: Valence too large for " << comp->id << ": " << comp->sel << " > " << valence << endl;
181 nsat += 100;
182 // bexit(-1);
183 }
184 }
185
186 if ( verbose & VERB_FULL ) {
187 if ( poly->number != n )
188 cerr << "Error: Polygon incomplete: " << poly->number << "/" << n << endl;
189 if ( !poly->closed )
190 cerr << "Error: Polygon not closed" << endl;
191 }
192
193 return nsat;
194 }
195
196 int seq_count_adj_pentagons(Bstring& seq)
197 {
198 int i, j, adj = 0;
199
200 for ( i=0, j=1; j<seq.length(); i++, j++ )
201 if ( seq[i] == '5' && seq[j] == '5' ) adj++;
202
203 return adj;
204 }
205
206 int model_vertex_types_in_first_polygons(Bmodel* model, int npoly)
207 {
208 int i, j, n;
209 Bmodel* mp;
210 Bcomponent* comp;
211 Bpolygon* poly;
212
213
214 for ( mp = model; mp; mp = mp->next ) {
215 for ( n=0, poly = mp->poly; poly && n<npoly; poly = poly->next, n++ ) {
216 for ( i=0; poly->comp[i]; i++ ) {
217 if ( i+1 < poly->number ) comp = poly->comp[i+1];
218 else comp = poly->comp[0];
219 for ( j=0; poly->comp[i]->link[j] != comp; j++ ) ;
220 poly->comp[i]->flag[j] = poly->number;
221 }
222 }
223 }
224
225 return 0;
226 }
227
228 int model_adjacent_pentagons(Bmodel* model)
229 {
230 int i, n, adj = 0;
231 Bcomponent* comp;
232
233 model_vertex_types(model);
234
235 for ( comp = model->comp; comp; comp = comp->next ) {
236 for ( i=n=0; comp->link[i]; i++ ) if ( comp->flag[i] == 5 ) n++;
237 if ( n > 1 ) adj++;
238 }
239
240 return adj;
241 }
242
243 int model_adjacent_pentagons_in_first_polygons(Bmodel* model, int npoly)
244 {
245 int i, n, adj = 0;
246 Bcomponent* comp;
247
248 model_vertex_types_in_first_polygons(model, npoly);
249
250 for ( comp = model->comp; comp; comp = comp->next ) {
251 for ( i=n=0; comp->link[i]; i++ ) if ( comp->flag[i] == 5 ) n++;
252 if ( n > 1 ) adj++;
253 }
254
255 return adj;
256 }
257
274 Bmodel* model_poly_spiral(Bstring& seq, int valence, int requirements)
275 {
276 int npoly = seq.length();
277 int vertices = 20 + 2*(npoly - 12);
278
279 Bmodel* model = model_init(seq);
280
281 int i, nvert = 1, nsat = 0, adj = 0, good = 1;
282
283 for ( i=1; nsat < nvert && i<=npoly; i++ ) {
284 nvert = seq[i-1]-48;
285 if ( verbose & VERB_PROCESS )
286 cout << "Polygon " << i << ":\t" << nvert << endl;
287 nsat = polygon_add(nvert, valence, model);
288 nvert = model_component_count(model);
289 if ( verbose & VERB_PROCESS )
290 cout << "Saturation:\t" << nsat << "/" << nvert << endl;
291 }
292
293 if ( ( i = model_polyhedron_check(model, valence) ) ) good = 0;
294 if ( requirements%2 == 1 ) if ( nvert != vertices ) good = 0;
295 if ( requirements > 1 ) if ( model_adjacent_pentagons(model) ) good = 0;
296
297 if ( !good ) {
298 if ( verbose & VERB_FULL ) {
299 cout << "Model rejected:";
300 if ( nvert != vertices )
301 cout << "\tvertices = " << nvert << endl;
302 else if ( nsat > nvert )
303 cout << "\tsaturation = " << nsat << " > " << nvert << endl;
304 else if ( adj )
305 cout << "\tadjacent pentagons = " << adj << endl;
306 else
307 cout << "\tcheck = " << i << endl;
308 cout << seq << endl;
309 }
310 model_kill(model);
311 model = NULL;
312 }
313
314 return model;
315 }
316
317 int model_poly_spiral_regularize(Bmodel* model)
318 {
319 model_set_link_length(model, 1);
320
321 return model_regularize(model, 10000, 0, 0, 0.2, 0.001, 0, 0, 0.1, 0.01);
322 }
323
336 int model_polyhedron_check(Bmodel* model, int valence)
337 {
338 int j, ncomp = 0, nlink = 0, npoly = 0, err = 0;
339 Bmodel* mp;
340 Bcomponent* comp = NULL;
341 Blink* link = NULL;
342 Bpolygon* poly = NULL;
343
344 if ( verbose & VERB_PROCESS )
345 cout << endl << "Checking the model:" << endl;
346
347 for ( ncomp=nlink=npoly=0, mp = model; mp; mp = mp->next ) {
348 for ( comp = mp->comp; comp; comp = comp->next, ncomp++ ) {
349 if ( comp->sel != valence ) {
350 if ( verbose & VERB_PROCESS )
351 cerr << comp->id << ": select = " << comp->sel << endl;
352 err++;
353 }
354 for ( j=0; comp->link[j]; j++ ) ;
355 if ( j != valence ) {
356 if ( verbose & VERB_PROCESS )
357 cerr << comp->id << ": valency = " << j << endl;
358 err++;
359 }
360 }
361 for ( link = mp->link; link; link = link->next, nlink++ ) ;
362 for ( poly = mp->poly; poly; poly = poly->next, npoly++ )
363 if ( !poly->closed ) {
364 if ( verbose & VERB_PROCESS )
365 cerr << npoly << ": polygon not closed!" << endl;
366 err++;
367 }
368 }
369
370 if ( ncomp - nlink + npoly != 2 ) {
371 if ( verbose & VERB_PROCESS )
372 cerr << "Euler's formula incorrect: " << ncomp << " - " << nlink << " + "
373 << npoly << " = " << ncomp - nlink + npoly << endl;
374 err++;
375 }
376
377 if ( verbose & VERB_PROCESS ) {
378 cout << "Number of components: " << ncomp << endl;
379 cout << "Number of links: " << nlink << endl;
380 cout << "Number of polygons: " << npoly << endl;
381 cout << "Errors: " << err << endl << endl;
382 }
383
384 return err;
385 }
386
399 Bmodel* model_poly_gen_sequence(Bstring& seq, int valence, int enantiomorph, int requirements, int nm)
400 {
401 return model_poly_gen_sequence(seq, valence, enantiomorph, requirements, nm, NULL);
402 }
403
419 Bmodel* model_poly_gen_sequence(Bstring& seq, int valence, int enantiomorph, int requirements, int nm, double* table)
420 {
421 int j = 0, k;
422 int d = 1, enant = 1;
423 Vector3<double> origin, normal(1,0,0);
424 Bstring sym_label("C1");
425
426 int vertices = 20 + 2*(seq.length() - 12);
427
428 Bstring id = Bstring(vertices, "%d_");
429
430 if ( verbose & VERB_PROCESS )
431 cout << nm+1 << ": " << seq << endl;
432
433 Bmodel* model = model_poly_spiral(seq, valence, requirements);
434 if ( !model ) return model;
435
436 vector<double> eigval = model_poly_sphere_coor(model);
437
438 if ( table ) {
439 if ( nm )
440 for ( j=0, d=1; j<nm*vertices && table[j] && d; j+=vertices )
441 for ( k=0, d=0; k<vertices; k++ )
442 if ( fabs(eigval[k] - table[j+k]) > 1e-6 ) d++;
443 if ( d ) for ( k=0; k<vertices; j++, k++ )
444 table[j] = eigval[k];
445 else
446 id += Bstring(j/vertices, "%04d");
447 }
448
449 // delete[] eigval;
450
451 if ( !d ) {
452 model_kill(model);
453 if ( verbose )
454 // cout << "Model rejected because of redundancy" << endl;
455 cout << id << tab << seq << endl;
456 return NULL;
457 }
458
459 id = Bstring(count_list((char *)model->comp), "%d_");
460 model->id = id + Bstring(++nm, "%04d");
461 model->type_id = model->id;
462 model_poly_spiral_regularize(model);
463 sym_label = model_poly_find_symmetry(model, 0.1);
464
465 if ( verbose )
466 cout << model->id << tab << seq << endl;
467
468 model_set_component_radius(model, 0.1);
469 model_set_link_radius(model, 0.1);
470
471 Bstring filename = "temp/" + model->id + ".cmm";
472 write_model(filename, model);
473
474 if ( enantiomorph ) {
475 if ( sym_label.contains("s") || sym_label.contains("v") ||
476 sym_label.contains("d") || sym_label.contains("h") ) enant = 0;
477 if ( enant ) {
478 model->next = model_copy(model);
479 model->next->id = id + Bstring(++nm, "%04d");
480 model_reflect(model->next, normal, origin);
481 }
482 }
483
484 return model;
485 }
486
494 Bmodel* model_poly_gen_permutations(int vertices, int valence, int enantiomorph)
495 {
496 long nt = (long) pow(10, (4*(log(1.0L*vertices) - 3.1))); // Maximum number of comparison table entries
497 if ( verbose )
498 cout << "Generating polyhedra with permutations:" << endl <<
499 "Vertices = " << vertices << " Table rows = " << nt << endl;
500 if ( nt < 100 ) nt = 100;
501 if ( nt > 1e8 ) {
502 cerr << "The number of table entries is too large! (" << nt << ")" << endl;
503 return NULL;
504 }
505
506 int i, np = 1, nm = 0;
507 double* table = new double[nt*vertices];
508 Bstring seq = "555555555555"; // Initial sequence
509 for ( i=0; i<(vertices-20)/2; i++ ) seq += '6';
510 for ( i=0; i<nt*vertices; i++ ) table[i] = 0;
511
512 if ( verbose & VERB_DEBUG )
513 cout << "DEBUG model_poly_gen_permutations: " << i << ": " << seq << ": start" << endl;
514
515 Bmodel* model = NULL;
516 Bmodel* mp = NULL;
517 Bmodel* new_mp = NULL;
518
519 for ( i=1, nm=0; np; i++ ) {
520 new_mp = model_poly_gen_sequence(seq, valence, enantiomorph, 1, nm, table);
521 if ( new_mp ) {
522 if ( !model ) model = new_mp;
523 else mp->next = new_mp;
524 mp = new_mp;
525 nm++;
526 if ( verbose )
527 cout << mp->id << " " << i << ": " << seq << ": " << mp->symmetry << endl;
528 if ( new_mp->next ) {
529 mp = new_mp->next;
530 nm++;
531 if ( verbose )
532 cout << mp->id << " " << i << ": " << seq << ": " << mp->symmetry << endl;
533 }
534 }
535 np = next_permutation(seq);
536 }
537
538 delete[] table;
539
540 for ( nm=0, mp = model; mp; mp = mp->next ) nm++;
541 if ( verbose )
542 cout << "Models made: " << nm << "/" << --i << endl << endl;
543
544 return model;
545 }
546
557 Bmodel* model_poly_gen_cone(int tip, int body, int base, int valence, int enantiomorph, int requirements)
558 {
559 if ( tip < 6 ) tip = 6;
560 if ( body < 1 ) body = 1;
561 if ( base < 15 ) base = 15;
562
563 int i;
564 Bstring stip;
565 // Bstring sbody(body, '6');
566 Bstring sbody('6', body);
567 Bstring sbase;
568
569 // Tip starting cases
570 int type = 4;
571 switch ( type ) {
572 case 1: stip = "5666665656565"; break;
573 case 2: stip = "56666656566565"; break;
574 case 3: stip = "56666665656565"; break;
575 case 4: stip = "665656565665"; break; // Equivalent of 1
576 case 5: stip = "6666565656565"; break;
577 // default: stip = Bstring(5, '5') + Bstring(tip-5, '6');
578 default: stip = Bstring('5', 5) + Bstring('6', tip-5);
579 }
580 while ( stip.length() < tip ) stip += "6";
581
582 for ( i=0; i<7; i++ ) sbase += "56";
583 // sbase += Bstring(base-14, '6');
584 sbase += Bstring('6', base-14);
585
586 return model_poly_gen_3part(stip, sbody, sbase, valence, enantiomorph, requirements);
587 }
588
598 Bmodel* model_poly_gen_lozenge(int ttop, int tbody, int valence, int enantiomorph, int requirements)
599 {
600 int i, j, h, k, vertices, nm, nt;
601 int top = 1 + (5*ttop*(ttop + 1))/2;
602 int dm = (5*ttop + 1)/2;
603 int body = tbody*dm;
604
605 Bstring stip, sbody, sbase;
606 Bstring stip_rpt, sbase_rpt;
607 Bstring seq;
608
609 Bmodel* model = NULL;
610 Bmodel* mp = NULL;
611 Bmodel* new_mp = NULL;
612
613 for ( nm=0, nt=1, i=0; i<ttop; i++ ) {
614 stip_rpt = 0;
615 for ( k=0; k<i; k++ ) stip_rpt += "6";
616 stip_rpt += "5";
617 for ( k++; k<ttop; k++ ) stip_rpt += "6";
618 stip = "5";
619 // stip += Bstring(top - 1 - 5*ttop, '6');
620 stip += Bstring('6', top - 1 - 5*ttop);
621 for ( k=0; k<5; k++ ) stip += stip_rpt;
622 for ( h=body; h<=body+2*dm; h++ ) {
623 // if ( h ) sbody = Bstring(body+h, '6');
624 if ( h ) sbody = Bstring('6', body+h);
625 for ( j=0; j<ttop; j++, nt++ ) {
626 sbase_rpt = 0;
627 for ( k=0; k<j; k++ ) sbase_rpt += "6";
628 sbase_rpt += "5";
629 for ( k++; k<ttop; k++ ) sbase_rpt += "6";
630 sbase = 0;
631 for ( k=0; k<5; k++ ) sbase += sbase_rpt;
632 // sbase += Bstring(top - 1 - 5*ttop, '6');
633 sbase += Bstring('6', top - 1 - 5*ttop);
634 sbase += "5";
635 seq = stip + sbody + sbase;
636 new_mp = model_poly_gen_sequence(seq, valence, enantiomorph, requirements, nm);
637 if ( new_mp ) {
638 vertices = 20 + 2*(seq.length() - 12);
639 new_mp->id = Bstring(vertices, "%d_") + Bstring(++nm, "%04d");
640 cout << new_mp->id << " " << nt << ": " << seq << ": " << new_mp->symmetry << endl;
641 if ( mp ) mp->next = new_mp;
642 else model = new_mp;
643 mp = new_mp;
644 }
645 }
646 }
647 }
648
649 cout << "Models made: " << nm << "/" << --nt << endl << endl;
650
651 return model;
652 }
653
665 Bmodel* model_poly_gen_coffin(int ttop, int tbody, int tbase, int valence, int enantiomorph, int requirements)
666 {
667 int i, j, h, k, vertices, nm, nt;
668 int top = 1 + (5*ttop*(ttop + 1))/2;
669 int dm = (5*ttop + 6*tbase + 1)/2;
670 int body = tbody*dm;
671 int base = 1 + 3*tbase*(tbase + 1);
672
673 Bstring stip, sbody, sbase;
674 Bstring stip_rpt, sbase_rpt;
675 Bstring seq;
676
677 Bmodel* model = NULL;
678 Bmodel* mp = NULL;
679 Bmodel* new_mp = NULL;
680
681 for ( nm=0, nt=1, i=0; i<ttop; i++ ) {
682 stip_rpt = 0;
683 for ( k=0; k<i; k++ ) stip_rpt += "6";
684 stip_rpt += "5";
685 for ( k++; k<ttop; k++ ) stip_rpt += "6";
686 stip = "5";
687 // stip += Bstring(top - 1 - 5*ttop, '6');
688 stip += Bstring('6', top - 1 - 5*ttop);
689 for ( k=0; k<5; k++ ) stip += stip_rpt;
690 for ( h=0; h<dm; h++ ) {
691 // sbody = Bstring(body+h, '6');
692 sbody = Bstring('6', body+h);
693 for ( j=0; j<tbase; j++, nt++ ) {
694 sbase_rpt = 0;
695 for ( k=0; k<j; k++ ) sbase_rpt += "6";
696 sbase_rpt += "5";
697 for ( k++; k<tbase; k++ ) sbase_rpt += "6";
698 sbase = 0;
699 for ( k=0; k<6; k++ ) sbase += sbase_rpt;
700 // sbase += Bstring(base - 6*tbase, '6');
701 sbase += Bstring('6', base - 6*tbase);
702 seq = stip + sbody + sbase;
703 new_mp = model_poly_gen_sequence(seq, valence, enantiomorph, requirements, nm);
704 if ( new_mp ) {
705 vertices = 20 + 2*(seq.length() - 12);
706 new_mp->id = Bstring(vertices, "%d_") + Bstring(++nm, "%04d");
707 cout << new_mp->id << " " << nt << ": " << seq << ": " << new_mp->symmetry << endl;
708 if ( mp ) mp->next = new_mp;
709 else model = new_mp;
710 mp = new_mp;
711 }
712 }
713 }
714 }
715
716 cout << "Models made: " << nm << "/" << --nt << endl << endl;
717
718 return model;
719 }
720
732 Bmodel* model_poly_gen_coffin_loose(int ttop, int tbody, int tbase, int valence, int enantiomorph, int requirements)
733 {
734 int i;
735 int top = 1 + (5*ttop*(ttop + 1))/2;
736 int body = tbody*(5*ttop + 6*tbase + 1)/2;
737 int base = 1 + 3*tbase*(tbase + 1);
738
739 Bstring stip("5");
740 // Bstring sbody(body, '6');
741 Bstring sbody('6', body);
742 Bstring sbase;
743 Bstring stip_rpt("5");
744 Bstring sbase_rpt("5");
745
746 for ( i=1; i<ttop; i++ ) stip_rpt += "6";
747 for ( i=1; i<tbase; i++ ) sbase_rpt += "6";
748
749 // stip += Bstring(top - 1 - 5*ttop, '6');
750 stip += Bstring('6', top - 1 - 5*ttop);
751 for ( i=0; i<5; i++ ) stip += stip_rpt;
752
753 for ( i=0; i<6; i++ ) sbase += sbase_rpt;
754 // sbase += Bstring(base - 6*tbase, '6');
755 sbase += Bstring('6', base - 6*tbase);
756
757 return model_poly_gen_3part(stip, sbody, sbase, valence, enantiomorph, requirements);
758 }
759
770 Bmodel* model_poly_gen_coffin_jiggle(int ttop, int tbody, int tbase, int valence, int enantiomorph, int requirements)
771 {
772 int i;
773 int top = 1 + (5*ttop*(ttop + 1))/2;
774 int body = tbody*(5*ttop + 6*tbase + 1)/2;
775 int base = 1 + 3*tbase*(tbase + 1);
776
777 Bstring stip("5");
778 // Bstring sbody(body, '6');
779 Bstring sbody('6', body);
780 Bstring sbase;
781 Bstring stip_rpt("5");
782 Bstring sbase_rpt("5");
783
784 for ( i=1; i<ttop; i++ ) stip_rpt += "6";
785 for ( i=1; i<tbase; i++ ) sbase_rpt += "6";
786
787 // stip += Bstring(top - 1 - 5*ttop, '6');
788 stip += Bstring('6', top - 1 - 5*ttop);
789 for ( i=0; i<5; i++ ) stip += stip_rpt;
790
791 for ( i=0; i<6; i++ ) sbase += sbase_rpt;
792 // sbase += Bstring(base - 6*tbase, '6');
793 sbase += Bstring('6', base - 6*tbase);
794
795 Bstring seq = stip + sbody + sbase;
796
797 return model_poly_gen_move_pentagons(seq, valence, enantiomorph, requirements);
798 }
799
814 Bmodel* model_poly_gen_3part(Bstring stip, Bstring sbody, Bstring sbase, int valence, int enantiomorph, int requirements)
815 {
816 int i, np = 1, npb = 1, nm = 0, max = 1000;
817 int nt = 1000; // Maximum number of comparison table entries
818 Bstring sbase_one;
819
820 Bmodel* model = NULL;
821 Bmodel* mp = NULL;
822 Bmodel* new_mp = NULL;
823
824 Bstring seq = stip + sbody + sbase;
825 int vertices = 20 + 2*(seq.length() - 12);
826 double* table = new double[nt*vertices];
827 for ( i=0; i<nt*vertices; i++ ) table[i] = 0;
828
829 if ( verbose )
830 cout << "Start: " << seq << endl;
831
832 for ( i=0, nm=0; nm<max && np; np = next_permutation(stip) )
833 if ( seq_count_adj_pentagons(stip) < 1 ) {
834 sbase_one = sbase;
835 for ( npb=1; nm<max && npb; npb = next_permutation(sbase_one) )
836 if ( seq_count_adj_pentagons(sbase_one) < 1 ) {
837 i++;
838 seq = stip + sbody + sbase_one;
839 new_mp = model_poly_gen_sequence(seq, valence, enantiomorph, requirements, nm, table);
840 if ( new_mp ) {
841 if ( !model ) model = new_mp;
842 else mp->next = new_mp;
843 mp = new_mp;
844 nm++;
845 cout << mp->id << " " << i << ": " << seq << ": " << mp->symmetry << endl;
846 if ( new_mp->next ) {
847 mp = new_mp->next;
848 nm++;
849 cout << mp->id << " " << i << ": " << seq << ": " << mp->symmetry << endl;
850 }
851 }
852 }
853 }
854
855 delete[] table;
856
857 for ( nm=0, mp = model; mp; mp = mp->next ) nm++;
858
859 cout << "Models made: " << nm << "/" << --nt << endl << endl;
860
861 return model;
862 }
863
864 Bmodel* move_pentagons(int len, int p[12], int n, int valence, int enantiomorph, int requirements, int* nm)
865 {
866 int i, j, pc[12];
867 Bstring seq;
868 Bmodel* model = NULL;
869 Bmodel* mp = NULL;
870 Bmodel* new_mp = NULL;
871
872 if ( n < 12 ) {
873 for ( i=0; i<12; i++ ) pc[i] = p[i];
874 for ( i = -1; i < 2; i++ ) {
875 pc[n] = p[n] + i;
876 if ( pc[n] >= 0 && pc[n] < len ) {
877 new_mp = move_pentagons(len, pc, n+1, valence, enantiomorph, requirements, nm);
878 if ( new_mp ) {
879 if ( !model ) model = mp = new_mp;
880 else mp->next = new_mp;
881 while ( mp->next ) {
882 (*nm)++;
883 mp = mp->next;
884 }
885 }
886 }
887 }
888 } else {
889 for ( i=j=0; i<len; i++ ) if ( i==p[j] ) {
890 seq += "5";
891 j++;
892 } else {
893 seq += "6";
894 }
895 model = model_poly_gen_sequence(seq, valence, enantiomorph, requirements, *nm, NULL);
896 if ( model )
897 cout << model->id << " " << i << ": " << seq << ": " << model->symmetry << endl;
898 }
899
900 return model;
901 }
902
915 Bmodel* model_poly_gen_move_pentagons(Bstring& seq, int valence, int enantiomorph, int requirements)
916 {
917 int i, j, p[12], nm = 0;
918
919 for ( i=j=0; i<seq.length() && j<12; i++ ) if ( seq[i] == '5' ) p[j++] = i;
920
921 Bmodel* model = move_pentagons(seq.length(), p, 0, valence, enantiomorph, requirements, &nm);
922
923 return model;
924 }
925
Bcomponent::id
Bstring id
Definition: rwmodel.h:53
model_poly_spiral
Bmodel * model_poly_spiral(Bstring &seq, int valence, int requirements)
Generates a polyhedron using the spiral algorithm.
Definition: model_poly_spiral.cpp:274
model_set_component_radius
long model_set_component_radius(Bmodel *model, double comprad)
Set the display radius for all components to a specific value.
Definition: rwmodel.cpp:1264
Bcomponent::type
Bcomptype * type
Definition: rwmodel.h:54
Blink
Definition: rwmodel.h:82
Bmodel::id
Bstring id
Definition: rwmodel.h:121
Bmodel::poly
Bpolygon * poly
Definition: rwmodel.h:134
model_regularize
int model_regularize(Bmodel *model, int reg_iter, double distance, double Kdistance, double Klink, double Kangle, double Kpoly, double Kpolyplane, double Kpoint, double decay)
Regularizes a model.
Definition: model_mechanics.cpp:1411
utilities.h
Header file for general utilities.
model_util.h
Library routines used for model processing.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
model_poly_gen_coffin_jiggle
Bmodel * model_poly_gen_coffin_jiggle(int ttop, int tbody, int tbase, int valence, int enantiomorph, int requirements)
An icosahedral tip and a 6-fold base is set up and polyhedra generated by moving pentagons around.
Definition: model_poly_spiral.cpp:770
Bcomponent::flag
int flag[MAXLINK]
Definition: rwmodel.h:57
Bpolygon::comp
Bcomponent * comp[MAXLINK]
Definition: rwmodel.h:105
model_poly_gen_3part
Bmodel * model_poly_gen_3part(Bstring stip, Bstring sbody, Bstring sbase, int valence, int enantiomorph, int requirements)
Generates several polyhedra by permuting the first and last parts of a three-part sequence.
Definition: model_poly_spiral.cpp:814
Bpolygon
Definition: rwmodel.h:102
add_item
char * add_item(char **list, unsigned long size)
Adds an item to a linked list.
Definition: linked_list.cpp:26
model_component_count
int model_component_count(Bmodel *model)
Counts the total number of components.
Definition: rwmodel.cpp:635
Bstring::length
long length() const
Definition: Bstring.cpp:263
count_list
long count_list(char *list)
Counts the number of items in a linked list.
Definition: linked_list.cpp:235
component_add
Bcomponent * component_add(Bcomponent **comp, Bstring &id)
Adds a component to a linked list.
Definition: rwmodel.cpp:267
link_add
Blink * link_add(Blink **link, Bcomponent *comp1, Bcomponent *comp2, double length, double radius)
Adds a component link to a linked list.
Definition: rwmodel.cpp:315
Matrix.h
Generalized matrix class.
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
model_mechanics.h
Functions to do molecular mechanics.
model_links.h
Library routines used for model link processing.
model_poly_gen_sequence
Bmodel * model_poly_gen_sequence(Bstring &seq, int valence, int enantiomorph, int requirements, int nm)
Generates a polyhedron using a given sequence.
Definition: model_poly_spiral.cpp:399
model_poly_spiral_regularize
int model_poly_spiral_regularize(Bmodel *model)
Definition: model_poly_spiral.cpp:317
model_copy
Bmodel * model_copy(Bmodel *model)
Copies a model.
Definition: rwmodel.cpp:685
model_vertex_types_in_first_polygons
int model_vertex_types_in_first_polygons(Bmodel *model, int npoly)
Definition: model_poly_spiral.cpp:206
move_pentagons
Bmodel * move_pentagons(int len, int p[12], int n, int valence, int enantiomorph, int requirements, int *nm)
Definition: model_poly_spiral.cpp:864
Bpolygon::number
int number
Definition: rwmodel.h:104
model_reflect
long model_reflect(Bmodel *model, Vector3< double > normal, Vector3< double > origin)
Reflects the model through a mirror plane.
Definition: model_transform.cpp:143
model_poly_gen_lozenge
Bmodel * model_poly_gen_lozenge(int ttop, int tbody, int valence, int enantiomorph, int requirements)
Two icosahedral tips are set up and polyhedra generated by rotating the 2 tips.
Definition: model_poly_spiral.cpp:598
model_poly_gen_coffin_loose
Bmodel * model_poly_gen_coffin_loose(int ttop, int tbody, int tbase, int valence, int enantiomorph, int requirements)
An icosahedral tip and a 6-fold base is set up and polyhedra generated by permuting the tip and base.
Definition: model_poly_spiral.cpp:732
Bstring::contains
bool contains(const Bstring &s)
Definition: Bstring.cpp:584
linked_list.h
Header file for generalized linked list functions.
model_kill
int model_kill(Bmodel *model)
Deallocates all memory in the list.
Definition: rwmodel.cpp:1124
model_init
Bmodel * model_init(Bstring &id)
Initializes a model structure.
Definition: rwmodel.cpp:144
base
string base(string &filename)
Definition: string_util.cpp:28
verbose
int verbose
model_set_link_radius
long model_set_link_radius(Bmodel *model, double linkrad)
Set the display radius for all links to a specific value.
Definition: model_links.cpp:139
Blink::next
Blink * next
Definition: rwmodel.h:83
Bmodel::type_id
Bstring type_id
Definition: rwmodel.h:122
model_poly_gen_move_pentagons
Bmodel * model_poly_gen_move_pentagons(Bstring &seq, int valence, int enantiomorph, int requirements)
Generates many polyhedrons using a given sequence and moving pentagons around.
Definition: model_poly_spiral.cpp:915
Bpolygon::next
Bpolygon * next
Definition: rwmodel.h:103
Bmodel::symmetry
Bstring symmetry
Definition: rwmodel.h:124
model_vertex_types
int model_vertex_types(Bmodel *model)
Determines the vertex type based on adjacent polygons.
Definition: model_poly.cpp:313
model_poly.h
Functions to manipulate polyhedral coordinate files.
Bmodel::next
Bmodel * next
Definition: rwmodel.h:120
model_poly_find_symmetry
Bstring model_poly_find_symmetry(Bmodel *model, double find)
Finds the symmetry axes associated with polyhedral elements.
Definition: model_poly.cpp:1095
Bcomponent::sel
int sel
Definition: rwmodel.h:66
model_polyhedron_check
int model_polyhedron_check(Bmodel *model, int valence)
Checks a polyhedron for accuracy and completeness.
Definition: model_poly_spiral.cpp:336
model_add_type_by_id
Bcomptype * model_add_type_by_id(Bmodel *model, Bstring &id)
Add a type to a model if the identifier does not exist already.
Definition: rwmodel.cpp:411
model
Bmodel * model
Definition: bshow.cpp:32
write_model
int write_model(Bstring &filename, Bmodel *model)
Writes model parameters.
Definition: rwmodel.cpp:91
model_poly_gen_permutations
Bmodel * model_poly_gen_permutations(int vertices, int valence, int enantiomorph)
All polyhedra are generated for a given number of vertices.
Definition: model_poly_spiral.cpp:494
Bstring
Definition: Bstring.h:29
Bcomponent::link
Bcomponent * link[MAXLINK]
Definition: rwmodel.h:55
Bmodel::link
Blink * link
Definition: rwmodel.h:133
next_permutation
int next_permutation(Bstring &s)
Produces the next permutation in lexical order.
Definition: math_util.cpp:220
Bcomponent::next
Bcomponent * next
Definition: rwmodel.h:52
rwmodel.h
Header file for reading and writing atomic model files.
model_adjacent_pentagons
int model_adjacent_pentagons(Bmodel *model)
Definition: model_poly_spiral.cpp:228
Vector3< double >
polygon_add
int polygon_add(int n, int valence, Bmodel *model)
Definition: model_poly_spiral.cpp:39
seq_count_adj_pentagons
int seq_count_adj_pentagons(Bstring &seq)
Definition: model_poly_spiral.cpp:196
Vector3.h
Class for 3-value vectors.
model_set_link_length
long model_set_link_length(Bmodel *model, double linklength)
Sets the reference link lengths.
Definition: model_links.cpp:112
Bstring::integer
long integer()
Definition: Bstring.cpp:539
Bmodel
Definition: rwmodel.h:119
model_poly_sphere_coor
vector< double > model_poly_sphere_coor(Bmodel *model)
Generates coordinates for components based on the eigenvectors of the adjacency matrix.
Definition: model_poly.cpp:1659
Bmodel::comp
Bcomponent * comp
Definition: rwmodel.h:132
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
model_poly_spiral.h
Functions to generate polyhedra using the spiral algorithm.
model_adjacent_pentagons_in_first_polygons
int model_adjacent_pentagons_in_first_polygons(Bmodel *model, int npoly)
Definition: model_poly_spiral.cpp:243
model_transform.h
Library routines used for model transformation.
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
model_poly_gen_coffin
Bmodel * model_poly_gen_coffin(int ttop, int tbody, int tbase, int valence, int enantiomorph, int requirements)
An icosahedral tip and a 6-fold base is set up and polyhedra generated by rotating the tip and base.
Definition: model_poly_spiral.cpp:665
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
math_util.h
Header file for general utilities.
Bpolygon::sel
int sel
Definition: rwmodel.h:109
model_poly_gen_cone
Bmodel * model_poly_gen_cone(int tip, int body, int base, int valence, int enantiomorph, int requirements)
A cone tip with 5 pentagons and a base with 7 pentagons are use to generate polyhedra.
Definition: model_poly_spiral.cpp:557
Bpolygon::closed
int closed
Definition: rwmodel.h:107
Bcomponent
Definition: rwmodel.h:51