home *** CD-ROM | disk | FTP | other *** search
- /////////////////////////////////////////////////////////////////////////////
- // //
- // ROTATOR v 0.1 //
- // //
- // This program takes a set of object positions and generates rotate and //
- // translate commands to point each object at a given point. //
- // //
- // (c) S.A.Collyer 1994 //
- // CIS: 100137,230 //
- // Internet: spencerc@lasermnt.demon.co.uk //
- // //
- // This program is freeware. //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // //
- // Usage: //
- // ROTATE [options] //
- // //
- // Options: //
- // -i<name> - Specifies input filename. If not given, defaults to //
- // DATA.ROT. //
- // -o<name> - Specifies output filename. If not given, defaults to //
- // ROTATE.INC. //
- // -f[odi] - Specifies output file format. Formats are: //
- // o - Object format //
- // d - Declare format //
- // i - Object-Declare format //
- // Default is '-fo' //
- // -pn - Specifies precision to use when outputting data. //
- // Default is 3 dps. //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <complex.h> // This is for M_PI
- #include <iostream.h>
- #include <iomanip.h>
- #include <fstream.h>
-
- const double PI = M_PI;
- const double EPS = 0.000005;
-
- enum ObFormat {FormatObject, FormatDeclare, FormatObjDecl};
-
- // Precision to use when outputting vector data
- unsigned int VectorPrecision = 3;
-
- // Simple vector class. Does all we require of it - reads in a vector,
- // allows access to each element, writes it out
- class Vector
- {
- private:
- double v1,v2,v3; // vector components
- public:
- Vector() {}
- Vector(const Vector& v) : v1(v.v1),v2(v.v2),v3(v.v3) {}
- Vector(double x, double y, double z) : v1(x), v2(y), v3(z) {}
- Vector& operator=(const Vector& v) {v1=v.v1;v2=v.v2;v3=v.v3;return *this;}
- friend istream& operator>>(istream& is, Vector& v);
- friend ostream& operator<<(ostream& os, Vector& v);
- double x() { return v1;}
- double y() { return v2;}
- double z() { return v3;}
- };
-
- istream& operator>>(istream& is, Vector& v)
- {
- is >> v.v1 >> v.v2 >> v.v3;
- return is;
- }
-
- ostream& operator<<(ostream& os, Vector& v)
- {
- os.precision(VectorPrecision);
- #ifdef __BORLANDC__
- os.setf(0, ios::floatfield);
- os.setf(ios::showpoint);
- #else
- os.setf(ios::fixed, ios::floatfield);
- #endif
- os << "< " << v.v1
- << ", " << v.v2
- << ", " << v.v3
- << " >";
- return os;
- }
-
-
- //////////////////////////////////////////
- // ParseParams //
- // This function parses the input //
- // parameters //
- //////////////////////////////////////////
- void ParseParams(int argc, char *argv[], char **pInFile, char **pOutFile,
- ObFormat& OutForm)
- {
- for (int i = 1; i < argc; i++)
- {
- if (argv[i][0] != '-')
- {
- cerr << "Illegal parameter: " << argv[i] << "\n";
- }
- else
- {
- switch (argv[i][1])
- {
- case 'i':
- *pInFile = argv[i]+2;
- break;
- case 'o':
- *pOutFile = argv[i]+2;
- break;
- case 'f':
- switch (argv[i][2])
- {
- case 'o':
- OutForm = FormatObject;
- break;
- case 'd':
- OutForm = FormatDeclare;
- break;
- case 'i':
- OutForm = FormatObjDecl;
- break;
- default:
- cerr << "Unknown output file format: " << argv[i][2] << "\n";
- break;
- }
- break;
- case 'p':
- VectorPrecision = atoi(argv[i]+2);
- if (VectorPrecision <= 0)
- {
- VectorPrecision = 3;
- }
- break;
- default:
- cerr << "Unknown parameter: " << argv[i] << "\n";
- break;
- }
- }
- }
- }
-
- //////////////////////////////////////////
- // Rotation functions //
- // These next three functions take an //
- // object point and a point to point //
- // at, and generate a rotation vector //
- // to line them up //
- //////////////////////////////////////////
- void RotateX(Vector& Obj, Vector& Point, Vector&Rot, char dirn)
- {
- double vx = Obj.x() - Point.x();
- double vy = Obj.y() - Point.y();
- double vz = Obj.z() - Point.z();
- double t = sqrt(vy*vy + vx*vx);
- double theta = 0.0;
- double phi = 0.0;
-
- theta = atan2(-vz, t);
- if (fabs(vy) < EPS && fabs(vx) < EPS)
- {
- phi = 0.0;
- }
- else
- {
- phi = atan2(vy, vx);
- }
- if (dirn == '-')
- {
- theta += PI;
- }
- Rot = Vector(0.0, theta*180/PI, phi*180/PI);
- }
-
- void RotateY(Vector& Obj, Vector& Point, Vector&Rot, char dirn)
- {
- double vx = Obj.x() - Point.x();
- double vy = Obj.y() - Point.y();
- double vz = Obj.z() - Point.z();
- double t = sqrt(vx*vx + vy*vy);
- double theta = 0.0;
- double phi = 0.0;
-
- theta = atan2(vz, t);
- if (fabs(vx) < EPS && fabs(vy) < EPS)
- {
- phi = 0.0;
- }
- else
- {
- phi = atan2(-vx, vy);
- }
- if (dirn == '-')
- {
- theta += PI;
- }
- Rot = Vector(theta*180/PI, 0.0, phi*180/PI);
- }
-
- void RotateZ(Vector& Obj, Vector& Point, Vector&Rot, char dirn)
- {
- double vx = Obj.x() - Point.x();
- double vy = Obj.y() - Point.y();
- double vz = Obj.z() - Point.z();
- double t = sqrt(vx*vx + vz*vz);
- double theta = 0.0;
- double phi = 0.0;
-
- theta = atan2(-vy, t);
- if (fabs(vx) < EPS && fabs(vz) < EPS)
- {
- phi = 0.0;
- }
- else
- {
- phi = atan2(vx, vz);
- }
- if (dirn == '-')
- {
- theta += PI;
- }
- Rot = Vector(theta*180/PI, phi*180/PI, 0.0);
- }
-
- //////////////////////////////////////////
- // Output functions: //
- // The next three functions output the //
- // rotation and translation data in //
- // the requested format. //
- //////////////////////////////////////////
- void OutputObject(ofstream& Out, char *Name, Vector& Rot, Vector &Obj)
- {
- Out << "object\n{\n\t" << Name << "\n";
- Out << "\trotate " << Rot << "\n\ttranslate " << Obj << "\n}\n\n";
- }
-
- void OutputDeclare(ofstream& Out, char *Name, Vector& Rot, Vector &Obj)
- {
- Out << "#declare " << Name << "_R = " << Rot << "\n";
- Out << "#declare " << Name << "_T = " << Obj << "\n\n";
- }
-
- void OutputObjDecl(ofstream& Out, char *Name, Vector& Rot, Vector &Obj)
- {
- Out << "#declare " << Name << "_Def = ";
- Out << "\tobject\n\t{\n\t\t" << Name << "\n";
- Out << "\t\trotate " << Rot << "\n\t\ttranslate " << Obj << "\n\t}\n\n";
- }
-
- //////////////////////////////////////////
- // DoRotations //
- // This function reads the input file //
- // and calls the appropriate function //
- // to do the rotation. It then calls //
- // the appropriate function to output //
- // the data. //
- //////////////////////////////////////////
- void DoRotations(ifstream& In, ofstream& Out, ObFormat& Form)
- {
- char dirn;
- char axis;
- char ObjectName[255];
- Vector Obj;
- Vector Point;
- Vector Rot;
-
- while (In)
- {
- In >> dirn;
- if (!In)
- {
- return;
- }
- if (dirn != ';')
- {
- In >> axis >> ObjectName;
- In >> Obj;
- In >> Point;
- switch (axis)
- {
- case 'x':
- RotateX(Obj,Point,Rot,dirn);
- break;
- case 'y':
- RotateY(Obj,Point,Rot,dirn);
- break;
- case 'z':
- RotateZ(Obj,Point,Rot,dirn);
- break;
- default:
- cerr << "Unknown axis: " << axis << "\n";
- break;
- }
- switch (Form)
- {
- case FormatObject:
- OutputObject(Out, ObjectName, Rot, Obj);
- break;
- case FormatDeclare:
- OutputDeclare(Out, ObjectName, Rot, Obj);
- break;
- case FormatObjDecl:
- OutputObjDecl(Out, ObjectName, Rot, Obj);
- break;
- }
- }
- else
- {
- char ch;
- while (In.get(ch) && ch != '\n')
- {
- ;
- }
- }
- }
- }
-
- //////////////////////////////////////////
- // PrintHeader //
- // This function outputs details of //
- // the run to the file header //
- //////////////////////////////////////////
- void PrintHeader(int argc, char *argv[], ofstream& Out)
- {
- for (int i = 0; i <20; i++)
- {
- Out << "////";
- }
- Out << "\n// POV-Ray 2.2 include file generated by ROTATE\n//\n";
- Out << "// Input parameters:\n";
- for (i = 1; i < argc; i++)
- {
- Out << "//\t" << argv[i] << "\n";
- }
- Out << "//\n";
- }
-
- //////////////////////////////////////////
- // main function //
- //////////////////////////////////////////
- int main(int argc, char *argv[])
- {
- char *pInFile = "DATA.ROT";
- char *pOutFile = "ROTATE.INC";
- ObFormat OutForm = FormatObject;
-
- if (argc > 1)
- {
- ParseParams(argc, argv, &pInFile, &pOutFile, OutForm);
- }
- ifstream InFile(pInFile);
- if (!InFile)
- {
- cerr << "Cannot open input file " << pInFile << "\n";
- return 1;
- }
- ofstream OutFile(pOutFile);
- if (!OutFile)
- {
- cerr << "Cannot open output file " << pOutFile << "\n";
- return 1;
- }
- PrintHeader(argc, argv, OutFile);
- DoRotations(InFile, OutFile, OutForm);
- return 0;
- }
-