ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/primitives/StuntDouble.cpp
Revision: 1698
Committed: Tue Nov 2 15:28:25 2004 UTC (19 years, 8 months ago) by chrisfen
File size: 17398 byte(s)
Log Message:
Shapes looks like it's working

File Contents

# User Rev Content
1 tim 1492 #include "primitives/StuntDouble.hpp"
2     #include "primitives/Atom.hpp"
3     #include "primitives/DirectionalAtom.hpp"
4     #include "primitives/RigidBody.hpp"
5     #include "utils/simError.h"
6 gezelter 1490
7     /*
8     "Don't move, or you're dead! Stand up! Captain, we've got them!"
9    
10     "Spectacular stunt, my friends, but all for naught. Turn around
11     please. Ha. What a pity. What a pity. So, Princess, you thought
12     you could outwit the imperious forces of...."
13    
14     "You idiots! These are not them. You've captured their stunt
15     doubles! Search the area. Find them! Find them!"
16    
17     StuntDouble is a very strange idea. A StuntDouble stands in for
18     some object that can be manipulated by the Integrators or
19     Minimizers. Some of the manipulable objects are Atoms, some are
20     DirectionalAtoms, and some are RigidBodies. StuntDouble
21     provides an interface for the Integrators and Minimizers to use,
22     and does some preliminary sanity checking so that the program
23     doesn't try to do something stupid like torque an Atom. (The
24     quotes above are from Spaceballs...)
25    
26     */
27    
28     StuntDouble::~StuntDouble(){
29     map<string, GenericData*>::iterator iter;
30    
31     for(iter = properties.begin(); iter != properties.end(); ++iter ){
32     delete iter->second;
33     properties.erase(iter);
34     }
35    
36     }
37    
38     int StuntDouble::getObjType(){
39     return objType;
40     }
41    
42     double StuntDouble::getMass(){
43     switch (objType)
44     {
45     case OT_ATOM :
46     case OT_DATOM:
47     return ((Atom*)this)->getMass();
48     break;
49     case OT_RIGIDBODY:
50     return ((RigidBody*)this)->getMass();
51     break;
52     default:
53     sprintf( painCave.errMsg,
54     "Unrecognized ObjType (%d) in StuntDouble::getMass.\n",
55     objType );
56     painCave.isFatal = 1;
57     simError();
58     return 0.0;
59     }
60     }
61    
62    
63     void StuntDouble::getPos(double pos[3]){
64     switch (objType)
65     {
66     case OT_ATOM :
67     case OT_DATOM:
68     ((Atom*)this)->getPos(pos);
69     break;
70     case OT_RIGIDBODY:
71     ((RigidBody*)this)->getPos(pos);
72     break;
73     default:
74     sprintf( painCave.errMsg,
75     "Unrecognized ObjType (%d) in StuntDouble::getPos.\n",
76     objType );
77     painCave.isFatal = 1;
78     simError();
79     }
80     }
81    
82     void StuntDouble::getVel(double vel[3]){
83     switch (objType)
84     {
85     case OT_ATOM :
86     case OT_DATOM:
87     ((Atom*)this)->getVel(vel);
88     break;
89     case OT_RIGIDBODY:
90     ((RigidBody*)this)->getVel(vel);
91     break;
92     default:
93     sprintf( painCave.errMsg,
94     "Unrecognized ObjType (%d) in StuntDouble::getVel.\n",
95     objType );
96     painCave.isFatal = 1;
97     simError();
98     }
99     }
100    
101     void StuntDouble::getFrc(double frc[3]){
102     switch (objType)
103     {
104     case OT_ATOM :
105     case OT_DATOM:
106     ((Atom*)this)->getFrc(frc);
107     break;
108     case OT_RIGIDBODY:
109     ((RigidBody*)this)->getFrc(frc);
110     break;
111     default:
112     sprintf( painCave.errMsg,
113     "Unrecognized ObjType (%d) in StuntDouble::getFrc.\n",
114     objType );
115     painCave.isFatal = 1;
116     simError();
117     }
118     }
119    
120    
121     void StuntDouble::setPos(double pos[3]){
122     switch (objType)
123     {
124     case OT_ATOM :
125     case OT_DATOM:
126     ((Atom*)this)->setPos(pos);
127     break;
128     case OT_RIGIDBODY:
129     ((RigidBody*)this)->setPos(pos);
130     break;
131     default:
132     sprintf( painCave.errMsg,
133     "Unrecognized ObjType (%d) in StuntDouble::setPos.\n",
134     objType );
135     painCave.isFatal = 1;
136     simError();
137     }
138     }
139    
140     void StuntDouble::setVel(double vel[3]){
141    
142     switch (objType)
143     {
144     case OT_ATOM :
145     case OT_DATOM:
146     ((Atom*)this)->setVel(vel);
147     break;
148     case OT_RIGIDBODY:
149     ((RigidBody*)this)->setVel(vel);
150     break;
151     default:
152     sprintf( painCave.errMsg,
153     "Unrecognized ObjType (%d) in StuntDouble::setVel.\n",
154     objType );
155     painCave.isFatal = 1;
156     simError();
157     }
158     }
159    
160     void StuntDouble::addFrc(double frc[3]){
161     switch (objType)
162     {
163     case OT_ATOM :
164     case OT_DATOM:
165     ((Atom*)this)->addFrc(frc);
166     break;
167     case OT_RIGIDBODY:
168     ((RigidBody*)this)->addFrc(frc);
169     break;
170     default:
171     sprintf( painCave.errMsg,
172     "Unrecognized ObjType (%d) in StuntDouble::addFrc.\n",
173     objType );
174     painCave.isFatal = 1;
175     simError();
176     }
177     }
178    
179     void StuntDouble::getA(double A[3][3]){
180     switch (objType)
181     {
182     case OT_ATOM:
183     sprintf( painCave.errMsg,
184     "StuntDouble::getA was called for a regular atom.\n"
185     "\tRegular Atoms don't have rotation matrices. Be smarter.\n");
186     painCave.isFatal = 0;
187     simError();
188     // Return unit matrix
189     A[0][0] = 1; A[0][1] = 0; A[0][2] = 0;
190     A[1][0] = 0; A[1][1] = 1; A[1][2] = 0;
191     A[2][0] = 0; A[2][1] = 0; A[2][2] = 1;
192     break;
193     case OT_DATOM:
194     ((DirectionalAtom*)this)->getA(A);
195     break;
196     case OT_RIGIDBODY:
197     ((RigidBody*)this)->getA(A);
198     break;
199     default:
200     sprintf( painCave.errMsg,
201     "Unrecognized ObjType (%d) in StuntDouble::getA.\n",
202     objType );
203     painCave.isFatal = 1;
204     simError();
205     }
206     }
207    
208     void StuntDouble::setA(double A[3][3]){
209     switch (objType)
210     {
211     case OT_ATOM:
212     sprintf( painCave.errMsg,
213     "StuntDouble::setA was called for a regular atom.\n"
214     "\tRegular Atoms don't have rotation matrices. Be smarter.\n");
215     painCave.isFatal = 1;
216     simError();
217     break;
218     case OT_DATOM:
219     ((DirectionalAtom*)this)->setA(A);
220     break;
221     case OT_RIGIDBODY:
222     ((RigidBody*)this)->setA(A);
223     break;
224     default:
225     sprintf( painCave.errMsg,
226     "Unrecognized ObjType (%d) in StuntDouble::setA.\n",
227     objType );
228     painCave.isFatal = 1;
229     simError();
230     }
231     }
232    
233     void StuntDouble::getJ(double j[3]){
234     switch (objType)
235     {
236     case OT_ATOM:
237     sprintf( painCave.errMsg,
238     "StuntDouble::getJ was called for a regular atom.\n"
239     "\tRegular Atoms don't have angular momentum. Be smarter.\n");
240     painCave.isFatal = 0;
241     simError();
242     // Return zeros.
243     j[0] = 0;
244     j[1] = 0;
245     j[2] = 0;
246     break;
247     case OT_DATOM:
248     ((DirectionalAtom*)this)->getJ(j);
249     break;
250     case OT_RIGIDBODY:
251     ((RigidBody*)this)->getJ(j);
252     break;
253     default:
254     sprintf( painCave.errMsg,
255     "Unrecognized ObjType (%d) in StuntDouble::getJ.\n",
256     objType );
257     painCave.isFatal = 1;
258     simError();
259     }
260     }
261    
262     void StuntDouble::setJ(double j[3]){
263     switch (objType)
264     {
265     case OT_ATOM:
266     sprintf( painCave.errMsg,
267     "StuntDouble::setJ was called for a regular atom.\n"
268     "\tRegular Atoms don't have angular momentum. Be smarter.\n");
269     painCave.isFatal = 1;
270     simError();
271     break;
272     case OT_DATOM:
273     ((DirectionalAtom*)this)->setJ(j);
274     break;
275     case OT_RIGIDBODY:
276     ((RigidBody*)this)->setJ(j);
277     break;
278     default:
279     sprintf( painCave.errMsg,
280     "Unrecognized ObjType (%d) in StuntDouble::setJ.\n",
281     objType );
282     painCave.isFatal = 1;
283     simError();
284     }
285     }
286    
287     void StuntDouble::getQ(double q[4] ){
288     switch (objType)
289     {
290     case OT_ATOM:
291     sprintf( painCave.errMsg,
292     "StuntDouble::getJ was called for a regular atom.\n"
293     "\tRegular Atoms don't have angular momentum. Be smarter.\n");
294     painCave.isFatal = 0;
295     simError();
296     // Return zeros.
297     q[0] = 0;
298     q[1] = 0;
299     q[2] = 0;
300     q[3] = 0;
301     break;
302     case OT_DATOM:
303     ((DirectionalAtom*)this)->getQ(q);
304     break;
305     case OT_RIGIDBODY:
306     ((RigidBody*)this)->getQ(q);
307     break;
308     default:
309     sprintf( painCave.errMsg,
310     "Unrecognized ObjType (%d) in StuntDouble::getJ.\n",
311     objType );
312     painCave.isFatal = 1;
313     simError();
314     }
315     }
316    
317     void StuntDouble::setQ(double q[4] ){
318     switch (objType)
319     {
320     case OT_ATOM:
321     sprintf( painCave.errMsg,
322     "StuntDouble::setJ was called for a regular atom.\n"
323     "\tRegular Atoms don't have angular momentum. Be smarter.\n");
324     painCave.isFatal = 1;
325     simError();
326     break;
327     case OT_DATOM:
328     ((DirectionalAtom*)this)->setJ(q);
329     break;
330     case OT_RIGIDBODY:
331     ((RigidBody*)this)->setJ(q);
332     break;
333     default:
334     sprintf( painCave.errMsg,
335     "Unrecognized ObjType (%d) in StuntDouble::setJ.\n",
336     objType );
337     painCave.isFatal = 1;
338     simError();
339     }
340     }
341     void StuntDouble::getTrq(double trq[3]){
342     switch (objType)
343     {
344     case OT_ATOM:
345     sprintf( painCave.errMsg,
346     "StuntDouble::getTrq was called for a regular atom.\n"
347     "\tRegular Atoms don't have torques. Be smarter.\n");
348     painCave.isFatal = 0;
349     simError();
350     // Return zeros.
351     trq[0] = 0;
352     trq[1] = 0;
353     trq[2] = 0;
354     break;
355     case OT_DATOM:
356     ((DirectionalAtom*)this)->getTrq(trq);
357     break;
358     case OT_RIGIDBODY:
359     ((RigidBody*)this)->getTrq(trq);
360     break;
361     default:
362     sprintf( painCave.errMsg,
363     "Unrecognized ObjType (%d) in StuntDouble::getTrq.\n",
364     objType );
365     painCave.isFatal = 1;
366     simError();
367     }
368     }
369    
370     void StuntDouble::addTrq(double trq[3]){
371     switch (objType)
372     {
373     case OT_ATOM:
374     sprintf( painCave.errMsg,
375     "StuntDouble::addTrq was called for a regular atom.\n"
376     "\tRegular Atoms don't have torques. Be smarter.\n");
377     painCave.isFatal = 1;
378     simError();
379     break;
380     case OT_DATOM:
381     ((DirectionalAtom*)this)->addTrq(trq);
382     break;
383     case OT_RIGIDBODY:
384     ((RigidBody*)this)->addTrq(trq);
385     break;
386     default:
387     sprintf( painCave.errMsg,
388     "Unrecognized ObjType (%d) in StuntDouble::addTrq.\n",
389     objType );
390     painCave.isFatal = 1;
391     simError();
392     }
393     }
394    
395     void StuntDouble::getI(double I[3][3]){
396     switch (objType)
397     {
398     case OT_ATOM:
399     sprintf( painCave.errMsg,
400     "StuntDouble::getI was called for a regular atom.\n"
401     "\tRegular Atoms don't have moments of inertia. Be smarter.\n");
402     painCave.isFatal = 0;
403     simError();
404     // Return zero matrix
405     I[0][0] = 0; I[0][1] = 0; I[0][2] = 0;
406     I[1][0] = 0; I[1][1] = 0; I[1][2] = 0;
407     I[2][0] = 0; I[2][1] = 0; I[2][2] = 0;
408     break;
409     case OT_DATOM:
410     ((DirectionalAtom*)this)->getI(I);
411     break;
412     case OT_RIGIDBODY:
413     ((RigidBody*)this)->getI(I);
414     break;
415     default:
416     sprintf( painCave.errMsg,
417     "Unrecognized ObjType (%d) in StuntDouble::getI.\n",
418     objType );
419     painCave.isFatal = 1;
420     simError();
421     }
422     }
423    
424     void StuntDouble::lab2Body(double vec[3]){
425     switch (objType)
426     {
427     case OT_ATOM:
428     sprintf( painCave.errMsg,
429     "StuntDouble::lab2Body was called for a regular atom.\n"
430     "\tRegular Atoms don't have reference frames. Be smarter.\n");
431     painCave.isFatal = 0;
432     simError();
433     break;
434     case OT_DATOM:
435     ((DirectionalAtom*)this)->lab2Body(vec);
436     break;
437     case OT_RIGIDBODY:
438     ((RigidBody*)this)->lab2Body(vec);
439     break;
440     default:
441     sprintf( painCave.errMsg,
442     "Unrecognized ObjType (%d) in StuntDouble::lab2Body.\n",
443     objType );
444     painCave.isFatal = 1;
445     simError();
446     }
447     }
448    
449     void StuntDouble::getGrad(double grad[6]){
450     double frc[3];
451    
452     switch (objType)
453     {
454     case OT_ATOM:
455     sprintf( painCave.errMsg,
456     "StuntDouble::getGrad was called for a regular atom.\n"
457     "\tRegular Atoms don't have 6 coordinates. Be smarter.\n");
458     painCave.isFatal = 0;
459     simError();
460     ((Atom*)this)->getFrc(frc);
461     grad[0] = -frc[0];
462     grad[1] = -frc[1];
463     grad[2] = -frc[2];
464     grad[3] = 0.0;
465     grad[4] = 0.0;
466     grad[5] = 0.0;
467     break;
468     case OT_DATOM:
469     ((DirectionalAtom*)this)->getGrad(grad);
470     break;
471     case OT_RIGIDBODY:
472     ((RigidBody*)this)->getGrad(grad);
473     break;
474     default:
475     sprintf( painCave.errMsg,
476     "Unrecognized ObjType (%d) in StuntDouble::getGrad.\n",
477     objType );
478     painCave.isFatal = 1;
479     simError();
480     }
481     }
482    
483     void StuntDouble::setEuler(double phi, double theta, double psi){
484     switch (objType)
485     {
486     case OT_ATOM:
487     sprintf( painCave.errMsg,
488     "StuntDouble::setEuler was called for a regular atom.\n"
489     "\tRegular Atoms don't have Euler Angles. Be smarter.\n");
490     painCave.isFatal = 1;
491     simError();
492     break;
493     case OT_DATOM:
494     ((DirectionalAtom*)this)->setEuler(phi, theta, psi);
495     break;
496     case OT_RIGIDBODY:
497     ((RigidBody*)this)->setEuler(phi, theta, psi);
498     break;
499     default:
500     sprintf( painCave.errMsg,
501     "Unrecognized ObjType (%d) in StuntDouble::setA.\n",
502     objType );
503     painCave.isFatal = 1;
504     simError();
505     }
506     }
507    
508     void StuntDouble::getEulerAngles(double eulers[3]){
509     switch (objType)
510     {
511     case OT_ATOM:
512     sprintf( painCave.errMsg,
513     "StuntDouble::getEulerAngles was called for a regular atom.\n"
514     "\tRegular Atoms don't have Euler angles. Be smarter.\n");
515     painCave.isFatal = 0;
516     simError();
517     // Return zeros.
518     eulers[0] = 0;
519     eulers[1] = 0;
520     eulers[2] = 0;
521     break;
522     case OT_DATOM:
523     ((DirectionalAtom*)this)->getEulerAngles(eulers);
524     break;
525     case OT_RIGIDBODY:
526     ((RigidBody*)this)->getEulerAngles(eulers);
527     break;
528     default:
529     sprintf( painCave.errMsg,
530     "Unrecognized ObjType (%d) in StuntDouble::getEulerAngles.\n",
531     objType );
532     painCave.isFatal = 1;
533     simError();
534     }
535     }
536    
537 chrisfen 1698 bool StuntDouble::isLinear() {
538     int i;
539     double momI[3][3];
540     bool linearTest = false;
541     double tolerance = 0.001;
542    
543     getI(momI);
544    
545     for (i=0; i<3; i++){
546     if (momI[i][i]<tolerance){
547     linearTest = true;
548     zeroAxis = i;
549     }
550     }
551    
552     return linearTest;
553     }
554    
555 gezelter 1490 double StuntDouble::getZangle(){
556     switch (objType)
557     {
558     case OT_ATOM:
559     sprintf( painCave.errMsg,
560     "StuntDouble::getZangle was called for a regular atom.\n"
561     "\tRegular Atoms don't have zAngles. Be smarter.\n");
562     painCave.isFatal = 0;
563     simError();
564     // Return zeros.
565     return 0;
566     break;
567     case OT_DATOM:
568     return ((DirectionalAtom*)this)->getZangle();
569     break;
570     case OT_RIGIDBODY:
571     return ((RigidBody*)this)->getZangle();
572     break;
573     default:
574     sprintf( painCave.errMsg,
575     "Unrecognized ObjType (%d) in StuntDouble::getZangle.\n",
576     objType );
577     painCave.isFatal = 1;
578     simError();
579     return 0;
580     }
581     }
582    
583     void StuntDouble::setZangle(double zAngle){
584     switch (objType)
585     {
586     case OT_ATOM:
587     sprintf( painCave.errMsg,
588     "StuntDouble::setZangle was called for a regular atom.\n"
589     "\tRegular Atoms don't have zAngles. Be smarter.\n");
590     painCave.isFatal = 1;
591     simError();
592     break;
593     case OT_DATOM:
594     ((DirectionalAtom*)this)->setZangle(zAngle);
595     break;
596     case OT_RIGIDBODY:
597     ((RigidBody*)this)->setZangle(zAngle);
598     break;
599     default:
600     sprintf( painCave.errMsg,
601     "Unrecognized ObjType (%d) in StuntDouble::setZangle.\n",
602     objType );
603     painCave.isFatal = 1;
604     simError();
605     }
606     }
607    
608     void StuntDouble::addZangle(double zAngle){
609     switch (objType)
610     {
611     case OT_ATOM:
612     sprintf( painCave.errMsg,
613     "StuntDouble::addZangle was called for a regular atom.\n"
614     "\tRegular Atoms don't have zAngles. Be smarter.\n");
615     painCave.isFatal = 1;
616     simError();
617     break;
618     case OT_DATOM:
619     ((DirectionalAtom*)this)->addZangle(zAngle);
620     break;
621     case OT_RIGIDBODY:
622     ((RigidBody*)this)->addZangle(zAngle);
623     break;
624     default:
625     sprintf( painCave.errMsg,
626     "Unrecognized ObjType (%d) in StuntDouble::addZangle.\n",
627     objType );
628     painCave.isFatal = 1;
629     simError();
630     }
631     }
632    
633     void StuntDouble::addProperty(GenericData* data){
634     map<string, GenericData*>::iterator result;
635     result = properties.find(data->getID());
636    
637     //we can't simply use properties[prop->getID()] = prop,
638     //it will cause memory leak if we already contain a propery which has the same name of prop
639    
640     if(result != properties.end()){
641     delete (*result).second;
642     (*result).second = data;
643     }
644     else
645     properties[data->getID()] = data;
646    
647    
648     }
649     void StuntDouble::removeProperty(const string& propName){
650     map<string, GenericData*>::iterator result;
651    
652     result = properties.find(propName);
653    
654     if(result != properties.end()){
655     delete result->second;
656     properties.erase(result);
657    
658     }
659    
660     }
661     GenericData* StuntDouble::getProperty(const string& propName){
662     map<string, GenericData*>::iterator result;
663    
664    
665     result = properties.find(propName);
666    
667     if(result != properties.end())
668     return (*result).second;
669     else
670     return NULL;
671     }

Properties

Name Value
svn:executable *