/*Conjugate gradient method from wikipedia. First version by Jasmin, changes made by Alex*/ int conjugateGradient(struct Matrix* a, struct Vector* b, struct Vector* initialVal, struct Vector** x, int size, double precision, int steps){ copy_Vector(initialVal,x[0]); //This could still be optimised struct Vector** r = malloc(sizeof(struct Vector*)*steps); for (int j=0; j < steps; j++) { r[j] = new_Vector(size); } struct Vector* p = new_Vector(size); struct Vector* help=new_Vector(size); struct Vector* help1=new_Vector(size); double alpha, beta, sp1, sp2; multiply_Matrix_Vector(a,x[0],help); scale_Vector(-1,help,help); //set r[0] add_Vectors(b,help,r[0]); copy_Vector(r[0],p); int i=0; int lastIndex=0; for(i=0;i<steps-1;i++){ sp1 =scalarproductRn(r[i],r[i],size); sp2 =scalarproductMatrix(a,p,p,size); alpha = sp1/sp2; scale_Vector(alpha,p,help1); add_Vectors(x[i],help1,x[i+1]); multiply_Matrix_Vector(a,p,help); scale_Vector(-1*alpha,help,help); add_Vectors(r[i],help,r[i+1]); lastIndex=i+1; if(vectornorm(r[i+1])<precision){ break; } sp1=scalarproductRn(r[i+1],r[i+1],size); sp2=scalarproductRn(r[i],r[i],size); beta = sp1/sp2; scale_Vector(beta,p,help); add_Vectors(help,r[i+1],p); } delete_Vector(p); delete_Vector(help); delete_Vector(help1); for (int j=0; j < steps; j++) { delete_Vector(r[j]); } free(r); return lastIndex; }
/*Gives you the gradient in x of function above, result is stored in gradient*/ void getGradient(struct Matrix* a, struct Vector* b, struct Vector* x, struct Vector* gradient, int size){ struct Vector* help= new_Vector(size); struct Vector* help2= new_Vector(size); struct Matrix* transposed=new_Matrix(size,size); transpose(a,transposed); multiply_Matrix_Vector(a,x, help); for(int i=0;i<size;i++){ help->values[i]=help->values[i]-b->values[i]; } multiply_Matrix_Vector(transposed,help,help2); scale_Vector(2,help2,gradient); delete_Vector(help); delete_Vector(help2); delete_Matrix(transposed); }
/* Explicit Euler Scheme */ void euler (void (*f)(double,struct Vector*,struct Vector*), double t0, struct Vector* y0, double h, double* t, struct Vector** y, int steps) { t[0] = t0; y[0] = y0; struct Vector* tmp1; struct Vector* tmp2; for (int j=1; j<steps; j++) { t[j] = t0+j*h; tmp1 = new_Vector(DIM); tmp2 = new_Vector(DIM); f(t[j-1],y[j-1],tmp1); scale_Vector(h,tmp1,tmp2); add_Vectors(y[j-1],tmp2,y[j]); delete_Vector(tmp1); delete_Vector(tmp2); } }
float * FonctionsMath::resol_ConjGrad(float ** A,float * b,int n) { float * x,* r,* s,* p,* q,** tA,alpha,beta,normRSqr; x=new_Vector(n); tA=transp_Mat_Sqr(A,n); init_Vector_norm1(x,n,norm_Vector_2(b,n)); s=minus_Vector(b,prod_MatVector_Sqr(A,x,n),n); r=prod_MatVector_Sqr(tA,s,n); p=affectValues_Vector(r,n); q=prod_MatVector_Sqr(A,p,n); do { normRSqr=dot_Prod(r,r,n); alpha=normRSqr/dot_Prod(q,q,n); x=plus_Vector(x,scalProd_Vector(alpha,p,n),n); s=minus_Vector(s,scalProd_Vector(alpha,q,n),n); delete [] r; r=prod_MatVector_Sqr(tA,s,n); beta=dot_Prod(r,r,n)/normRSqr; p=plus_Vector(r,scalProd_Vector(beta,p,n),n); q=prod_MatVector_Sqr(A,p,n); } while(norm_Vector_inf(s,n)/norm_Vector_2(b,n) > PRECISION); return x; }
float * FonctionsMath::base_Vector(int i,int n) { float *x; x=new_Vector(n); x[i]=1; return x; }
/*scalarproduct induced by matrix*/ double scalarproductMatrix(struct Matrix* a, struct Vector* x, struct Vector* y, int size){ struct Vector* help=new_Vector(size); multiply_Matrix_Vector(a,x,help); double value = scalarproductRn(help,y,size); delete_Vector(help); return value; }
float * FonctionsMath::affectValues_Vector(float * b,int n) { float * c; int i; c=new_Vector(n); for(i=0;i<n;i++) c[i]=b[i]; return c; }
Order_list* new_Order_list(Streader* sr) { rassert(sr != NULL); if (Streader_is_error_set(sr)) return NULL; // Create the base structure Order_list* ol = memory_alloc_item(Order_list); if (ol == NULL) { Streader_set_memory_error( sr, "Could not allocate memory for order list"); return NULL; } ol->pat_insts = NULL; ol->index_map = NULL; // Create Pattern instance reference vector ol->pat_insts = new_Vector(sizeof(Pat_inst_ref)); if (ol->pat_insts == NULL) { Streader_set_memory_error( sr, "Could not allocate memory for order list"); del_Order_list(ol); return NULL; } // Create reverse index of ol->pat_insts ol->index_map = new_AAtree( (AAtree_item_cmp*)Pat_inst_ref_cmp, (AAtree_item_destroy*)memory_free); if (ol->index_map == NULL) { Streader_set_memory_error( sr, "Could not allocate memory for order list"); del_Order_list(ol); return NULL; } // List is empty by default if (!Streader_has_data(sr)) return ol; // Read the list of Pattern instance references if (!Streader_read_list(sr, read_piref, ol)) { del_Order_list(ol); return NULL; } return ol; }
float * FonctionsMath::plus_Vector(float * x,float * y,int n) { int i; float * z; z=new_Vector(n); for(i=0;i<n;i++) z[i]=x[i]+y[i]; return z; }
float * FonctionsMath::extr_Vect_Mat(float ** M,int n,int j) { int i; float * x; x=new_Vector(n); for(i=0;i<n;i++) x[i]=M[i][j]; return x; }
float * FonctionsMath::scalProd_Vector(float a,float * A,int n) { int i; float * C; C=new_Vector(n); for(i=0;i<n;i++) C[i]=a*A[i]; return C; }
/* Adaptive Runge-Kutta Scheme of order 3, uses tol for stepsize-control */ void adaptive_rk3 (void (*f)(double,struct Vector*,struct Vector*), double t0, struct Vector* y0, double tol, double* t, struct Vector** y, int steps) { t[0] = t0; y[0] = y0; double h; double norm; struct Vector* k1; struct Vector* k2; struct Vector* k3; struct Vector* tmp1; struct Vector* tmp2; struct Vector* tmp3; for (int j=1; j<steps; j++) { bool adapt = true; h = 1; k1 = new_Vector(DIM); k2 = new_Vector(DIM); k3 = new_Vector(DIM); tmp1 = new_Vector(DIM); tmp2 = new_Vector(DIM); tmp3 = new_Vector(DIM); while(adapt) { f(t[j-1],y[j-1],k1); scale_Vector(h,k1,tmp1); add_Vectors(y[j-1],tmp1,tmp2); f(t[j-1]+h,tmp2,k2); add_Vectors(k1,k2,tmp1); scale_Vector(h/4,tmp1,tmp2); add_Vectors(y[j-1],tmp2,tmp1); f(t[j-1]+h/2,tmp1,k3); scale_Vector(2,k3,tmp1); scale_Vector(-1,k2,tmp2); add_Vectors(tmp1,tmp2,tmp3); scale_Vector(-1,k1,tmp1); add_Vectors(tmp1,tmp3,tmp2); norm = vectornorm(tmp2); if (h/3*norm < tol) { adapt = false; add_Vectors(k1,k2,tmp1); scale_Vector(4,k3,tmp2); add_Vectors(tmp1,tmp2,tmp3); scale_Vector(h/6,tmp3,tmp1); add_Vectors(y[j-1],tmp1,y[j]); } else { if (3/2*tol/norm>0) { h = 3/2*tol/norm; } else { h = h/2; } } } t[j] = t[j-1]+h; delete_Vector(tmp1); delete_Vector(tmp2); delete_Vector(tmp3); delete_Vector(k1); delete_Vector(k2); delete_Vector(k3); } }
float * FonctionsMath::prod_MatVector_Sqr(float ** A,float *b, int n) { int i,j; float * x; x=new_Vector(n); for(i=0;i<n;i++) for(j=0;j<n;j++) x[i]=x[i]+A[i][j]*b[j]; return x; }
double normAxb_squared(struct Matrix* a, struct Vector* b, struct Vector* x, int size){ int i=0; double scalarprod=0; struct Vector* help= new_Vector(size); multiply_Matrix_Vector(a,x, help); for(i=0;i<size;i++){ help->values[i]=help->values[i]-b->values[i]; help->values[i]*=help->values[i]; scalarprod+=help->values[i]; } delete_Vector(help); return scalarprod; }
/* Gradient Descent Method, assuming gamma is given?*/ void gradientDescent(struct Matrix* a, struct Vector* b, struct Vector* initialVal, struct Vector** x, double gamma, int size, int steps){ copy_Vector(initialVal,x[0]); int i=0; struct Vector* gradient=new_Vector(size); for(i=1;i<steps;i++){ getGradient(a,b,x[i-1],gradient,size); scale_Vector(-gamma,gradient,gradient); add_Vectors(x[i-1],gradient,x[i]); } delete_Vector(gradient); }
float * FonctionsMath::resol_Up(float ** A,float *b,int n) { int i,j; float *x,s; x=new_Vector(n); x[n-1]=b[n-1]/A[n-1][n-1]; for(i=(n-2);i >= 0;i--) { s=0; for(j=(i+1);j<n;j++) s=s+A[i][j]*x[j]; x[i]=(b[i]-s)/A[i][i]; } return x; }
float * FonctionsMath::sign_Vector(float * x,int n) { int i; float * s; s=new_Vector(n); for(i=0;i<n;i++) { if(x[i] > 0) s[i]=1; else if(x[i]==0) s[i]=0; else s[i]=-1; } return s; }
Visual* link_Scene( Scene* sc, pointer tag, uint32 mask, Drawable* dr, Shader_Arg* argv ) { struct Bucket* bucket = lookup_Map( sc->buckets, sizeof( tag ), &tag ); if( NULL == bucket ) { // Create a new bucket bucket = ralloc( sc->R, sizeof(struct Bucket) ); bucket->visuals = new_Vector( ZONE_heap, sizeof(Visual), bucketSize ); bucket->freelist = NULL; put_Map( sc->buckets, sizeof(tag), &tag, bucket ); } // Stick it in the bucket Visual* vis = NULL; if( bucket->freelist ) { vis = bucket->freelist; bucket->freelist = vis->next; } else vis = (Visual*)push_back_Vector( bucket->visuals ); vis->tag = tag; vis->mask = mask; vis->draw = dr; vis->argv = argv; vis->next = NULL; return vis; }
/* Symplectic Euler Scheme. Only to be used for Hamiltonian systems. Requires even dimension DIM */ void symplectic_euler (void (*f)(double,struct Vector*,struct Vector*), double t0, struct Vector* y0, double h, double* t, struct Vector** y, int steps) { if (DIM%2 != 0) printf("Warning: Tried to use symplectic Euler method for vector of odd dimension"); else { t[0] = t0; y[0] = y0; struct Vector* tmp; for (int j=1; j<steps; j++) { t[j] = t0+j*h; tmp = new_Vector(DIM); f(t[j-1],y[j-1],tmp); //print_Vector(tmp); copy_Vector(y[j-1],y[j]); for(int i=DIM/2; i<DIM; i++) { y[j]->values[i] = y[j-1]->values[i] + h*tmp->values[i]; } f(t[j-1],y[j],tmp); for(int i=0; i<DIM/2; i++) { y[j]->values[i] = y[j-1]->values[i] + h*tmp->values[i]; } delete_Vector(tmp); } } }
float * FonctionsMath::resol_ConjGrad_SymPosDef(float ** A,float * b,int n) { float * x,* r,* p,* Ap,alpha,beta,normRSqr; x=new_Vector(n); init_Vector_norm1(x,n,norm_Vector_2(b,n)); r=minus_Vector(b,prod_MatVector_Sqr(A,x,n),n); p=affectValues_Vector(r,n); do { normRSqr=dot_Prod(r,r,n); Ap=prod_MatVector_Sqr(A,p,n); alpha=normRSqr/dot_Prod(p,Ap,n); x=plus_Vector(x,scalProd_Vector(alpha,p,n),n); r=minus_Vector(r,scalProd_Vector(alpha,Ap,n),n); beta=dot_Prod(r,r,n)/normRSqr; p=plus_Vector(r,scalProd_Vector(beta,p,n),n); } while(norm_Vector_inf(r,n)/norm_Vector_2(b,n) > PRECISION); return x; }
/* Runge-Kutta Scheme of order 4 */ void rk4 (void (*f)(double,struct Vector*,struct Vector*), double t0, struct Vector* y0, double h, double* t, struct Vector** y, int steps) { t[0] = t0; y[0] = y0; struct Vector* k1; struct Vector* k2; struct Vector* k3; struct Vector* k4; struct Vector* tmp1; struct Vector* tmp2; for (int j=1; j<steps; j++) { k1 = new_Vector(DIM); k2 = new_Vector(DIM); k3 = new_Vector(DIM); k4 = new_Vector(DIM); tmp1 = new_Vector(DIM); tmp2 = new_Vector(DIM); f(t[j-1],y[j-1],k1); scale_Vector(h/2,k1,tmp1); add_Vectors(y[j-1],tmp1,tmp2); f(t[j-1]+h/2,tmp2,k2); scale_Vector(h/2,k2,tmp1); add_Vectors(y[j-1],tmp1,tmp2); f(t[j-1]+h/2,tmp2,k3); scale_Vector(h,k3,tmp1); add_Vectors(y[j-1],tmp1,tmp2); f(t[j-1]+h,tmp2,k4); add_Vectors(k2,k3,tmp1); scale_Vector(2,tmp1,tmp2); add_Vectors(k1,tmp2,tmp1); add_Vectors(tmp1,k4,tmp2); scale_Vector(h/6,tmp2,tmp1); add_Vectors(y[j-1],tmp1,y[j]); t[j] = t[j-1]+h; delete_Vector(tmp1); delete_Vector(tmp2); delete_Vector(k1); delete_Vector(k2); delete_Vector(k3); } }
//Run Program int main (int argc, char** argv) { //Read input argument int in = 0; double h = 0.5; double tol = 0.1; if (argc > 1) in = atoi(argv[1]); if (argc > 2) h = atof(argv[2]); if (argc > 3) tol = atof(argv[3]); printf("Input arguments: %i %f %f \n", in, h, tol); //Check if SDL Initialization is successful if (SDL_Init(SDL_INIT_VIDEO) != 0) { return -1; } //Create Window SDL_Window *win = SDL_CreateWindow("Adaptive Step Sizes",50,50,640,480,SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); if (!win) { fprintf(stderr, "Could not create window: %s\n", SDL_GetError()); } //Initialize OpenGL SDL_GLContext context = SDL_GL_CreateContext(win); if (!context) { fprintf(stderr, "Could not create OpenGL context: %s\n", SDL_GetError()); } glViewport(0,0,(GLsizei)640,(GLsizei)480); glClearColor(1.0f,1.0f,1.0f,1.0f); glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapWindow(win); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); //Plot Functions double xpos = -0.9; double ypos = -0.9; double width = 1.8; double height = 1.8; glColor4f(0.0f,0.0f,0.0f,1.0f); glBegin(GL_LINE_LOOP); glVertex3f(xpos,ypos,0.0f); glVertex3f(xpos+width,ypos,0.0f); glVertex3f(xpos+width,ypos+height,0.0f); glVertex3f(xpos,ypos+height,0.0f); glEnd(); glBegin(GL_LINES); for (int j=1; j<10; j++) { glVertex3f(xpos+j*width/10,ypos,0.0f); glVertex3f(xpos+j*width/10,ypos+0.02f,0.0f); glVertex3f(xpos+j*width/10,ypos+height,0.0f); glVertex3f(xpos+j*width/10,ypos+height-0.02f,0.0f); glVertex3f(xpos,ypos+j*height/10,0.0f); glVertex3f(xpos+0.02f,ypos+j*height/10,0.0f); glVertex3f(xpos+width,ypos+j*height/10,0.0f); glVertex3f(xpos+width-0.02f,ypos+j*height/10,0.0f); } glEnd(); double xmin,xmax,ymin,ymax,t0; struct Vector* y0; int steps; void (*f)(double,struct Vector*,struct Vector*); switch(in) { case 0: xmin = 0.0; xmax = 20; ymin = 0.0; ymax = 1.2; t0 = 0; y0 = new_Vector(DIM); y0->values[0] = 1; steps = (int)floor((xmax-xmin)/h+1); f = f1; break; case 1: xmin = 0.0; xmax = 0.999; ymin = 0; ymax = 15; t0 = 0; y0 = new_Vector(DIM); y0->values[0] = 0; steps = (int)floor((xmax-xmin)/h+1); f = f2; break; default: printf("Invalid argument: %i\n",in); break; } glColor4f(0.0f,0.0f,0.0f,1.0f); double* t = malloc(sizeof(double)*steps); double* values = malloc(sizeof(double)*steps); struct Vector** y = malloc(sizeof(struct Vector*)*steps); for (int j=1; j < steps; j++) { y[j] = new_Vector(DIM); } /* euler (f, t0, y0, h, t, y, steps); glColor4f(1.0f,0.0f,0.0f,1.0f); for (int j=0; j < steps; j++) { values[j] = y[j]->values[0]; } plotArray(t, values, steps, xmin, xmax, ymin, ymax, xpos, ypos, width, height); */ /* modEuler (f, t0, y0, h, t, y, steps); glColor4f(0.0f,0.0f,1.0f,1.0f); for (int j=0; j < steps; j++) { values[j] = y[j]->values[0]; } plotArray(t, values, steps, xmin, xmax, ymin, ymax, xpos, ypos, width, height); */ heun (f, t0, y0, h, t, y, steps); glColor4f(0.0f,1.0f,0.0f,1.0f); for (int j=0; j < steps; j++) { values[j] = y[j]->values[0]; } plotArray(t, values, steps, xmin, xmax, ymin, ymax, xpos, ypos, width, height); adaptive_rk3 (f, t0, y0, tol, t, y, steps); glColor4f(1.0f,0.0f,0.0f,1.0f); for (int j=0; j < steps; j++) { values[j] = y[j]->values[0]; } plotArray(t, values, steps, xmin, xmax, ymin, ymax, xpos, ypos, width, height); //Clean Up Memory free(t); for (int j=1; j < steps; j++) { delete_Vector(y[j]); } free(y); free(values); delete_Vector(y0); SDL_GL_SwapWindow(win); //Save PLot as BMP /* unsigned char* pixels = malloc(640*480*4*sizeof(unsigned char)); glReadPixels(0,0,640,480,GL_RGBA,GL_UNSIGNED_BYTE,pixels); SDL_Surface* sur = SDL_CreateRGBSurfaceFrom(pixels,640,480,8*4,640*4,0x000000FF,0x0000FF00,0x00FF0000,0); SDL_SaveBMP(sur,"test.bmp"); SDL_FreeSurface(sur); free(pixels); */ //Wait for Window Close Event SDL_Event event; while (SDL_WaitEvent(&event) >= 0) { if (event.type == SDL_QUIT) { SDL_GL_DeleteContext(context); SDL_DestroyWindow(win); SDL_Quit(); break; } } return 0; }
/* Run Program */ int main (int argc, char** argv) { //Read input argument int steps=1000; double h = 0.1; if (argc == 1){ printf("USAGE: NumberOfSteps StepSize/Tolerance\nExited.\n"); return 0; } if (argc > 1) steps = atoi(argv[1]); if (argc > 2) h = atof(argv[2]); printf("Input arguments: %i %f \n", steps, h); //Check if SDL Initialization is successful if (SDL_Init(SDL_INIT_VIDEO) != 0) { return -1; } //Create Window SDL_Window *win = SDL_CreateWindow("Exercise 5, Lorenz Equations",50,50,800,600,SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); if (!win) { fprintf(stderr, "Could not create window: %s\n", SDL_GetError()); } //Initialize OpenGL SDL_GLContext context = SDL_GL_CreateContext(win); if (!context) { fprintf(stderr, "Could not create OpenGL context: %s\n", SDL_GetError()); } glViewport(0,0,(GLsizei)800,(GLsizei)600); glClearColor(1.0f,1.0f,1.0f,1.0f); glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapWindow(win); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glEnable(GL_DEPTH_TEST); glFrustum(-100,100,-100,100,0.01,100); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1,1); glEnable(GL_LIGHTING); glShadeModel(GL_SMOOTH); GLfloat lightcol[] = {0.9,0.9,0.9,1.0}; GLfloat lightamb[] = {0.5,0.5,0.5,1.0}; GLfloat lightpos[] = {20.0,20.0,30.0,1.0}; glLightfv(GL_LIGHT0,GL_AMBIENT,lightamb); glLightfv(GL_LIGHT0,GL_DIFFUSE,lightcol); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); glEnable(GL_RESCALE_NORMAL); //Init all vectors double t0 = 0; double* t = malloc(sizeof(double)*steps); double* xValues = malloc(sizeof(double)*steps); double* yValues = malloc(sizeof(double)*steps); double* zValues = malloc(sizeof(double)*steps); double* xValues_it = malloc(sizeof(double)*steps); double* yValues_it = malloc(sizeof(double)*steps); double* zValues_it = malloc(sizeof(double)*steps); double xmin = -4; double xmax = 4; double ymin = -4; double ymax = 4; double xsteps = 21; double ysteps = 21; struct Matrix* X = new_Matrix(xsteps,ysteps); struct Matrix* Y = new_Matrix(xsteps,ysteps); struct Matrix* Z = new_Matrix(xsteps,ysteps); meshgrid(xmin,xmax,ymin,ymax,xsteps,ysteps,X,Y); paraboloid(X,Y,Z); struct Vector* vec0 = new_Vector(DIM); vec0->values[0] = 1; vec0->values[1] = 1; vec0->values[2] = 2; vec0->values[3] = 1-0.25; vec0->values[4] = -1-0.25; vec0->values[5] = -1; struct Vector** vec = malloc(sizeof(struct Vector*)*steps); for (int j=1; j < steps; j++) { vec[j] = new_Vector(DIM); } //find geodesic iteratively struct Vector** vec_it = malloc(sizeof(struct Vector*)*steps); vec_it[0] = vec0; for (int j=1; j < steps; j++) { vec_it[j] = new_Vector(DIM); geodesic_step(vec_it[j-1],h,vec_it[j]); } for (int j=0; j < steps; j++) { xValues_it[j] = vec_it[j]->values[0]; yValues_it[j] = vec_it[j]->values[1]; zValues_it[j] = vec_it[j]->values[2]; } //solve ODE //adaptive_rk3(geodesic_rhs,t0,vec0,h,t,vec,steps); euler(geodesic_rhs,t0,vec0,h,t,vec,steps); for (int j=0; j < steps; j++) { xValues[j] = vec[j]->values[0]; yValues[j] = vec[j]->values[1]; zValues[j] = vec[j]->values[2]; } SDL_GL_SwapWindow(win); /* Look Around Loop */ bool loop = true; bool wireframe = false; bool overlay = true; double xMouse = 0; double yMouse = 0; double xpos = 0; double ypos = 0; double zpos = 0; bool mouseDown = false; double mouseZoom = 0.1; SDL_Event event; while (loop) { while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { loop = false; } if (event.type== SDL_MOUSEBUTTONDOWN) { mouseDown = true; } if (event.type == SDL_MOUSEBUTTONUP) { mouseDown = false; } if (event.type == SDL_MOUSEMOTION) { if(mouseDown){ xMouse += 0.5*event.motion.xrel; yMouse += 0.5*event.motion.yrel; } } if (event.type== SDL_KEYDOWN) { if(event.key.keysym.scancode == SDL_SCANCODE_W) ypos += 0.1; if(event.key.keysym.scancode == SDL_SCANCODE_S) ypos -= 0.1; if(event.key.keysym.scancode == SDL_SCANCODE_A) xpos -= 0.1; if(event.key.keysym.scancode == SDL_SCANCODE_D) xpos += 0.1; if(event.key.keysym.scancode == SDL_SCANCODE_Q) zpos += 0.1; if(event.key.keysym.scancode == SDL_SCANCODE_E) zpos -= 0.1; if(event.key.keysym.scancode == SDL_SCANCODE_TAB) wireframe = !wireframe; if(event.key.keysym.scancode == SDL_SCANCODE_O) overlay = !overlay; } if (event.type== SDL_MOUSEWHEEL) { if (event.wheel.y < 0) mouseZoom /= 1.2; else mouseZoom *= 1.2; } } //Draw current frame buffer SDL_GL_SwapWindow(win); //Prepare next frame buffer glClearColor( 1.0f, 1.0f, 1.0f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslated(xpos, ypos, zpos); glScaled(mouseZoom,mouseZoom,mouseZoom); glRotated(-90, 1.0, 0.0, 0.0); glRotated(-yMouse, 1.0, 0.0, 0.0); glRotated(-xMouse, 0.0, 0.0, 1.0); plotAxis3D(-10,10,-10,10,-5,30,0,0,0); glColor4f(0.2,0.4,0.5,1.0); glLightfv(GL_LIGHT0,GL_POSITION,lightpos); if (wireframe) { glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); surf(X,Y,Z); } else { glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); surf(X,Y,Z); if (overlay) { glColor4f(0.2,0.2,0.2,1.0); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); surf(X,Y,Z); } } glColor4f(0.85,0.85,0.10,1.0); plotArray3D(xValues,yValues,zValues,steps); glColor4f(0.9,0.2,0.4,1.0); plotArray3D(xValues_it,yValues_it,zValues_it,steps); glColor4f(0.0,0.0,0.0,1.0); } //Clean Up Memory free(t); for (int j=1; j < steps; j++) { delete_Vector(vec[j]); } free(vec); free(xValues); free(yValues); free(zValues); delete_Vector(vec0); delete_Matrix(X); delete_Matrix(Y); delete_Matrix(Z); SDL_GL_DeleteContext(context); SDL_DestroyWindow(win); SDL_Quit(); return 0; }