home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- Program : DNA.EXE v0.90
- Purpose : Creates twisted ladder-shaped objects ( like DNA strands ) for the
- POV-Ray v2.x raytracer.
- Created : 12/30/93
- By : Rob Bryerton CIS [73747,433]
- File : DNA_v090.CPP
- Compiler: Microsoft C++ v8.00
- Model : Medium
- Comments: To do... add graphic preview, PolyRay and CTDS output
- *****************************************************************************/
-
- #include <fstream.h>
- #include <math.h>
- #include <stdlib.h>
- #include <string.h>
-
- const char cVERSION[6] = "v0.90";
-
- void ErrExit(char *cMessage);
-
- void GetAndValidateUserInput(char *cFileName, char *cUnionName, double *dHeight,
- double *dRadius, double *dPartRadius,
- long *lStepsPerRevolution, long *lTotalSteps,
- long *lConnectXsteps);
-
- void ShowTitle();
-
- inline void WriteCone(double dLastX, double dLastY, double dLastZ,
- double dX, double dY, double dZ,
- double dRad, ofstream& outfile, long *lGlobalCounter);
-
- void WriteFileEnd(ofstream& outfile, long lGlobalCounter);
-
- void WriteFileHeader(char *cFileName, char *cUnionName, ofstream& outfile,
- double dHeight);
-
- void WriteSceneFile(char *cFileName, char *cUnionName,
- double dHeight, double dRadius);
-
- inline void WriteSphere(double dX, double dY, double dZ, double dRad,
- ofstream& outfile, long *lGlobalCounter);
-
- int main()
- {
- char cFileName[80] = "DNA.INC";
- char cUnionName[80] = "DNA";
- double dRadius; // the radius of the twister (DNA strand)
- double dHeight; // the overall length of the object
- double dAngle; // used to calc the polar coordinates
- double dPartRadius;// the radius of the spheres (and cones) written at each coordinate
- double dLastXpos1, dLastZpos1, dLastYpos; // stores the previous values... used
- double dLastXpos2, dLastZpos2; // to connect the cones together
- long lTotalSteps;// the TOTAL number of coords calc'd
- long lStepsPerRevolution;
- long lGlobalCounter = 0; // the overall # of objects written to file
- long lConnectorCounter = 0; // ready for another connector??
- long lConnectXsteps; // connect strands every X steps
-
- const double dPI = 3.1415926535897932384626;// hmmm
- ofstream outfile; // the disk output file
-
- ShowTitle();
-
- /* get some user input and check for validity */
- GetAndValidateUserInput(cFileName, cUnionName, &dHeight,
- &dRadius, &dPartRadius,
- &lStepsPerRevolution, &lTotalSteps,
- &lConnectXsteps);
-
- /* Open file for output */
- cout<< "\nCreating data file " << cFileName << endl;
- outfile.open(cFileName,ios::out); // try to open a disk file
- if(! outfile) ErrExit("opening file."); // can't open disk file,exit
- outfile.setf(ios::showpoint | ios::fixed); // successful, set formats
-
- WriteFileHeader(cFileName, cUnionName, outfile, dHeight);
-
- /* caculate each vector and write to file */
- for(long lCurrentStep = 0; lCurrentStep < lTotalSteps; ++lCurrentStep)
- {
- dAngle = dPI * 2 * ( (double)lCurrentStep / (double)lStepsPerRevolution );
- double dXpos1 = dRadius * cos(dAngle);
- double dZpos1 = dRadius * sin(dAngle);
- double dXpos2 = fabs(dRadius) * cos(dAngle);
- double dZpos2 = fabs(dRadius) * sin(dAngle);
- double dYpos = dHeight * ( (double)lCurrentStep / (double)lTotalSteps );
-
- WriteSphere(dXpos1, dYpos, dZpos1, dPartRadius, outfile, &lGlobalCounter);
- WriteSphere(dXpos2, dYpos, dZpos2, dPartRadius, outfile, &lGlobalCounter);
-
- if(lCurrentStep > 0) // ignore this clause the first time around
- {
- WriteCone(dLastXpos1, dLastYpos, dLastZpos1, dXpos1, dYpos, dZpos1, dPartRadius, outfile, &lGlobalCounter);
- WriteCone(dLastXpos2, dLastYpos, dLastZpos2, dXpos2, dYpos, dZpos2, dPartRadius, outfile, &lGlobalCounter);
- }
-
- lConnectorCounter++;
- if(lConnectorCounter == lConnectXsteps) /* write a connector? */
- {
- WriteCone(dXpos1, dYpos, dZpos1, dXpos2, dYpos, dZpos2, dPartRadius, outfile, &lGlobalCounter);
- lConnectorCounter = 0; // reset counter to calc the next connector
- }
-
- dLastXpos1 = dXpos1; // now store x, y etc in Lastx, LastY etc
- dLastZpos1 = dZpos1; // so we can use them on the next loop to
- dLastXpos2 = dXpos2; // connect the cones and spheres together
- dLastZpos2 = dZpos2;
- dLastYpos = dYpos;
- }
-
- cout << lGlobalCounter << " objects written to " << cFileName << endl;
- WriteFileEnd(outfile, lGlobalCounter);
- outfile.close(); // close the output file
-
- WriteSceneFile(cFileName, cUnionName, dHeight, dRadius); // now write a scene file
- return(0);
- }
-
-
-
- /************************** FUNCTION DEFINITIONS *****************************/
-
-
- void ErrExit(char *cMessage)
- {
- cerr << "\a\n\nERROR" << cMessage << "- Exiting \n";
- exit(1);
- }
-
- void GetAndValidateUserInput(char *cFileName, char *cUnionName, double *dHeight,
- double *dRadius, double *dPartRadius,
- long *lStepsPerRevolution, long *lTotalSteps,
- long *lConnectXsteps)
- {
- char cBuffer[256]; // general use (user input) buffer
- const int iBUFFSIZECHAR = 80;// constant size for cin.getline() for character op's
- const int iBUFFSIZENUMB = 80;// constant size for cin.getline() for numeric op's
-
- cout << "\nOutput file name [DNA.INC]:";
- cin.getline(cBuffer,iBUFFSIZECHAR);
- if(cBuffer[0] == NULL) strcpy(cBuffer, "DNA.INC");
- cFileName = _strupr(cBuffer); // place capitalized contents of buffer in cFileName
-
- /*************** VERIFY FILENAME *****************/
- for(int i = 0; i < (int)strlen(cFileName); i++)
- if (cFileName[i] == '.') break;
- cFileName[i] = '.';
- strcpy (&cFileName[i+1], "INC");
- /*************************************************/
-
- cout << "Union name [DNA]:";
- cin.getline(cBuffer,iBUFFSIZECHAR);
- if(cBuffer[0] == NULL) strcpy(cBuffer, "DNA");
- strcpy(cUnionName, cBuffer);
-
- cout << "Height (Y units) of object [50.0]:";
- cin.getline(cBuffer,iBUFFSIZENUMB);
- *dHeight = atof(cBuffer);
- if( *dHeight <= 0.0 ) *dHeight = 50.0;
-
- cout << "Radius (X-Z) of object [10.0]:";
- cin.getline(cBuffer,iBUFFSIZENUMB);
- *dRadius = atof(cBuffer);
- if( *dRadius <= 0.0 ) *dRadius = 10.0;
- *dRadius -= (*dRadius * 2); // to make the result a negative
-
- cout << "Radius of individual objects [0.5]:";
- cin.getline(cBuffer,iBUFFSIZENUMB);
- *dPartRadius = atof(cBuffer);
- if(*dPartRadius <= 0.0 ) *dPartRadius = 0.5;
-
- cout << "Steps per revolution [30]:";
- cin.getline(cBuffer,iBUFFSIZENUMB);
- *lStepsPerRevolution = atoi(cBuffer);
- if(*lStepsPerRevolution <= 0 ) *lStepsPerRevolution = 30;
-
- cout << "Connect strands every X steps [3]:";
- cin.getline(cBuffer,iBUFFSIZENUMB);
- *lConnectXsteps = atoi(cBuffer);
- if(*lConnectXsteps <= 0 ) *lConnectXsteps = 3;
-
- cout << "Number of revolutions [1]:";
- cin.getline(cBuffer,iBUFFSIZENUMB);
- *lTotalSteps = atoi(cBuffer);
- if(*lTotalSteps <=0) *lTotalSteps = 1;
- *lTotalSteps = (*lTotalSteps * *lStepsPerRevolution);
- // That * operator sure gets around!
- }
-
- void ShowTitle()
- {
- cout << "\nDNA "<< cVERSION << ", Copyright (c) 1993 Rob Bryerton\n"
- << "Creates a data file of a twisted ladder-shaped object\n"
- << "(like a DNA strand) for the POV-Ray v2.x raytracer.\n";
- }
-
- inline void WriteCone(double dLastX, double dLastY, double dLastZ,
- double dX, double dY, double dZ,
- double dRad, ofstream& outfile, long *lGlobalCounter)
- {
- outfile << "\n cone{ < " <<dLastX<< ", " << dLastY << ", " <<dLastZ<< " >, " << dRad << ", < " <<dX<< ", " << dY << ", " <<dZ<< " >, " << dRad << " }";
- ++*lGlobalCounter; //increment counter; note that postfix notation will not work
- }
-
- void WriteFileEnd(ofstream& outfile, long lGlobalCounter)
- {
- outfile << "\n}\n"
- << "\n// " << lGlobalCounter << " objects written to this file.\n";
- }
-
- void WriteFileHeader(char *cFileName, char *cUnionName, ofstream& outfile, double dHeight)
- {
- outfile << "// This data file created by DNA.EXE " << cVERSION << " for the POV-Ray v2.x raytracer.\n"
- << "// File Name: " << cFileName << " Union Name: " << cUnionName << endl
-
- << "\n#declare " << cUnionName << " =\n"
- << "union {";
- }
-
- void WriteSceneFile(char *cFileName, char *cUnionName,
- double dHeight, double dRadius)
- {
- struct Vector{ double x,y,z;};
- char cSceneFileName[80];
- ofstream sceneOutFile;
- Vector CamLocation, CamLookAt, LightLocation;
-
- /****************************************/
- strcpy(cSceneFileName, cFileName);
- for(int i = 0; i < (int)strlen(cSceneFileName); i++)
- if (cSceneFileName[i] == '.') break; // create a SCENE filename based
- // on the include filename
- cSceneFileName[i] = '.'; // but with the ".POV" extension
- strcpy (&cSceneFileName[i+1], "POV");
- /****************************************/
-
- cout<< "Creating scene file " << cSceneFileName << endl;
-
- // calculate camera and light vectors based on object size
-
- CamLocation.x = 0;
- CamLocation.y = dHeight * 0.5;
- CamLocation.z = dHeight - (dHeight * 2.2);
-
- CamLookAt.x = 0;
- CamLookAt.y = dHeight * 0.5;
- CamLookAt.z = 0;
-
- LightLocation.x = fabs(dRadius);
- LightLocation.y = dHeight * 0.75;
- LightLocation.z = dHeight - (dHeight * 2.0);
-
- // open a disk file and write the scene file
- sceneOutFile.open(cSceneFileName,ios::out); // try to open a disk file
- if(! sceneOutFile) ErrExit("opening file."); // can't open disk file,exit
- sceneOutFile.setf(ios::showpoint | ios::fixed);
-
- sceneOutFile << "// This data file created by DNA.EXE " << cVERSION << " for the POV-Ray v2.x raytracer.\n"
- << "// Scene File: " << cSceneFileName << " Include File: " << cFileName << " Union Name: " << cUnionName << endl
- << "#include \"colors.inc\"\n"
- << "#include \"textures.inc\"\n\n";
-
- sceneOutFile << "camera {\n"
- << " location < " << CamLocation.x << ", " << CamLocation.y << ", " << CamLocation.z << " >\n"
- << " look_at < " << CamLookAt.x << ", " << CamLookAt.y << ", " << CamLookAt.z << " >\n"
- << "}\n\n";
-
- sceneOutFile << "light_source { < " << LightLocation.x << ", " << LightLocation.y << ", " << LightLocation.z << " > color White }\n"
-
- << "\n#declare " << cUnionName << "_Texture ="
- << "\ntexture { Y_Gradient finish { ambient 0.2 } scale<1," << dHeight << ",1> }\n\n";
-
- sceneOutFile << "#include \"" << cFileName << "\"\n\n"
- << "object{"
- << "\n " << cUnionName
- << "\n texture{ " << cUnionName << "_Texture rotate < 0,0,25 > }"
- << "\n}\n";
-
- sceneOutFile.close();
-
- }
-
- inline void WriteSphere(double dX, double dY, double dZ, double dRad,
- ofstream& outfile, long *lGlobalCounter)
- {
- outfile << "\n sphere{ < " << dX << ", " << dY << ", " << dZ << " > " << dRad << " }";
- ++*lGlobalCounter;//increment counter; note that postfix notation will not work
- }