//sets the vtm to be the virw transfermation defined by the 2D View structure void matrix_setView2D(Matrix *vtm, View2D *view){ matrix_identity(vtm); matrix_translate2D(vtm, -view->vrp.val[0], -view->vrp.val[1]); matrix_rotateZ(vtm, view->x.val[0], -view->x.val[1]); matrix_scale2D(vtm, (view->screenx / view->dx), (-view->screenx / view->dx)); // S(C/ du, R/ dv) where dv = du*R/ C matrix_translate2D(vtm, (view->screenx / 2.0), (view->screeny / 2.0)); }
void matrix_setView2D(Matrix *vtm, View2D *view){ if(NULL != vtm && NULL != view){ float dv = (view->dx*view->screeny)/view->screenx; matrix_identity(vtm); matrix_print(vtm, stdout); matrix_translate2D(vtm, -view->vrp.val[0], -view->vrp.val[1]); matrix_rotateZ(vtm, view->x.val[0], -view->x.val[1]); matrix_scale2D(vtm, view->screenx/view->dx, -view->screeny/dv); matrix_translate2D(vtm, view->screenx/2, view->screeny/2); } }
//3D viewing pipeline. VTM is complete view matrix. none of the values of the View structure should be edited. void matrix_setView3D(Matrix *vtm, View3D *view){ Vector u, vup, vpn; double b, d; matrix_identity(vtm); matrix_translate(vtm, -view->vrp.val[0], -view->vrp.val[1], -view->vrp.val[2]); vpn = view->vpn; vector_cross(&view->vup, &vpn, &u); vector_cross(&vpn, &u, &vup); vector_normalize(&u); vector_normalize(&vup); vector_normalize(&vpn); matrix_rotateXYZ(vtm, &u, &vup, &vpn); matrix_translate(vtm, 0.0, 0.0, view->d); // in lecture notes here (6 and 7) it says to shear but as we only have d to define the COP I don't think we have to b = view->d + view->b; matrix_scale(vtm, ((2.0*view->d) / (b*view->du)), ((2.0*view->d) / (b*view->dv)), (1/b)); d = view->d / b; matrix_perspective(vtm, d); matrix_scale2D(vtm, (-view->screenx / (2.0*d)), (-view->screeny / (2.0*d))); matrix_translate2D(vtm, (view->screenx / 2.0), (view->screeny / 2.0)); }
void matrix_setView3D(Matrix *vtm, View3D *view){ if(NULL != vtm && NULL != view){ Vector u; Vector vup = view->vup; Vector vpn = view->vpn; Matrix project; double bPrime = view->d +view->b; double dPrime = view->d/bPrime; matrix_identity(vtm); printf("before everything:\n"); matrix_print(vtm, stdout); vector_cross(&vup,&vpn,&u); vector_cross(&vpn,&u,&vup); printf("vrp:\n"); vector_print(&view->vrp,stdout); matrix_translate(vtm, -view->vrp.val[0], -view->vrp.val[1],-view->vrp.val[2]); printf("After VRP translation:\n"); matrix_print(vtm, stdout); vector_normalize(&u); vector_normalize(&vpn); vector_normalize(&vup); matrix_rotateXYZ(vtm, &u, &vup, &vpn ); printf("After Rxyz :\n"); matrix_print(vtm, stdout); matrix_translate(vtm, 0, 0,view->d); printf("After translating COP to origin:\n"); matrix_print(vtm, stdout); matrix_scale(vtm, (2*view->d)/(bPrime*view->du), (2*view->d)/(bPrime*view->dv), 1/bPrime); printf("After scaling to CVV:\n"); matrix_print(vtm, stdout); matrix_identity(&project); project.m[3][3]=0; project.m[3][2]=1/dPrime; printf("projection:\n"); matrix_print(&project, stdout); matrix_multiply(&project,vtm,vtm); printf("After perspective:\n"); matrix_print(vtm, stdout); matrix_scale2D(vtm, -view->screenx/(2*dPrime), -view->screeny/(2*dPrime)); printf("After scale to image coords:\n"); matrix_print(vtm, stdout); matrix_translate2D(vtm, view->screenx/2, view->screeny/2); printf("After final translation to image coords:\n"); matrix_print(vtm, stdout); } }
/* * Matrix operand to add a translation matrix to the tail of the module’s list. */ void module_translate2D(Module *md, double tx, double ty){ if(!md){ printf("Null md passed to module_translate2D\n"); return; } Element *e; Matrix m; matrix_identity(&m); matrix_translate2D(&m,tx,ty); e = element_init(ObjMatrix, &m); module_insert(md, e); }
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"); }