Exemplo n.º 1
0
/* intersect_sphere : intersect func for spheres */
hit_test intersect_sphere(ray r, object obj)
{
  sphere s = obj.o.s;
  hit_test result;
  xyz A = xyz_sub(r.origin, s.center);
  double B = xyz_dot(A, xyz_norm(r.dir));
  double C = xyz_dot(A, A) - s.radius*s.radius;
  double D = B*B - C;
  double t = -B - sqrt(D);
  ray newr = {r.origin, xyz_norm(r.dir)};
  xyz loc = ray_position(newr,t);
  xyz v = xyz_sub(loc, s.center);
  xyz norm = xyz_norm(v);

  if(D<=0 || t<=0) 
    result.miss = MISS;
  else {
    result.miss = HIT;
    result.t = t;
    result.hit_point = loc;
    result.surf = s.surface_color(&obj, loc);
    result.shine = s.shine;
    result.surf_norm = norm;
  }
  return result;
}
Exemplo n.º 2
0
// return norm(a - b)
double
xyz_distance( const xyz_t * const a, const xyz_t * const b )
{
  xyz_t diff;
  xyz_diff( &diff, a, b);
  return xyz_norm( &diff );
}
Exemplo n.º 3
0
/* intersect_poster : intersect func for posters */
hit_test intersect_poster(ray r, object obj)
{
  poster p = obj.o.p;
  hit_test result;
  xyz n = xyz_expr(0, 0, -1);
  double d = p.upper_left.z;
  xyz rd = xyz_norm(r.dir);
  double t = -(xyz_dot(r.origin, n) + d)/xyz_dot(rd, n);
  ray newr = {r.origin, rd};
  xyz loc = ray_position(newr,t);
  xyz ul = p.upper_left;

  if (t>0 && 
      loc.x>=ul.x && 
      loc.x<=(ul.x+p.w) &&
      loc.y<=ul.y &&
      loc.y>=(ul.y-p.h)) {
    result.miss = HIT;
    result.t = t;
    result.hit_point = loc;
    result.surf = p.surface_color(&obj, loc);
    result.shine = p.shine;
    result.surf_norm = n;
  } else {
    result.miss = MISS;
  }
  return result;
}
Exemplo n.º 4
0
// vec *= new_norm/norm(vec)
void
xyz_normalize_self_to( xyz_t * vec, const double new_norm )
{
  xyz_scale_self( vec, new_norm/(xyz_norm(vec) + 1e-12) );
}
Exemplo n.º 5
0
// vec_out = vec_in*new_norm/norm(vec_in)
void
xyz_normalize_to( xyz_t * vec_out, const double new_norm, const xyz_t * const vec_in)
{
  xyz_scale( vec_out, new_norm/(xyz_norm(vec_in) + 1e-12), vec_in );
}
Exemplo n.º 6
0
int main()
{
  /* xyz */
  printf(" *** testing xyz *** \n");
  xyz v = xyz_expr(1,2,3);
  xyz add = xyz_add(v,v);
  xyz vv = xyz_expr(5,5,5);
  xyz sub = xyz_sub(v,vv);
  xyz n = xyz_neg(sub);
  xyz sc = xyz_scale(1.5,v);
  xyz sc2 = xyz_scale(-3.33,n);
  double dt = xyz_dot(v,sc);
  double mag = xyz_mag(v);
  xyz z = xyz_expr(0,0,0);
  xyz zn = xyz_norm(z);
  xyz vn = xyz_norm(v);
  
  printf("xyz_expr(1,2,3) =>\t%s\n",xyz_tos(v));
  printf("(1,2,3)+(1,2,3) =>\t%s\n",xyz_tos(add));
  printf("(1,2,3)-(5,5,5) =>\t%s\n",xyz_tos(sub));
  printf("-(-4,-3,-2) =>\t%s\n",xyz_tos(n));
  printf("scale (1,2,3) by 1.5 =>\t%s\n",xyz_tos(sc));
  printf("scale (4,3,2) by -3.33 =>\t%s\n",xyz_tos(sc2));
  printf("(1,2,3)*(1.5,3,4.5) =>\t%.2lf\n",dt);
  printf("magnitude of (1,2,3) =>\t%.2lf\n",mag);
  printf("norm (0,0,0) =>\t%s\n",xyz_tos(zn));
  printf("norm (1,2,3) =>\t%s\n",xyz_tos(vn));
  printf(" *****\n");

  /* color */
  printf(" *** testing color *** \n");
  color c = color_expr(1,0.5,0);
  color cc = color_expr(0.75,0,0.25);
  color mod = color_modulate(c,cc);
  color scc = color_scale(1.5, cc);
  color addc = color_add(c,cc);

  printf("color_expr(1,0.5,0) =>\t%s\n",color_tos(c));
  printf("(1,0.5,0)*(0.75,0,0.25) =>\t%s\n",color_tos(mod));
  printf("scale (0.75,0,0.25) by 1.5 =>\t%s\n",color_tos(scc));
  printf("(1,0.5,0)+(0.75,0,0.25) =>\t%s\n",color_tos(addc));
  printf("(0.75,0,0.25) on [0,255] =>");
  color_show_bytes(stdout,cc);
  printf(" *****\n");

  /* ray */
  printf(" *** testing ray *** \n");
  ray testray = {v,vv};
  printf("ray from (1,2,3) to (5,5,5) =>\t%s\n",ray_tos(testray));
  printf(" *****\n");

  /* sphere */
  printf(" *** testing sphere *** \n");
  sphere testsph = sphere_expr(v, 3.2, get_sc, c);
  printf("sphere at (1,2,3) with radius 3.2:\n");
  sphere_show(stdout,testsph);
  printf("\n *****\n");

  /* poster */
  printf(" *** testing poster *** \n");
  poster testpst = poster_expr(v, 4, 5.25, get_sc, c);
  printf("poster at (1,2,3) with width 4 and height 5.25:\n");
  poster_show(stdout,testpst);
  printf("\n *****\n");

  /* object */
  printf(" *** testing object *** \n");
  object objs = {SPHERE,{.s = testsph},NULL};
Exemplo n.º 7
0
int project_o_tron(aero_table_output_t * out,
		   aero_model_t * model,
		   quat_t ref_to_body, int w, int h, int *pix_buf_panel)
{

	int n = model->n_panels;

	// *** Input parameters
	xyz_t UU e_v_ref = { 1, 0, 0 };	// velocity unit vector in ref frame
	// todo: check that is normalized
	double res = 0.001 / MEGARES;	// Resolution
	double sig_n = 0.8;	// normal momentum exchange coeff
	double sig_t = 0.8;	// tangential momentum exchange coeff

	// *** Let's choose a new "freestream" frame so that the velocity vector is just +X
	quat_t body_to_fs;
	xyz_t e_v_fs = { 1, 0, 0 };
	// Don't need to rotate at all, the frames are already aligned
	// Now form the quaternion rotating the body frame to the freestream frame
	quat_inv(&body_to_fs, &ref_to_body);

	// *** Rotate "everything" into the new frame
	//

	//  Rotate the center of mass
	xyz_t cg_fs;
	rot_vec_by_quat_a2b(&cg_fs, &body_to_fs, &model->cg);

	//  Rotate the panels' coordinates 
	panel_t panels_fs[model->n_panels];
	for (int i = 0; i < n; i++) {
		rot_vec_by_quat_a2b(&panels_fs[i].origin, &body_to_fs,
				    &model->panels[i].origin);
		rot_vec_by_quat_a2b(&panels_fs[i].side_a, &body_to_fs,
				    &model->panels[i].side_a);
		rot_vec_by_quat_a2b(&panels_fs[i].side_b, &body_to_fs,
				    &model->panels[i].side_b);
	}

	//  Find the centroids
	xyz_t centroid_fs[n];
	for (int i = 0; i < n; i++) {
		centroid_fs[i] = panels_fs[i].origin;
		//  This handy function does (a <= a*A + b*B + c*C)
		xyz_sum_scale(&centroid_fs[i], 1, &panels_fs[i].side_a, 0.5,
			      &panels_fs[i].side_b, 0.5);
	}

	// Sort by the X coordinate of the centroids
	struct indirect_element sort_list[n];
	for (int i = 0; i < n; i++) {
		sort_list[i].index = i;
		sort_list[i].val = centroid_fs[i].x;
	}
	qsort(sort_list, n, sizeof(sort_list[0]), compare_indirect_elements);

	double *pix_buf_x = malloc(w * h * sizeof(double));
	// Holds the fs frame X coordinate
	// of the panel element at each pixel
	if (!pix_buf_x) {
		fprintf(stderr, "Unable to allocate %zu bytes for pix_buf_x\n",
			w * h * sizeof(double));
		return 1;
	}
	// Iterate over the panels, rearmost centroid first
	for (int i = 0; i < n; i++) {	// if(sort_list[i].index==0){
		panel_t *p = &panels_fs[sort_list[i].index];
		//printf("Panel %d:::\n",sort_list[i].index);

		double res_a = res / xyz_norm(&p->side_a) / sqrt(2);
		double res_b = res / xyz_norm(&p->side_b) / sqrt(2);

		// Iterate over side a
		for (double a = 0; a <= 1; a += res_a) {
			//  Iterate over side b
			for (double b = 0; b <= 1; b += res_b) {
				xyz_t panel_cell = p->origin;
				xyz_sum_scale(&panel_cell, 1, &p->side_a, a,
					      &p->side_b, b);
				int pix_y =
				    (int)round(panel_cell.y / res + w / 2);
				int pix_z =
				    (int)round(panel_cell.z / res + h / 2);
				pix_buf_panel[pix_z + pix_y * w] =
				    sort_list[i].index + 1;
				pix_buf_x[pix_z + pix_y * w] = panel_cell.x;
				//   printf("\t%+7.4f\t%+7.4f\t%d\t%d\n",panel_cell.y,panel_cell.z,pix_y,pix_z);
			}
		}
	}

	// Find the unit normal vector in fs frame, and e_v.e_n for all panels
	xyz_t e_n_fs[n];
	double e_v_dot_e_n[n];
	for (int p = 0; p < n; p++) {
		xyz_cross(&e_n_fs[p], &panels_fs[p].side_a,
			  &panels_fs[p].side_b);
		xyz_normalize_self(&e_n_fs[p]);
		e_v_dot_e_n[p] = xyz_dot(&e_n_fs[p], &e_v_fs);
//    if (e_v_dot_e_n[p] < 0)
//      printf("e_v dot e_n negative for panel %d\n",p);
	}

//  double A = 0;
	int n_pix[n];
	memset(n_pix, 0, sizeof(n_pix));
	xyz_t panel_sum_pos[n];
	memset(panel_sum_pos, 0, sizeof(panel_sum_pos));

	//printf("sizeof(n_pix)=%zu\n",sizeof(n_pix));

  xyz_t F_fs = {0, 0, 0};
  xyz_t T_fs = {0, 0, 0};

	// Now iterate over the pixels
	for (int pix_y = 0; pix_y < w; pix_y++)
		for (int pix_z = 0; pix_z < h; pix_z++) {
			int p = pix_buf_panel[pix_z + pix_y * w];
			if (p) {
				// There is a panel at this pixel.
        p--;  // Actual panel index number is one less

				if (e_v_dot_e_n[p] < 0) {
					// Skip panels facing the wrong way
					continue;
				}

				n_pix[p]++;

				// Find the coordinates in the fs frame
				xyz_t fs_p;
				fs_p.x = pix_buf_x[pix_z * w + pix_y];
				fs_p.y = (pix_y - w / 2) * res;
				fs_p.z = (pix_z - h / 2) * res;

				// Where is it wrt the center of mass?
				xyz_t r_from_cg_fs;
				xyz_diff(&r_from_cg_fs, &fs_p, &cg_fs);

				// Let's compute the forces on this element
				// ref: NASA SP-8058 eq 2-2 (page 5).
				// Dynamic pressure (1/2 rho v^2) factored out, hence leading 2 *
				xyz_t dF = { 0, 0, 0 };
				xyz_sum_scale(&dF, 0,
					      &e_n_fs[p],
					      2 * -1 * res * res * (2 - sig_n -
							       sig_t) *
					      xyz_dot(&e_v_fs, &e_n_fs[p]),
					      &e_v_fs, 2 * -1 * res * res * sig_t);

				// Torque contribution from this element
				xyz_t dT;
				xyz_cross(&dT, &r_from_cg_fs, &dF);

				xyz_sum(&F_fs, &F_fs, &dF);
				xyz_sum(&T_fs, &T_fs, &dT);

			}
		}


  rot_vec_by_quat_b2a(&out->force,  &body_to_fs, &F_fs);
  rot_vec_by_quat_b2a(&out->torque, &body_to_fs, &T_fs);
  
  printf("F = %f %f %f (norm=%f)\n",out->force.x, out->force.y, out->force.z, xyz_norm(&out->force));
  printf("T = %f %f %f (norm=%f)\n",out->torque.x, out->torque.y, out->torque.z, xyz_norm(&out->torque));
//	 printf("%d pixels dropped due to e_v dot e_n negative\n",n_pix);

	free(pix_buf_x);
	return 0;
}
Exemplo n.º 8
0
int main(int argc, char *argv[])
{
	char *filename_base;
	char filename_table[100];

  aero_model_t model;
	aero_env_t env;
	aero_table_output_t result;

	load_aero_model(&model, "");
	load_aero_env(&env, "");

  int w = 2 * 600 * MEGARES;
	int h = w;
	int *pix_buf = malloc(w * h * sizeof(int));
	if (!pix_buf) {
		fprintf(stderr, "Unable to allocate %zu bytes for pix_buf\n",
			w * h * sizeof(int));
		return 1;
	};

	if (argc > 2) {
		if (strlen(argv[2]) + 10 > sizeof(filename_table)) {
			printf("Specify a shorter filename, please (max %zu)\n",
			       sizeof(filename_table) - 10);
      return 1;
    }
		else
			filename_base = argv[2];
	}
  else {
    printf("syntax: %s {w|r} basename\n",argv[0]);
    return 1;
  }


	snprintf(filename_table, sizeof(filename_table), "%s.table",
		 filename_base);

  if (argv[1][0]=='r') {
    aero_table_t table;
    load_aero_table(&table,filename_table);
    
    aero_table_output_t result;
   
		sdl_open(w, h);

    for (int c=0; c<=1; c++)
    for (double a=-1; a<=1; a+=0.01)
      for (double b=-1; b<=1; b+=0.01) {
        if (a*a + b*b > 1.0001)
          continue;
        if (lookup_aero_table(&result,&table,a,b,c)) {
          printf("lookup fail for %.3f, %.3f, %d\n",a,b,c);
          continue;
        }
        double torque = xyz_norm(&result.torque);
        if (torque < 0.00015) {
          printf("Low torque position found: %.3f, %.3f, %d  (%.4f)\n",a,b,c, torque);
          quat_t att;

          att_of_params(&att,a,b,c);

			    memset(pix_buf, 0, w * h * sizeof(*pix_buf));
    			project_o_tron(&result, &model, att, w, h, pix_buf);

			    sdl_plot(w, h, pix_buf);

			    if (sdl_waitkey()) return 1;

        }

      }

    
    close_aero_table(&table);
    return 0;
  }

 if (argv[1][0]=='a') {
    aero_table_t table;
    load_aero_table(&table,filename_table);
    
    aero_table_output_t result;
   
		sdl_open(w, h);

    double a,b;
    int c;

    sscanf(argv[3],"%lf",&a);
    sscanf(argv[4],"%lf",&b);
    sscanf(argv[5],"%d",&c);


        if (lookup_aero_table(&result,&table,a,b,c)) {
          printf("lookup fail for %.3f, %.3f, %d\n",a,b,c);
          return 1;
        }
        double torque = xyz_norm(&result.torque);
          printf("Params: %.3f, %.3f, %d  (%.4f)\n",a,b,c, torque);
          quat_t att;

          att_of_params(&att,a,b,c);

			    memset(pix_buf, 0, w * h * sizeof(*pix_buf));
    			project_o_tron(&result, &model, att, w, h, pix_buf);

			    sdl_plot(w, h, pix_buf);

			    if (sdl_waitkey()) return 1;

        
    close_aero_table(&table);
    return 0;
  }



	FILE UU *table_file = fopen(filename_table, "wb");


  const double param_step = 0.02;
	

	int UU o = 0;


	double max_torque = 0;

  int UU col=1;

  int coverage[600][600];
  memset(coverage, 0, sizeof(coverage));

	memset(pix_buf, 0, w * h * sizeof(*pix_buf));


  int param_dim = round(2/param_step + 1);

  
  for (int c=0; c<2; c++)
  for (int ia = 0; ia < param_dim; ia ++) 
    {
  for (int ib = 0; ib < param_dim; ib ++) 
		{

    double a,b;
    a = 2.0 * ia / (param_dim-1) - 1;
    b = 2.0 * ib / (param_dim-1) - 1;

    if (a*a + b*b > 1.0001) {
      printf("skipping %f, %f\n",a,b);
      continue;
    }
    else   printf("@ %f, %f \n",a,b);


    quat_t att;

    att_of_params(&att,a,b,c);

/*
    if (c) 
      pix_buf[(int)(100*a)+120 + w * ((int)(100*b)+120)] = col;
    else
      pix_buf[(int)(100*a)+420 + w * ((int)(100*b)+120)] = col;
  
    col%=7;
    col++;
*/

			// printf("norm = %f\n",quat_norm(&att));

			memset(pix_buf, 0, w * h * sizeof(*pix_buf));

  

			project_o_tron(&result, &model, att, w, h, pix_buf);

			write_aero_table_entry(table_file, a, b,c, &result);

#ifdef DRAW
      /*
			// Plot some color squares at the top, as a crude key / legend
			for (int i = 0; i < model.n_panels; i++)
				for (int y = 0; y < 22; y++)
					for (int x = 0; x < 22; x++)
						pix_buf[x + 22 * 2 * i +
							y * w] = i + 1;
      */

			if (!o) {
				sdl_open(w, h);
				o = 1;
			}
			sdl_plot(w, h, pix_buf);
			if (sdl_poll_key()) goto end;
    //  if (sdl_waitkey()) goto end;
#endif

			double torque =
			    .5 * env.rho * env.v * env.v *
			    xyz_norm(&result.torque);
			if (torque > max_torque) {
				max_torque = torque;
				printf
				    ("New max torque, %.2f microNewton meters\n",
				     max_torque / 1E-6);
    //   if (torque > 4e-6 &&  sdl_waitkey()) goto end;
			}
		}
	}
#ifdef DRAW
 end:
  sdl_waitkey();
	sdl_close();
#endif
  fclose(table_file);
	free(pix_buf);
	return 0;
}