void view_rotate_circle(Polygon* poly_vrp, Point* center, int sides, double scale, double thetax, double thetay, double thetaz){ if(NULL != poly_vrp){ //make a unit circle of "sides" number fo sides and store the points in the poly_vrp int i; double x, z; polygon_init(poly_vrp); Point p[sides]; Matrix LTM; matrix_identity(<M); matrix_scale(<M, scale, scale, scale); matrix_rotateX(<M, cos(thetax*M_PI/180), sin(thetax*M_PI/180)); matrix_rotateY(<M, cos(thetay*M_PI/180), sin(thetay*M_PI/180)); matrix_rotateZ(<M, cos(thetaz*M_PI/180), sin(thetaz*M_PI/180)); matrix_translate(<M, center->val[0], center->val[1], center->val[2]); for(i=0; i<sides; i++){ x = cos( i * M_PI * 2.0 / sides ); z = sin( i * M_PI * 2.0 / sides ); point_set3D(&p[i], x, 0.1, z); } polygon_set(poly_vrp, sides, &p[0]); matrix_xformPolygon(<M, poly_vrp); } }
int main(int argc, char *argv[]) { const int rows = 1000; const int cols = 1000; View3D view; Matrix vtm; Polygon side[4]; Polygon tpoly; Point tv[3]; Point v[4]; Color color[4]; Image *src; char filename[100]; double x; int i; // set some colors Color_set( &color[0], 0, 0, 1 ); Color_set( &color[1], 0, 1, 0 ); Color_set( &color[2], 1, 0, 0 ); Color_set( &color[3], 1, 0, 1 ); // initialize polygons for(i=0;i<4;i++) { polygon_init( &side[i] ); } // corners of a cube, centered at (0, 0, 0) point_set3D( &v[0], 0, 1, 0 ); point_set3D( &v[1], 1, -1, 0); point_set3D( &v[2], -1, -1, 0 ); point_set3D( &v[3], 0, 0, 1 ); //base of the pyramid polygon_set(&side[3], 3, &(v[0])); //side1 point_copy(&tv[0], &v[0]); point_copy(&tv[1], &v[2]); point_copy(&tv[2], &v[3]); polygon_set(&side[0], 3, tv); //side2 point_copy(&tv[0], &v[0]); point_copy(&tv[1], &v[1]); point_copy(&tv[2], &v[3]); polygon_set(&side[1], 3, tv); //side3 point_copy(&tv[0], &v[1]); point_copy(&tv[1], &v[2]); point_copy(&tv[2], &v[3]); polygon_set(&side[2], 3, tv); point_set3D( &(view.vrp), 1, 0, 0); vector_set( &(view.vpn), -view.vrp.val[0], -view.vrp.val[1], -view.vrp.val[2] ); vector_set( &(view.vup), 0, 0, 1 ); view.d = 1; // focal length view.du = 2; view.dv = view.du * (float)rows / cols; view.f = 0; // front clip plane view.b = 4; // back clip plane view.screenx = cols; view.screeny = rows; matrix_setView3D( &vtm, &view ); // use a temprary polygon to transform stuff polygon_init( &tpoly ); printf("Drawing pyramid\n"); x = -2; int j; for (j=0; j<50; j++){ // create image src = image_create( rows, cols ); point_set3D(&(view.vrp), x , 2, 0.5); vector_set( &(view.vpn), -x, -2, -0.5); matrix_setView3D(&vtm, &view); i=0; for(i=0;i<4;i++) { polygon_copy( &tpoly, &side[i] ); matrix_xformPolygon( &vtm, &tpoly ); // normalize by homogeneous coordinate before drawing polygon_normalize( &tpoly ); polygon_draw( &tpoly, src, color[i] ); //polygon_print( &tpoly, stdout ); } printf("Writing image\n"); sprintf(filename, "pyramid_%04d.ppm", j); image_write( src, filename); free(src); if(j<25){ x += 0.08; }else{ x -= 0.08; } } printf("Making the .gif file...\n"); system("convert -delay 10 pyramid_*.ppm ../images/ext1.gif"); system("rm -f pyramid*"); return(0); }
int main(int argc, char *argv[]) { Image *src; const int rows = 600; const int cols = 800; const int Resolution = 50; Color white; Color Grey; Color dkGrey; Color Red; Color Blue; Point unitCircle[Resolution]; Point unitSquare[4]; Point pt[Resolution]; Point ptt[Resolution]; int i, j, index = 0; Matrix VTM, GTM, LTM; Polygon *ship[50]; Color shipColor[50]; double theta = 0.0; double phaserAngle = 0.0; int firePhase = 0; color_set(&Grey, 180/255.0, 180/255.0, 183/255.0); color_set(&dkGrey, 140/255.0, 140/255.0, 143/255.0); color_set(&Red, 250/255.0, 40/255.0, 40/255.0); color_set(&Blue, 30/255.0, 20/255.0, 250/255.0); if(argc > 1) { theta = atoi(argv[1]); } printf("Drawing ship with orientation %.2f degrees\n", theta); if(argc > 2) { phaserAngle = atoi(argv[2]); firePhase = 1; printf("Drawing phaser with angle %.2f degrees\n", phaserAngle); } srand(42); src = image_create(rows, cols); color_set(&white, 1.0, 1.0, 1.0); for(i=0; i<rows; i++){ for(j=0; j<cols; j++){ if((rand()%50) == 13){ image_setColor(src, i, j, white); } } } // initialize the three matrices matrix_identity(&VTM); matrix_identity(>M); matrix_identity(<M); // Fix world coordinates as normal (x, y) // give the view window an origin at -180m, -150m // size is a 4x3 ratio // VTM = T(0, rows-1)S(cols/vx, rows/vy)T(180, 150) matrix_translate2D(&VTM, 120, 100); matrix_scale2D(&VTM, cols/(4*60), -rows/(3*60)); matrix_translate2D(&VTM, 0, rows-1); printf("VTM\n"); matrix_print(&VTM, stdout); // make a space ship oriented along the positive X axis // use the LTM to move simple primitives into place // use the GTM to rotate the ship // use the VTM to change the view // make a list of points that form the unit circle for(i=0;i<Resolution;i++) { point_set2D(&(unitCircle[i]), cos( i * 2.0 * M_PI / (float)Resolution), sin( i * 2.0 * M_PI / (float)Resolution)); } // set up the unit square point_set2D(&(unitSquare[0]), 0, 0); point_set2D(&(unitSquare[1]), 1, 0); point_set2D(&(unitSquare[2]), 1, 1); point_set2D(&(unitSquare[3]), 0, 1); // build a set of polygons that form the ship in model space // put the origin of the model between the engines // outline for the main disk matrix_identity(<M); matrix_scale2D(<M, 31, 31); // move it 20m along the X-axis matrix_translate2D(<M, 60, 0); // transform the circle points using LTM for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // add the polygon matrix_print(<M, stdout); ship[index] = polygon_createp(Resolution, pt); shipColor[index++] = Red; printf("Post-LTM\n"); polygon_print(ship[0], stdout); // main disk matrix_identity(<M); matrix_scale2D(<M, 30, 30); // move it 20m along the X-axis matrix_translate2D(<M, 60, 0); // transform the circle points using LTM for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // add the polygon matrix_print(<M, stdout); ship[index] = polygon_createp(Resolution, pt); shipColor[index++] = Grey; // central bridge disk matrix_identity(<M); matrix_scale2D(<M, 10, 10); // move it 20m along the X-axis matrix_translate2D(<M, 60, 0); // transform the circle points using LTM for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // add the polygon matrix_print(<M, stdout); ship[index] = polygon_createp(Resolution, pt); shipColor[index++] = dkGrey; // make the body disk elongated along the X axis matrix_identity(<M); matrix_scale2D(<M, 30, 12); matrix_translate2D(<M, 2.5, 0); // transform the circle points using LTM for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // add the polygon matrix_print(<M, stdout); ship[index] = polygon_createp(Resolution, pt); shipColor[index++] = Grey; // make a trapezoidal strut out of the unit square matrix_identity(<M); matrix_translate2D(<M, -0.5, 0.0); matrix_scale2D(<M, 10, 10); matrix_shear2D(<M, .2, 0.0); for(i=0;i<4;i++) { matrix_xformPoint(<M, &(unitSquare[i]), &(pt[i])); } // move the strut out from the origin along the Y axis matrix_identity(<M); matrix_translate2D(<M, 0, 12); for(i=0;i<4;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon matrix_print(<M, stdout); ship[index] = polygon_createp(4, ptt); shipColor[index++] = Grey; // place the second strut matrix_identity(<M); matrix_scale2D(<M, 1, -1); matrix_translate2D(<M, 0, -12); for(i=0;i<4;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon ship[index] = polygon_createp(4, ptt); shipColor[index++] = Grey; // create an engine outline from the unit circle matrix_identity(<M); matrix_scale2D(<M, 31, 6); // make the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // send one engine to the right location matrix_identity(<M); matrix_translate2D(<M, -5, 27); // move the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon ship[index] = polygon_createp(Resolution, ptt); shipColor[index++] = Blue; // send the other engine to the right location matrix_identity(<M); matrix_translate2D(<M, -5, -27); // move the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon ship[index] = polygon_createp(Resolution, ptt); shipColor[index++] = Blue; // create an engine matrix_identity(<M); matrix_scale2D(<M, 30, 5); // make the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(unitCircle[i]), &(pt[i])); } // send one engine to the right location matrix_identity(<M); matrix_translate2D(<M, -5, 27); // move the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon ship[index] = polygon_createp(Resolution, ptt); shipColor[index++] = Grey; // send the other engine to the right location matrix_identity(<M); matrix_translate2D(<M, -5, -27); // move the engine for(i=0;i<Resolution;i++) { matrix_xformPoint(<M, &(pt[i]), &(ptt[i])); } // add the polygon ship[index] = polygon_createp(Resolution, ptt); shipColor[index++] = Grey; // set up the phaser if(firePhase) { matrix_identity(<M); matrix_scale2D(<M, 100, 2); // orient the phaser matrix_rotateZ(<M, cos(phaserAngle*M_PI/180.0), sin(phaserAngle*M_PI/180.0)); // translate it to the center of the disk and out matrix_translate2D(<M, 60 + 30 * cos(phaserAngle*M_PI/180.0), 30 * sin(phaserAngle*M_PI/180.0) ); // use the unit square for(i=0;i<4;i++) { matrix_xformPoint(<M, &(unitSquare[i]), &(pt[i])); } // add the polygon ship[index] = polygon_createp(4, pt); shipColor[index++] = Red; } matrix_rotateZ(>M, cos(theta*M_PI/180.0), sin(theta*M_PI/180.0)); printf("GTM:\n"); matrix_print(>M, stdout); printf("Pre-GTM/VTM\n"); polygon_print(ship[0], stdout); for(i=0;i<index;i++) { // multiply the polygon by the global transform matrix matrix_xformPolygon(>M, ship[i]); if(i==0) { printf("Pre-VTM\n"); polygon_print(ship[i], stdout); } // multiply the polygon by the view transformation matrix matrix_xformPolygon(&VTM, ship[i]); if(i==0) { printf("Pre-draw\n"); polygon_print(ship[i], stdout); } // draw the polygon polygon_drawFill(ship[i], src, shipColor[i]); } image_write(src, "space.ppm"); image_free(src); return(0); }
int main(int argc, char *argv[]) { const int rows = 100; const int cols = 100; const int nFrames = 16; // View3D view3D; View2D view; //Matrix vtm; Matrix vtm, gtm, ltm; Polygon poly[16]; Point vp[4]; FILE *fp; fp = fopen("matrix_info.txt","w"); Image *src; int i, j, t; char filename[256]; Color color[6]; // set some colors color_set( &color[0], 0, 0, 1 ); // blue color_set( &color[1], 0, 1, 0 ); // green color_set( &color[2], 1, 0, 0 ); // red color_set( &color[3], 1, 0, 1 ); // magenta color_set( &color[4], 0, 1, 1 ); // cyan color_set( &color[5], 1, 1, 0 ); // yellow // optional theta value // if(argc > 1) { // theta = atoi(argv[1]); // } // initialize the three matrices matrix_identity(&vtm); matrix_identity(>m); matrix_identity(<m); // create image src = image_create( rows, cols ); srand ( time(NULL) ); for (i=0; i<16; i++){ for (j=0; j<4; j++){ point_set2D(&(vp[j]), rand()%cols, rand()%rows); } poly[i] = *(polygon_createp(4, vp)); } // grab command line argument to determine viewpoint // and set up the view structure if( argc > 1 ) { float alpha = atof( argv[1] ); if( alpha < 0.0 || alpha > 1.0 ){ alpha = 0.0; } point_set1( &(view.vrp), 3*alpha, 2*alpha, -2*alpha - (1.0-alpha)*3 ); } else { point_set1( &(view.vrp), 3, 2, -2 ); } vector_set( &(view.x), -view.vrp.val[0], -view.vrp.val[1], -view.vrp.val[2] ); view.dx = 1; // focal length view.screenx = cols; view.screeny = rows; matrix_setView2D( &vtm, &view ); matrix_print(&vtm, fp); // create image in arbitrary world coordinates for(t=0;t<nFrames;t++) { setWhite( src ); for (i=0; i<16; i++){ // need to add print statements to follow the ltm and polygons // Polygons not drawing matrix_identity(<m); matrix_translate2D(<m, -vp[0].val[0], -vp[0].val[1]); matrix_shear2D(<m, t, 0); matrix_translate2D(<m, vp[0].val[0], vp[0].val[1]); matrix_xformPolygon(<m, &poly[i]); matrix_xformPolygon(&vtm, &poly[i]); printf("begin scanline fill...\n"); polygon_drawFill(&poly[i], src, color[i%5]); printf("...end scanline fill\n"); } printf("hello: %d\n", t); sprintf(filename, "test5vt-%04d.ppm", t ); image_write( src, filename ); // translate the view across the scene point_set2D( &(view.vrp), 1.8 - 2.4*(t+1)/nFrames, 1.8 - 2.4*(t+1)/nFrames ); matrix_setView2D( &vtm, &view ); } fclose(fp); system("convert test5vt-*.ppm test5vt.gif"); //system("rm test5vt-*.ppm"); }
int main(int argc, char *argv[]) { const int rows = 180; const int cols = 320; const int nFrames = 100; View3D view; Matrix vtm; Polygon side[6]; Polygon tpoly; Point tv[4]; Point v[8]; Color color[6]; Image *src; int i, t; char filename[256]; // set some colors color_set( &color[0], 0, 0, 1 ); color_set( &color[1], 0, 1, 0 ); color_set( &color[2], 1, 0, 0 ); color_set( &color[3], 1, 0, 1 ); color_set( &color[4], 0, 1, 1 ); color_set( &color[5], 1, 1, 0 ); for(t=0;t<nFrames;t++) { // initialize polygons for(i=0;i<6;i++) { polygon_init( &side[i] ); } // corners of a cube, centered at (0, 0, 0) point_set1( &v[0], -1, -1, -1 ); point_set1( &v[1], 1, -1, -1 ); point_set1( &v[2], 1, 1, -1 ); point_set1( &v[3], -1, 1, -1 ); point_set1( &v[4], -1, -1, 1 ); point_set1( &v[5], 1, -1, 1 ); point_set1( &v[6], 1, 1, 1 ); point_set1( &v[7], -1, 1, 1 ); // front side polygon_set( &side[0], 4, &(v[0]) ); // back side polygon_set( &side[1], 4, &(v[4]) ); // top side point_copy( &tv[0], &v[2] ); point_copy( &tv[1], &v[3] ); point_copy( &tv[2], &v[7] ); point_copy( &tv[3], &v[6] ); polygon_set( &side[2], 4, tv ); // bottom side point_copy( &tv[0], &v[0] ); point_copy( &tv[1], &v[1] ); point_copy( &tv[2], &v[5] ); point_copy( &tv[3], &v[4] ); polygon_set( &side[3], 4, tv ); // left side point_copy( &tv[0], &v[0] ); point_copy( &tv[1], &v[3] ); point_copy( &tv[2], &v[7] ); point_copy( &tv[3], &v[4] ); polygon_set( &side[4], 4, tv ); // right side point_copy( &tv[0], &v[1] ); point_copy( &tv[1], &v[2] ); point_copy( &tv[2], &v[6] ); point_copy( &tv[3], &v[5] ); polygon_set( &side[5], 4, tv ); // grab command line argument to determine viewpoint // and set up the view structure /*if( argc > 1 ) { float alpha = atof( argv[1] ); if( alpha < 0.0 || alpha > 1.0 ) alpha = 0.0; point_set1( &(view.vrp), 3*alpha, 2*alpha, -2*alpha - (1.0-alpha)*3 ); } else { point_set1( &(view.vrp), 3, 2, -2 ); } */ float alpha = abs(t - (0.5*nFrames)) / (0.5*nFrames); point_set1( &(view.vrp), 3*alpha, 2*alpha, -2*alpha - (1.0-alpha)*3 ); vector_set( &(view.vpn), -view.vrp.val[0], -view.vrp.val[1], -view.vrp.val[2] ); vector_set( &(view.vup), 0, 1, 0 ); view.d = 1; // focal length view.du = 2; view.dv = view.du * (float)rows / cols; view.f = 0; // front clip plane view.b = 4; // back clip plane view.screenx = cols; view.screeny = rows; matrix_setView3D( &vtm, &view ); // create image src = image_create( rows, cols ); // use a temprary polygon to transform stuff polygon_init( &tpoly ); //printf("Drawing Polygons\n"); for(i=0;i<6;i++) { polygon_copy( &tpoly, &side[i] ); matrix_xformPolygon( &vtm, &tpoly ); // normalize by homogeneous coordinate before drawing polygon_normalize( &tpoly ); polygon_draw( &tpoly, src, color[i] ); //polygon_print( &tpoly, stdout ); } sprintf(filename, "frame-%04d.ppm", t ); image_write( src, filename ); /*printf("Writing image\n"); image_write( src, "cube.ppm" );*/ } system("convert frame-*.ppm cube.gif"); system("rm frame-*.ppm"); return(0); }
/* * Draw the module into the image using the given view transformation matrix [VTM], * Lighting and DrawState by traversing the list of Elements. * (For now, Lighting can be an empty structure.) */ void module_draw(Module *md, Matrix *VTM, Matrix *GTM, DrawState *ds, Lighting *lighting, Image *src){ /* for antialiasing Module *thickLineMod = module_create(); Element *thickLineE; float dx, dy, dz, lineLength; Vector u, v, w;*/ // all locally needed variables Matrix LTM, tempGTM; Line tempLine; DrawState *tempds = drawstate_create(); Point tempPointLTM, tempPointGTM, tempPointVTM; Polyline *tempPolyline = polyline_create(); Polygon *tempPolygon = polygon_create(); Element *e = md->head; matrix_identity(<M); // loop until the end of the linked list is reached while(e){ //printf("Handling type %d\n", e->type); // draw based on type switch(e->type){ case ObjNone: break; case ObjPoint: //printf("drawing point "); // copy, xform, normalize, draw matrix_xformPoint(<M, &(e->obj.point), &tempPointLTM); matrix_xformPoint(GTM, &tempPointLTM, &tempPointGTM); matrix_xformPoint(VTM, &tempPointGTM, &tempPointVTM); point_normalize(&(tempPointVTM)); //point_print(&tempPointVTM, stdout); point_draw(&tempPointVTM, src, ds->color); break; case ObjLine: line_copy(&tempLine, &(e->obj.line)); //printf("drawing line "); // copy, xform, normalize, draw matrix_xformLine(<M, &tempLine); matrix_xformLine(GTM, &tempLine); matrix_xformLine(VTM, &tempLine); line_normalize(&tempLine); line_draw(&tempLine, src, ds->color); //line_print(&tempLine, stdout); /*if(antialias){ dx = tempLine.b.val[0]-tempLine.a.val[0]; dy = tempLine.b.val[1]-tempLine.a.val[1]; dz = tempLine.b.val[2]-tempLine.a.val[2]; lineLength = sqrt(dx*dx+dy*dy+dz*dz); module_scale( thickLineMod, 1, lineLength, 1 ); vector_set(&v, dx, dy, dz); vector_normalize(&v); vector_set(&u, -dz, dx, dy); vector_cross(&u, &v, &w); vector_cross(&v, &w, &u); vector_normalize(&u); vector_normalize(&w); module_rotateXYZ( thickLineMod, &u, &v, &w ); module_translate( thickLineMod, tempLine.a.val[0], tempLine.a.val[1], tempLine.a.val[2] ); module_cylinder( thickLineMod, 4, 1, 1, 0, 0, 0 ); thickLineE = element_init(ObjModule, thickLineMod); thickLineE->next = e->next; e->next = thickLineE; }*/ break; case ObjPolyline: //printf("drawing polyline "); // copy, xform, normalize, draw polyline_copy(tempPolyline, &(e->obj.polyline)); matrix_xformPolyline(<M, tempPolyline); matrix_xformPolyline(GTM, tempPolyline); matrix_xformPolyline(VTM, tempPolyline); polyline_normalize(tempPolyline); //polyline_print(tempPolyline, stdout); polyline_draw(tempPolyline, src, ds->color); break; case ObjPolygon: //printf("drawing polygon "); // copy, xform, normalize, draw polygon_copy(tempPolygon, &(e->obj.polygon)); matrix_xformPolygon(<M, tempPolygon); matrix_xformPolygon(GTM, tempPolygon); matrix_xformPolygon(VTM, tempPolygon); polygon_normalize(tempPolygon); //polygon_print(tempPolygon, stdout); polygon_draw(tempPolygon, src, ds); break; case ObjColor: drawstate_setColor(ds, e->obj.color); break; case ObjBodyColor: break; case ObjSurfaceColor: break; case ObjSurfaceCoeff: break; case ObjLight: break; case ObjIdentity: matrix_identity(<M); break; case ObjMatrix: matrix_multiply(&(e->obj.matrix), <M, <M); break; case ObjModule: matrix_multiply(GTM, <M, &tempGTM); drawstate_copy(tempds, ds); module_draw(e->obj.module, VTM, &tempGTM, tempds, lighting, src); break; default: printf("ObjectType %d is not handled in module_draw\n",e->type); } // advance traversal e = e->next; } // clean up polygon_free(tempPolygon); polyline_free(tempPolyline); free(tempds); }