struct maybe_point sphere_intersection_point(struct ray r, struct sphere s){ struct maybe_point p; double A = dot_vector(r.dir,r.dir); double B = 2 * dot_vector(difference_point(r.p,s.center), r.dir); double C = dot_vector(difference_point(r.p,s.center), difference_point(r.p, s.center)) - s.radius*s.radius; double E = (-B+sqrt(B*B-4*A*C))/2/A; double F = (-B-sqrt(B*B-4*A*C))/2/A; if((E>0&& F>0)){ p.isPoint = 1; if(E>F) p.p = translate_point(r.p, scale_vector(r.dir,F)); else p.p = translate_point(r.p, scale_vector(r.dir,E)); }else if((E>0||F>0)){ p.isPoint = 1; if(E>0) p.p = translate_point(r.p, scale_vector(r.dir,E)); else p.p = translate_point(r.p, scale_vector(r.dir,F)); }else{ p.isPoint =0; p.p = create_point(0,0,0); } return p; }
/* rayliegh_quatient(double[], double[], uint32_t) * arg1: matrix (A[i][j] = A[i * cubic_matrix_size + j]) * arg2: vector * arg3: size of cubic matrix (A is (cubic_matrix_size, cubic_matrix_size) */ double rayliegh_quatient(double a[], double x[], uint32_t cubic_matrix_size){ double value = 0; double y[cubic_matrix_size]; produce_matrix_vector_product( a, x, y, cubic_matrix_size, cubic_matrix_size); value = dot_vector(y, x, cubic_matrix_size) / dot_vector(x, x, cubic_matrix_size); return value; }
// calculates the inverted flux, for testing purposes // it should return the same thing as riemann_solver(), only with minus sign void NumericalFlux::riemann_solver_invert(double result[4], double w_l[4], double w_r[4]) { double m[4][4]; double _w_l[4]; double _w_r[4]; double _tmp[4]; T_rot(m, M_PI); dot_vector(_w_l, m, w_l); dot_vector(_w_r, m, w_r); riemann_solver(_tmp, _w_r, _w_l); T_rot(m, -M_PI); dot_vector(result, m, _tmp); }
// Calculates the numerical flux in the normal (nx, ny) by rotating into the // local system, solving the Riemann problem and rotating back. It returns the // state as a 4-component vector. void NumericalFlux::numerical_flux(double result[4], double w_l[4], double w_r[4], double nx, double ny) { double alpha = atan2(ny, nx); double mat_rot[4][4]; double mat_rot_inv[4][4]; double w_l_local[4]; double w_r_local[4]; double flux_local[4]; T_rot(mat_rot, alpha); T_rot(mat_rot_inv, -alpha); dot_vector(w_l_local, mat_rot, w_l); dot_vector(w_r_local, mat_rot, w_r); riemann_solver(flux_local, w_l_local, w_r_local); dot_vector(result, mat_rot_inv, flux_local); }
struct maybe_point sphere_intersection_point(struct ray r, struct sphere s) { double a = dot_vector(r.dir, r.dir); double b = 2 * dot_vector(difference_point(r.p, s.center), r.dir); double c = dot_vector(difference_point(r.p, s.center), difference_point(r.p, s.center)) - (s.radius * s.radius); double disc = discriminant(a, b, c); double pos_result = pos_quadratic(a, b, c); double neg_result = neg_quadratic(a, b, c); double result; if (disc < 0) { return create_maybe_point(0, create_point(0.0, 0.0, 0.0)); } if (pos_result > 0 && neg_result > 0) { if (pos_result < neg_result) { result = pos_result; } else { result = neg_result; } } else if (pos_result > 0) { result = pos_result; } else if (neg_result > 0) { result = neg_result; } else { result = -1; } if (result > 0) { /*point is valid*/ return create_maybe_point(1, translate_point(r.p, scale_vector(r.dir, result))); } else { /* point is invalid*/ return create_maybe_point(0, translate_point(r.p, scale_vector(r.dir, result))); } }
void NumericalFlux::riemann_solver(double result[4], double w_l[4], double w_r[4]) { //printf("w_l: %f %f %f %f\n", w_l[0], w_l[1], w_l[2], w_l[3]); //printf("w_r: %f %f %f %f\n", w_r[0], w_r[1], w_r[2], w_r[3]); double _tmp1[4][4]; double _tmp2[4][4]; double _tmp3[4]; double _tmp4[4]; A_minus(_tmp1, w_r[0], w_r[1], w_r[2], w_r[3]); A_minus(_tmp2, w_l[0], w_l[1], w_l[2], w_l[3]); dot_vector(_tmp3, _tmp1, w_r); dot_vector(_tmp4, _tmp2, w_l); for (int i=0; i < 4; i++) { double _1 = f_x(i, w_l[0], w_l[1], w_l[2], w_l[3]); double _2 = _tmp3[i]; double _3 = _tmp4[i]; result[i] = _1 + _2 - _3; } }
void get_reflected_ray(t_ray* ray, t_object* obj, t_ray* new_ray) { new_ray->distance = 20000; mult_vector(&ray->dest, &new_ray->origin, ray->distance); add_vector(&new_ray->origin, &ray->origin, &new_ray->origin); get_normal(obj, &new_ray->origin, &new_ray->dest); mult_vector(&new_ray->dest, &new_ray->dest, dot_vector(&ray->dest, &new_ray->dest)); mult_vector(&new_ray->dest, &new_ray->dest, 2); sub_vector(&ray->dest, &new_ray->dest, &new_ray->dest); }
void color_cylinder(t_ray* ray, t_vector* inter, t_object* obj, t_color* clr) { t_vector normal; double angle; t_vector light; get_normal(obj, inter, &normal, ray); sub_vector(NULL, &ray->dest, &light); angle = dot_vector(&normal, &light); if (angle < 0.0) angle = 0.0; clr->r = obj->material.diffuse.r * AMBIANT_RED * angle; clr->g = obj->material.diffuse.g * AMBIANT_GREEN * angle; clr->b = obj->material.diffuse.b * AMBIANT_BLUE * angle; }
void get_refracted_ray(t_ray* ray, t_object* obj, t_ray* new_ray) { t_vector tmp; t_vector normal; double d[3]; t_ray* rays[2]; rays[0] = ray; rays[1] = new_ray; init_refraction(rays, &normal, obj, &tmp); d[0] = dot_vector(&tmp, &normal); d[1] = ray->refract / new_ray->refract; d[2] = asin(d[1] * sin(acos(d[0]))); mult_vector(&normal, &new_ray->dest, cos(d[2]) + d[1] * d[0]); mult_vector(&ray->dest, &tmp, d[1]); sub_vector(&tmp, &new_ray->dest, &new_ray->dest); normalize(&new_ray->dest); }
void get_rotation_all_matrix(t_transformation* t, t_vector* u, t_vector* v) { t_vector axis; double angle; double c; double s; id_memset(&t->rotation_all, 0, sizeof(t->rotation_all)); angle = acos(dot_vector(v, u)); c = cos(angle); s = sin(angle); prod_vector(u, v, &axis); t->rotation_all[0] = id_pow(axis.x, 2) + (1 - id_pow(axis.x, 2)) * c; t->rotation_all[1] = axis.x * axis.y * (1 - c) - axis.z * s; t->rotation_all[2] = axis.x * axis.z * (1 - c) + axis.y * s; t->rotation_all[4] = axis.x * axis.y * (1 - c) + axis.z * s; t->rotation_all[5] = id_pow(axis.y, 2) + (1 - id_pow(axis.y, 2)) * c; t->rotation_all[6] = axis.y * axis.z * (1 - c) - axis.x * s; t->rotation_all[8] = axis.x * axis.z * (1 - c) - axis.y * s; t->rotation_all[9] = axis.y * axis.z * (1 - c) + axis.x * s; t->rotation_all[10] = id_pow(axis.z, 2) + (1 - id_pow(axis.z, 2)) * c; t->is_rotation_all = 1; }
struct maybe_point sphere_intersection_point(struct ray r, struct sphere s) { double a = dot_vector(r.dir,r.dir); struct vector v=difference_point(r.p,s.center); double b = 2*dot_vector(v,r.dir); double c = dot_vector(v,v) - (s.radius*s.radius); if( (b*b-4*a*c)>0) //two real roots { double t1 = ( (-b+sqrt((b*b)-(4*a*c)))/(2*a)); double t2 = ( (-b-sqrt((b*b)-(4*a*c)))/(2*a)); if(t1>0 && t2>0) // ray hits sphere twice, need lower t value { if(t1<=t2) { struct maybe_point mp5; mp5.isPoint=1; mp5.p=translate_point(r.p,scale_vector(r.dir,t1)); return mp5; } else { struct maybe_point mp6; mp6.isPoint=1; mp6.p=translate_point(r.p,scale_vector(r.dir,t2)); return mp6; } } else if( (t1>0&&t2<0) || (t1<0&&t2>0) ) //t is positive and negative,need positive t value { if(t1>0) { struct maybe_point mp7; mp7.isPoint=1; mp7.p=translate_point(r.p,scale_vector(r.dir,t1)); return mp7; } else { struct maybe_point mp8; mp8.isPoint=1; mp8.p=translate_point(r.p,scale_vector(r.dir,t2)); return mp8; } } else //no intersection, both t's negative { struct maybe_point mp1; mp1.isPoint=0; mp1.p.x=0; mp1.p.y=0; mp1.p.z=0; return mp1; } } else if( (b*b-4*a*c)==0)//one real root { printf("oneroot!"); double t3 = -b/2*a; if(t3>0)//t is positive, so the ray intersects sphere tangentially { struct maybe_point mp2; mp2.isPoint=1; mp2.p=translate_point(r.p,scale_vector(r.dir,t3)); return mp2; } else //t is negative, so ray does not intersect sphere. //also includes the case where t==0, where the ray starting //point is on the sphere. am going to treat like non-intersection { struct maybe_point mp3; mp3.isPoint=0; mp3.p.x=0; mp3.p.y=0; mp3.p.z=0; return mp3; } } else // no real roots { struct maybe_point mp; mp.isPoint=0; mp.p.x=0; mp.p.y=0; mp.p.z=0; return mp; } }
int main(){ double a[ROW * COLUMN] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, }; double b[ROW * COLUMN] = { 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, }; double c[ROW * COLUMN] = {0.0}; double d[ROW] = {1.0, 2.0, 3.0}; double e[ROW] = {2.0, 5.0, 7.0}; double f[ROW] = {0.0}; uint32_t i = 0; uint32_t j = 0; /* * test add_matrix * */ /* show A */ printf("A\n"); for(i = 0; i < ROW; i++){ for(j = 0; j < COLUMN; j++) printf("%15.5lf", a[i * COLUMN + j]); printf("\n"); } printf("\n"); /* show B */ printf("B\n"); for(i = 0; i < ROW; i++){ for(j = 0; j < COLUMN; j++) printf("%15.5lf", b[i * COLUMN + j]); printf("\n"); } printf("\n"); /* calculate */ add_matrix(a, b, c, ROW, COLUMN); /* show C */ printf("C = A + B\n"); for(i = 0; i < ROW; i++){ for(j = 0; j < COLUMN; j++) printf("%15.5lf", c[i * COLUMN + j]); printf("\n"); } printf("\n"); /* * test dot_vector * */ /* show D */ printf("D\n"); for(i = 0; i < ROW; i++) printf("%15.5lf", d[i]); printf("\n\n"); /* show E */ printf("E\n"); for(i = 0; i < ROW; i++) printf("%15.5lf", e[i]); printf("\n\n"); /* calculate & show result */ printf("x = D dot E\n"); printf("%15.5lf",dot_vector(d, e, ROW)); printf("\n\n"); /* * test cross_vector * */ /* show D */ printf("D\n"); for(i = 0; i < ROW; i++) printf("%15.5lf", d[i]); printf("\n\n"); /* show E */ printf("E\n"); for(i = 0; i < ROW; i++) printf("%15.5lf", e[i]); printf("\n\n"); /* calculate */ cross_vector(d, e, f, ROW); /* show F */ printf("F = D x E\n"); for(i = 0; i < ROW; i++) printf("%15.5lf", f[i]); printf("\n"); return 0; }