/* 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); } }
void ft_impact(t_draw_suite *val, t_ray *ray, t_tool *t) { val->impact->o = vectoradd(ray->o, vectorscale(val->curobject->dist, ray->d)); find_normal(val->impact, val->curobject); vectornorm(val->impact->d); init_color(t, val->curobject->color, val->final_color); val->curlight = t->l_lights; while (val->curlight) { val->lightray->o = vectorcopy(val->curlight->o); val->lightray->d = vectorsub(val->impact->o, val->lightray->o); vectornorm(val->lightray->d); if ((val->curobject2 = intersection(t->l_objects, val->lightray)) && val->curobject2 == val->curobject) ft_impact2(val); val->curlight = val->curlight->next; } }
/*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; }
void ft_impact2(t_draw_suite *val) { val->invlight = vectorscale(-1, val->lightray->d); val->kdiff = vectordot(val->invlight, val->impact->d) * MAX((val->curlight->dist - val->curobject->dist) / val->curlight->dist, 0); if (val->kdiff >= 0) { update_color(val->kdiff * 1, val->curlight->color, val->final_color, val->curobject->color); val->reflectray = rotation(val->impact->d, val->invlight); vectornorm(val->reflectray); val->kspec = vectordot(val->invlight, val->reflectray); if (val->kspec >= 0) update_color(pow(val->kspec, 20) * MAX((val->curlight->dist - val->curobject->dist) / val->curlight->dist, 0) * val->curobject->shiny, val->curlight->color, val->final_color, val->curobject->color); } }
t_ray *get_ray(t_tool *t, double x, double y) { t_ray *ray; t_pos *b; ray = malloc(sizeof(t_ray)); ray->o = malloc(sizeof(t_pos)); b = malloc(sizeof(t_pos)); ray->o->x = t->cam->pos->x; ray->o->y = t->cam->pos->y; ray->o->z = t->cam->pos->z; b->x = t->cam->upleft->x + t->cam->r_vect->x * t->cam->indent * x - t->cam->h_vect->x * t->cam->indent * y; b->y = t->cam->upleft->y + t->cam->r_vect->y * t->cam->indent * x - t->cam->h_vect->y * t->cam->indent * y; b->z = t->cam->upleft->z + t->cam->r_vect->z * t->cam->indent * x - t->cam->h_vect->z * t->cam->indent * y; ray->d = vectorsub(b, ray->o); vectornorm(ray->d); free(b); return (ray); }