Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

C++ Creating a 3D Fly-by Movie in C++

#include #include #include #include #include #include #include #include using namespace std; double pi = 3.14158748587; typedef struct start_t { double RA; double DEC; double MAG; }Star; typedef struct camera_t { double fovx; double fovy; double f; int width; int height; double RA; double distance; }Camera; typedef struct image_t { int width; int height; unsigned char *data; }Image; typedef struct moon_t { Image texture; double radius; }Moon; // print an error message void error(string message) { cout << "Error: "<< message << endl; exit(1); } // initialize the image structure void setImage(int width,int height,Image & img) { img.width=width; img.height=height; img.data=new unsigned char[width*height]; for(int i=0; i> img.width; ss >> img.height; setImage(img.width,img.height,img); in.read((char*)img.data,img.width*img.height); in.close(); } // convert from HH:MM:SS.FRAC to double double convertFormat(string str) { double parts[3]; int part=0; int start=0; for (int i=0; i<=str.length(); ++i) { if(str==':' || str=='\0') { str='\0'; parts[part++]=atof(str.substr(start,i-start).c_str()); start=i+1; } } if(parts[0]<0) return -(-parts[0]+parts[1]/60.+parts[2]/3600.); else return parts[0]+parts[1]/60.+parts[2]/3600.; } // load the bright star catalog vector readCatalog() { vector stars; ifstream catalog; string buffer; catalog.open("kpno_brightstar_catalog"); if(!catalog.is_open()) error("Unable to open catalog file!"); getline(catalog,buffer); // get rid of header getline(catalog,buffer); while(getline(catalog,buffer)) { if(buffer.find("????")!=std::string::npos) // invalid line continue; Star star; stringstream ss(buffer); int line; string ra,dec,temp; ss >> line; ss >> ra; ss >> dec; ss >> temp; ss >> temp; ss >> temp; ss >> star.MAG; star.RA=(convertFormat(ra)*360.0/24.0)*pi/180.0; // convert to rads star.DEC=convertFormat(dec)*pi/180.0; // convert to rads stars.push_back(star); } return stars; } void setCamera(double fovx,double fovy,int width,Camera & camera) { camera.width=width; camera.fovx=fovx*pi/180.0; camera.f = 0.5*camera.width/tan(0.5*camera.fovx); // same focus for both directions camera.fovy=fovy*pi/180.0; camera.height=ceil(2*tan(0.5*camera.fovy)*camera.f); // round up camera.RA = 0.0; } // position camera at the right ascencion RA in degrees void positionCamera(double RA,double position,Camera & camera) { camera.RA = RA*pi/180.0; camera.distance=position; } // determine if the star is in the field of view of the camera int in_FOV(Star star,Camera camera) { double startAngle,endAngle; if(star.DEC < 0.5*camera.fovy && star.DEC>-0.5*camera.fovy) { // vertical visibility startAngle=camera.RA-0.5*camera.fovx; endAngle=camera.RA+0.5*camera.fovx; if(startAngle<0) { startAngle=2*pi+startAngle; if(star.RA > startAngle && star.RA < 2*pi) return 1; else if(star.RA >= 0 && star.RA < endAngle) return 1; else return 0; } else if(endAngle>2*pi) { endAngle=endAngle-2*pi; if(star.RA > startAngle && star.RA < 2*pi) return 1; else if(star.RA >= 0 && star.RA < endAngle) return 1; else return 0; } else if(star.RA > startAngle && star.RA < endAngle) return 1; } return 0; } // put a pixel in the image, trim if necessary void putPixel(int x,int y,unsigned char color,Image img) { if(x<0 || x>=img.width) return; if(y<0 || y>=img.height) return; int pos=(img.height-1-y)*img.width+img.width-1-x; unsigned newColor=color+img.data[pos]; if(newColor>255) newColor=255; img.data[pos]=newColor; } // put a pixel in the image, discard previous content void setPixel(int x,int y,unsigned char color,Image img) { if(x<0 || x>=img.width) return; if(y<0 || y>=img.height) return; int pos=(img.height-1-y)*img.width+img.width-1-x; img.data[pos]=color; } // get a pixel from the image unsigned char getPixel(int x,int y,Image img) { if(x<0 || x>=img.width) return 0; if(y<0 || y>=img.height) return 0; int pos=y*img.width+img.width-1-x; return img.data[pos]; } // draw a star as a small blob void drawStar(Star star,Camera camera,Image img) { double k = 2.0*star.MAG; // luminosity decay double startAngle=camera.RA-0.5*camera.fovx; double endAngle=camera.RA+0.5*camera.fovx; double y0 = (0.5*camera.fovy+star.DEC); double x0 = (star.RA - startAngle ); if(startAngle<0) { startAngle=2*pi+startAngle; if(star.RA > startAngle && star.RA < 2*pi) x0= (star.RA - startAngle ); } else if(endAngle>2*pi) { endAngle=endAngle-2*pi; if(star.RA > startAngle && star.RA < 2*pi) x0= (star.RA - startAngle ); else if(star.RA >= 0 && star.RA < endAngle) x0= (star.RA - startAngle + 2*pi ); } x0=x0*img.width/camera.fovx; y0=y0*img.height/camera.fovy; for(int x=-14; x<=14; ++x) { for(int y=-14; y<=14; ++y) { double r=x*x+y*y; int color=255*exp(-r/k); putPixel(x0+x,y0+y,color,img); } } } // draw the moon using the texture void drawMoon(Camera camera,Image img,Moon moon) { double theta = 2.0*atan(moon.radius/camera.distance); int d=theta*img.width/camera.fovx; for(double x=-d/2; x<=d/2; ++x) for(double y=-d/2; y<=d/2; ++y) { if(x*x+y*y<=d*d/4.0) { double yp=y*camera.distance/camera.f; double xp=x*camera.distance/camera.f; double rho=sqrt(xp*xp+yp*yp); double c = asin(rho/moon.radius); double lat = asin(yp/moon.radius); double lon = camera.RA + pi + atan2((xp/moon.radius),cos(c)); double u = 0.5 + atan2(sin(lon),cos(lon))/(2.*pi); double v = 0.5 - lat/pi; int tx=(moon.texture.width-1)*u; int ty=(moon.texture.height-1)*v; double px,py; px=x+img.width/2; py=y+img.height/2; setPixel(px,py,0.8*getPixel(tx,ty,moon.texture),img); } } } // render the picture void render(vector stars,Camera camera,Image img,Moon moon) { for(int i=0; i stars=readCatalog(); setCamera(24.0,16.0,1200,camera); Image img,texture; setImage(camera.width,camera.height,img); loadPGM("moon_shaded_1k.pgm",texture); Moon moon; moon.radius=1737; moon.texture=texture; int frame=0; int nframes = 500; for(double RA=0.0; RA<=360; RA+=360./nframes) { clearImage(img); positionCamera(RA,80000,camera); render(stars,camera,img,moon); stringstream ss; ss << "img_"; ss << ceil(camera.fovx*180/pi) << "x"; ss << ceil(camera.fovy*180/pi) << "_"; ss << setw(4) << setfill('0') << right << frame << ".pgm"; savePGM(ss.str().c_str(),img); frame++; } return (0); }
 

New Threads

Buy us a coffee!

Back
Top Bottom