Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

frame.cpp

Go to the documentation of this file.
00001 // frame.cpp
00002 // 
00003 // Copyright (C) 2003, Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include <celengine/frame.h>
00011 
00012 
00013 RigidTransform FrameOfReference::toUniversal(const RigidTransform& xform,
00014                                              double t) const
00015 {
00016     // Handle the easy case . . .
00017     if (coordSys == astro::Universal)
00018         return xform;
00019     UniversalCoord origin = refObject.getPosition(t);
00020 
00021     if (coordSys == astro::Geographic)
00022     {
00023         Quatd rotation(1, 0, 0, 0);
00024         switch (refObject.getType())
00025         {
00026         case Selection::Type_Body:
00027             rotation = refObject.body()->getEclipticalToGeographic(t);
00028             break;
00029         case Selection::Type_Star:
00030             rotation = refObject.star()->getRotationElements().eclipticalToPlanetographic(t);
00031             break;
00032         case Selection::Type_Location:
00033             if (refObject.location()->getParentBody() != NULL)
00034                 rotation = refObject.location()->getParentBody()->getEclipticalToGeographic(t);
00035             break;
00036         default:
00037             break;
00038         }
00039 
00040         Point3d p = (Point3d) xform.translation * rotation.toMatrix4();
00041         return RigidTransform(origin + Vec3d(p.x, p.y, p.z),
00042                               xform.rotation * rotation);
00043     }
00044     else if (coordSys == astro::PhaseLock)
00045     {
00046         Mat3d m;
00047         Vec3d lookDir = refObject.getPosition(t) - targetObject.getPosition(t);
00048         lookDir.normalize();
00049 
00050         switch (refObject.getType())
00051         {
00052         case Selection::Type_Body:
00053             {
00054                 Body* body = refObject.body();
00055                 Vec3d axisDir = Vec3d(0, 1, 0) * body->getEclipticalToEquatorial(t).toMatrix3();
00056                 Vec3d v = axisDir ^ lookDir;
00057                 v.normalize();
00058                 Vec3d u = lookDir ^ v;
00059                 m = Mat3d(v, u, lookDir);
00060             }
00061             break;
00062         case Selection::Type_Star:
00063             {
00064                 Star* star = refObject.star();
00065                 Vec3d axisDir = Vec3d(0, 1, 0) * star->getRotationElements().eclipticalToEquatorial(t).toMatrix3();
00066                 Vec3d v = axisDir ^ lookDir;
00067                 v.normalize();
00068                 Vec3d u = lookDir ^ v;
00069                 m = Mat3d(v, u, lookDir);
00070             }
00071         default:
00072             return xform;
00073         }
00074 
00075         Point3d p = (Point3d) xform.translation * m;
00076 
00077         return RigidTransform(origin + Vec3d(p.x, p.y, p.z),
00078                               xform.rotation * Quatd(m));
00079     }
00080     else if (coordSys == astro::Chase)
00081     {
00082         Mat3d m;
00083 
00084         switch (refObject.getType())
00085         {
00086         case Selection::Type_Body:
00087             {
00088                 Body* body = refObject.body();
00089                 Vec3d lookDir = body->getOrbit()->positionAtTime(t) -
00090                     body->getOrbit()->positionAtTime(t - 1.0 / 1440.0);
00091                 Vec3d axisDir = Vec3d(0, 1, 0) * body->getEclipticalToEquatorial(t).toMatrix3();
00092                 lookDir.normalize();
00093                 Vec3d v = lookDir ^ axisDir;
00094                 v.normalize();
00095                 Vec3d u = v ^ lookDir;
00096                 m = Mat3d(v, u, -lookDir);
00097             }
00098             break;
00099         default:
00100             return xform;
00101         }
00102 
00103         Point3d p = (Point3d) xform.translation * m;
00104 
00105         return RigidTransform(origin + Vec3d(p.x, p.y, p.z),
00106                               xform.rotation * Quatd(m));
00107     }
00108     else
00109     {
00110         return RigidTransform(origin + xform.translation, xform.rotation);
00111     }
00112 }
00113 
00114 
00115 RigidTransform FrameOfReference::fromUniversal(const RigidTransform& xform,
00116                                                double t) const
00117 {
00118     // Handle the easy case . . .
00119     if (coordSys == astro::Universal)
00120         return xform;
00121     UniversalCoord origin = refObject.getPosition(t);
00122 
00123     if (coordSys == astro::Geographic)
00124     {
00125         Quatd rotation(1, 0, 0, 0);
00126         switch (refObject.getType())
00127         {
00128         case Selection::Type_Body:
00129             rotation = refObject.body()->getEclipticalToGeographic(t);
00130             break;
00131         case Selection::Type_Star:
00132             rotation = refObject.star()->getRotationElements().eclipticalToPlanetographic(t);
00133             break;
00134         case Selection::Type_Location:
00135             if (refObject.location()->getParentBody() != NULL)
00136                 rotation = refObject.location()->getParentBody()->getEclipticalToGeographic(t);
00137             break;
00138         default:
00139             break;
00140         }
00141         Vec3d v = (xform.translation - origin) * (~rotation).toMatrix4();
00142         
00143         return RigidTransform(UniversalCoord(v.x, v.y, v.z),
00144                               xform.rotation * ~rotation);
00145     }
00146     else if (coordSys == astro::PhaseLock)
00147     {
00148         Mat3d m;
00149         Vec3d lookDir = refObject.getPosition(t) - targetObject.getPosition(t);
00150         lookDir.normalize();
00151 
00152         switch (refObject.getType())
00153         {
00154         case Selection::Type_Body:
00155             {
00156                 Body* body = refObject.body();
00157                 Vec3d axisDir = Vec3d(0, 1, 0) * body->getEclipticalToEquatorial(t).toMatrix3();
00158                 Vec3d v = axisDir ^ lookDir;
00159                 v.normalize();
00160                 Vec3d u = lookDir ^ v;
00161                 m = Mat3d(v, u, lookDir);
00162             }
00163             break;
00164 
00165         case Selection::Type_Star:
00166             {
00167                 Star* star = refObject.star();
00168                 Vec3d axisDir = Vec3d(0, 1, 0) * star->getRotationElements().eclipticalToEquatorial(t).toMatrix3();
00169                 Vec3d v = axisDir ^ lookDir;
00170                 v.normalize();
00171                 Vec3d u = lookDir ^ v;
00172                 m = Mat3d(v, u, lookDir);
00173             }
00174 
00175         default:
00176             return xform;
00177         }
00178 
00179         Vec3d v = (xform.translation - origin) * m.transpose();
00180 
00181         return RigidTransform(UniversalCoord(v.x, v.y, v.z),
00182                               xform.rotation * ~Quatd(m));
00183     }
00184     else if (coordSys == astro::Chase)
00185     {
00186         Mat3d m;
00187 
00188         switch (refObject.getType())
00189         {
00190         case Selection::Type_Body:
00191             {
00192                 Body* body = refObject.body();
00193                 Vec3d lookDir = body->getOrbit()->positionAtTime(t) -
00194                     body->getOrbit()->positionAtTime(t - 1.0 / 1440.0);
00195                 Vec3d axisDir = Vec3d(0, 1, 0) * body->getEclipticalToEquatorial(t).toMatrix3();
00196                 lookDir.normalize();
00197                 Vec3d v = lookDir ^ axisDir;
00198                 v.normalize();
00199                 Vec3d u = v ^ lookDir;
00200                 m = Mat3d(v, u, -lookDir);
00201             }
00202             break;
00203 
00204         default:
00205             return xform;
00206         }
00207 
00208         Vec3d v = (xform.translation - origin) * m.transpose();
00209 
00210         return RigidTransform(UniversalCoord(v.x, v.y, v.z),
00211                               xform.rotation * ~Quatd(m));
00212     }
00213     else
00214     {
00215         return RigidTransform(xform.translation.difference(origin),
00216                               xform.rotation);
00217     }
00218 }

Generated on Sat Jan 14 22:30:27 2006 for Celestia by  doxygen 1.4.1