Example #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;
}
Example #2
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;
}
Example #3
0
// return vec (dot) vec
double
xyz_norm_squared( const xyz_t * const vec)
{
  return xyz_dot( vec, vec);
}
Example #4
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};
Example #5
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;
}