home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / utility / dos / rotate / rotate.cpp next >
Encoding:
C/C++ Source or Header  |  1994-06-06  |  11.8 KB  |  373 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //                                                                         //
  3. //    ROTATOR v 0.1                                                          //
  4. //                                                                         //
  5. //    This program takes a set of object positions and generates rotate and  //
  6. //    translate commands to point each object at a given point.              //
  7. //                                                                         //
  8. //    (c) S.A.Collyer 1994                                                   //
  9. //        CIS: 100137,230                                                    //
  10. //        Internet: spencerc@lasermnt.demon.co.uk                            //
  11. //                                                                         //
  12. //    This program is freeware.                                              //
  13. //                                                                         //
  14. /////////////////////////////////////////////////////////////////////////////
  15.  
  16. /////////////////////////////////////////////////////////////////////////////
  17. //                                                                         //
  18. //    Usage:                                                                 //
  19. //        ROTATE [options]                                                   //
  20. //                                                                         //
  21. //    Options:                                                               //
  22. //        -i<name> - Specifies input filename.  If not given, defaults to    //
  23. //                   DATA.ROT.                                               //
  24. //        -o<name> - Specifies output filename.  If not given, defaults to   //
  25. //                   ROTATE.INC.                                             //
  26. //        -f[odi]  - Specifies output file format.  Formats are:             //
  27. //                     o - Object format                                     //
  28. //                     d - Declare format                                    //
  29. //                     i - Object-Declare format                             //
  30. //                   Default is '-fo'                                        //
  31. //        -pn      - Specifies precision to use when outputting data.        //
  32. //                   Default is 3 dps.                                       //
  33. //                                                                         //
  34. /////////////////////////////////////////////////////////////////////////////
  35.  
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <math.h>
  39. #include <complex.h>    // This is for M_PI
  40. #include <iostream.h>
  41. #include <iomanip.h>
  42. #include <fstream.h>
  43.  
  44. const double PI = M_PI;
  45. const double EPS = 0.000005;
  46.  
  47. enum ObFormat {FormatObject, FormatDeclare, FormatObjDecl};
  48.  
  49. // Precision to use when outputting vector data
  50. unsigned int VectorPrecision = 3;
  51.  
  52. // Simple vector class.  Does all we require of it - reads in a vector,
  53. // allows access to each element, writes it out
  54. class Vector
  55. {
  56. private:
  57.     double v1,v2,v3;    // vector components
  58. public:
  59.     Vector() {}
  60.     Vector(const Vector& v) : v1(v.v1),v2(v.v2),v3(v.v3) {}
  61.     Vector(double x, double y, double z) : v1(x), v2(y), v3(z) {}
  62.     Vector& operator=(const Vector& v) {v1=v.v1;v2=v.v2;v3=v.v3;return *this;}
  63.     friend istream& operator>>(istream& is, Vector& v);
  64.     friend ostream& operator<<(ostream& os, Vector& v);
  65.     double x() { return v1;}
  66.     double y() { return v2;}
  67.     double z() { return v3;}
  68. };
  69.  
  70. istream& operator>>(istream& is, Vector& v)
  71. {
  72.     is >> v.v1 >> v.v2 >> v.v3;
  73.     return is;
  74. }
  75.  
  76. ostream& operator<<(ostream& os, Vector& v)
  77. {
  78.     os.precision(VectorPrecision);
  79. #ifdef __BORLANDC__
  80.     os.setf(0, ios::floatfield);
  81.     os.setf(ios::showpoint);
  82. #else
  83.     os.setf(ios::fixed, ios::floatfield);
  84. #endif
  85.     os << "< " << v.v1
  86.        << ", " << v.v2
  87.        << ", " << v.v3
  88.        << " >";
  89.     return os;
  90. }
  91.  
  92.  
  93. //////////////////////////////////////////
  94. //    ParseParams                            //
  95. //    This function parses the input        //
  96. //    parameters                            //
  97. //////////////////////////////////////////
  98. void ParseParams(int argc, char *argv[], char **pInFile, char **pOutFile,
  99.                  ObFormat& OutForm)
  100. {
  101.     for (int i = 1; i < argc; i++)
  102.     {
  103.         if (argv[i][0] != '-')
  104.         {
  105.             cerr << "Illegal parameter: " << argv[i] << "\n";
  106.         }
  107.         else
  108.         {
  109.             switch (argv[i][1])
  110.             {
  111.                 case 'i':
  112.                     *pInFile = argv[i]+2;
  113.                     break;
  114.                 case 'o':
  115.                     *pOutFile = argv[i]+2;
  116.                     break;
  117.                 case 'f':
  118.                     switch (argv[i][2])
  119.                     {
  120.                         case 'o':
  121.                             OutForm = FormatObject;
  122.                             break;
  123.                         case 'd':
  124.                             OutForm = FormatDeclare;
  125.                             break;
  126.                         case 'i':
  127.                             OutForm = FormatObjDecl;
  128.                             break;
  129.                         default:
  130.                             cerr << "Unknown output file format: " << argv[i][2] << "\n";
  131.                             break;
  132.                     }
  133.                     break;
  134.                 case 'p':
  135.                     VectorPrecision = atoi(argv[i]+2);
  136.                     if (VectorPrecision <= 0)
  137.                     {
  138.                         VectorPrecision = 3;
  139.                     }
  140.                     break;
  141.                 default:
  142.                     cerr << "Unknown parameter: " << argv[i] << "\n";
  143.                     break;
  144.             }
  145.         }
  146.     }
  147. }
  148.  
  149. //////////////////////////////////////////
  150. //    Rotation functions                    //
  151. //    These next three functions take an    //
  152. //    object point and a point to point    //
  153. //    at, and generate a rotation vector  //
  154. //    to line them up                        //
  155. //////////////////////////////////////////
  156. void RotateX(Vector& Obj, Vector& Point, Vector&Rot, char dirn)
  157. {
  158.     double vx = Obj.x() - Point.x();
  159.     double vy = Obj.y() - Point.y();
  160.     double vz = Obj.z() - Point.z();
  161.     double t = sqrt(vy*vy + vx*vx);
  162.     double theta = 0.0;
  163.     double phi = 0.0;
  164.  
  165.     theta = atan2(-vz, t);
  166.     if (fabs(vy) < EPS && fabs(vx) < EPS)
  167.     {
  168.         phi = 0.0;
  169.     }
  170.     else
  171.     {
  172.         phi = atan2(vy, vx);
  173.     }
  174.     if (dirn == '-')
  175.     {
  176.         theta += PI;
  177.     }
  178.     Rot = Vector(0.0, theta*180/PI, phi*180/PI);
  179. }
  180.  
  181. void RotateY(Vector& Obj, Vector& Point, Vector&Rot, char dirn)
  182. {
  183.     double vx = Obj.x() - Point.x();
  184.     double vy = Obj.y() - Point.y();
  185.     double vz = Obj.z() - Point.z();
  186.     double t = sqrt(vx*vx + vy*vy);
  187.     double theta = 0.0;
  188.     double phi = 0.0;
  189.  
  190.     theta = atan2(vz, t);
  191.     if (fabs(vx) < EPS && fabs(vy) < EPS)
  192.     {
  193.         phi = 0.0;
  194.     }
  195.     else
  196.     {
  197.         phi = atan2(-vx, vy);
  198.     }
  199.     if (dirn == '-')
  200.     {
  201.         theta += PI;
  202.     }
  203.     Rot = Vector(theta*180/PI, 0.0, phi*180/PI);
  204. }
  205.  
  206. void RotateZ(Vector& Obj, Vector& Point, Vector&Rot, char dirn)
  207. {
  208.     double vx = Obj.x() - Point.x();
  209.     double vy = Obj.y() - Point.y();
  210.     double vz = Obj.z() - Point.z();
  211.     double t = sqrt(vx*vx + vz*vz);
  212.     double theta = 0.0;
  213.     double phi = 0.0;
  214.  
  215.     theta = atan2(-vy, t);
  216.     if (fabs(vx) < EPS && fabs(vz) < EPS)
  217.     {
  218.         phi = 0.0;
  219.     }
  220.     else
  221.     {
  222.         phi = atan2(vx, vz);
  223.     }
  224.     if (dirn == '-')
  225.     {
  226.         theta += PI;
  227.     }
  228.     Rot = Vector(theta*180/PI, phi*180/PI, 0.0);
  229. }
  230.  
  231. //////////////////////////////////////////
  232. //    Output functions:                    //
  233. //    The next three functions output the    //
  234. //    rotation and translation data in    //
  235. //    the requested format.                //
  236. //////////////////////////////////////////
  237. void OutputObject(ofstream& Out, char *Name, Vector& Rot, Vector &Obj)
  238. {
  239.     Out << "object\n{\n\t" << Name << "\n";
  240.     Out << "\trotate " << Rot << "\n\ttranslate " << Obj << "\n}\n\n";
  241. }
  242.  
  243. void OutputDeclare(ofstream& Out, char *Name, Vector& Rot, Vector &Obj)
  244. {
  245.     Out << "#declare " << Name << "_R = " << Rot << "\n";
  246.     Out << "#declare " << Name << "_T = " << Obj << "\n\n";
  247. }
  248.  
  249. void OutputObjDecl(ofstream& Out, char *Name, Vector& Rot, Vector &Obj)
  250. {
  251.     Out << "#declare " << Name << "_Def = ";
  252.     Out << "\tobject\n\t{\n\t\t" << Name << "\n";
  253.     Out << "\t\trotate " << Rot << "\n\t\ttranslate " << Obj << "\n\t}\n\n";
  254. }
  255.  
  256. //////////////////////////////////////////
  257. //    DoRotations                            //
  258. //    This function reads the input file    //
  259. //    and calls the appropriate function    //
  260. //    to do the rotation.  It then calls    //
  261. //    the appropriate function to output    //
  262. //    the data.                            //
  263. //////////////////////////////////////////
  264. void DoRotations(ifstream& In, ofstream& Out, ObFormat& Form)
  265. {
  266.     char dirn;
  267.     char axis;
  268.     char ObjectName[255];
  269.     Vector Obj;
  270.     Vector Point;
  271.     Vector Rot;
  272.  
  273.     while (In)
  274.     {
  275.         In >> dirn;
  276.         if (!In)
  277.         {
  278.             return;
  279.         }
  280.         if (dirn != ';')
  281.         {
  282.             In >> axis >> ObjectName;
  283.             In >> Obj;
  284.             In >> Point;
  285.             switch (axis)
  286.             {
  287.                 case 'x':
  288.                     RotateX(Obj,Point,Rot,dirn);
  289.                     break;
  290.                 case 'y':
  291.                     RotateY(Obj,Point,Rot,dirn);
  292.                     break;
  293.                 case 'z':
  294.                     RotateZ(Obj,Point,Rot,dirn);
  295.                     break;
  296.                 default:
  297.                     cerr << "Unknown axis: " << axis << "\n";
  298.                     break;
  299.             }
  300.             switch (Form)
  301.             {
  302.                 case FormatObject:
  303.                     OutputObject(Out, ObjectName, Rot, Obj);
  304.                     break;
  305.                 case FormatDeclare:
  306.                     OutputDeclare(Out, ObjectName, Rot, Obj);
  307.                     break;
  308.                 case FormatObjDecl:
  309.                     OutputObjDecl(Out, ObjectName, Rot, Obj);
  310.                     break;
  311.             }
  312.         }
  313.         else
  314.         {
  315.             char ch;
  316.             while (In.get(ch) && ch != '\n')
  317.             {
  318.                 ;
  319.             }
  320.         }
  321.     }
  322. }
  323.  
  324. //////////////////////////////////////////
  325. //    PrintHeader                            //
  326. //    This function outputs details of    //
  327. //    the run to the file header            //
  328. //////////////////////////////////////////
  329. void PrintHeader(int argc, char *argv[], ofstream& Out)
  330. {
  331.     for (int i = 0; i <20; i++)
  332.     {
  333.         Out << "////";
  334.     }
  335.     Out << "\n// POV-Ray 2.2 include file generated by ROTATE\n//\n";
  336.     Out << "// Input parameters:\n";
  337.     for (i = 1; i < argc; i++)
  338.     {
  339.         Out << "//\t" << argv[i] << "\n";
  340.     }
  341.     Out << "//\n";
  342. }
  343.  
  344. //////////////////////////////////////////
  345. //    main function                        //
  346. //////////////////////////////////////////
  347. int main(int argc, char *argv[])
  348. {
  349.     char *pInFile = "DATA.ROT";
  350.     char *pOutFile = "ROTATE.INC";
  351.     ObFormat OutForm = FormatObject;
  352.  
  353.     if (argc > 1)
  354.     {
  355.         ParseParams(argc, argv, &pInFile, &pOutFile, OutForm);
  356.     }
  357.     ifstream InFile(pInFile);
  358.     if (!InFile)
  359.     {
  360.         cerr << "Cannot open input file " << pInFile << "\n";
  361.         return 1;
  362.     }
  363.     ofstream OutFile(pOutFile);
  364.     if (!OutFile)
  365.     {
  366.         cerr << "Cannot open output file " << pOutFile << "\n";
  367.         return 1;
  368.     }
  369.     PrintHeader(argc, argv, OutFile);
  370.     DoRotations(InFile, OutFile, OutForm);
  371.     return 0;
  372. }
  373.