Beispiel #1
0
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;
}
Beispiel #2
0
/* 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;
}
Beispiel #3
0
// 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);
}
Beispiel #4
0
// 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)));
    }
}
Beispiel #6
0
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;
    }
}
Beispiel #7
0
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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
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);
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
   }   
}
Beispiel #12
0
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;
}