コード例 #1
0
ファイル: intersect.c プロジェクト: gaibo/C
hit_test intersect(ray r, object obj) {
    v3 ro = r.origin;
    v3 rd = r.direction;
    double t;
    hit_test ht_out;
    
    switch (obj.tag) {
        case SPHERE: {
            v3 sc = obj.o.s.center;
            double sr = obj.o.s.radius;
            v3 A = v3_sub(ro, sc);
            double B = v3_dot(A, rd);
            double C = v3_dot(A, A) - sr*sr;
            double D = B*B - C;
            t = -B - sqrt(D);
            if (D > 0 && t > 0) {
                v3 ray_pos = ray_position(r, t);
                ht_out.miss = HIT;
                ht_out.t = t;
                ht_out.hit_point = ray_pos;
                ht_out.surf = \
                    (*(obj.o.s.surface_color))(obj.o.s.center, ray_pos);
                ht_out.shine = obj.o.s.shine;
                ht_out.surf_norm = v3_norm(v3_sub(ray_pos, obj.o.s.center));
            } else {
                ht_out.miss = MISS;
            }
            break;
        }
        case POSTER: {
            v3 n = v3_expr(0, 0, -1);
            double d = obj.o.p.upper_left.z;
            t = -(v3_dot(ro, n) + d) / v3_dot(rd, n);
            v3 ray_pos = ray_position(r, t);
            if (t > 0 && is_on_poster(ray_pos, obj.o.p)) {
                ht_out.miss = HIT;
                ht_out.t = t;
                ht_out.hit_point = ray_pos;
                ht_out.surf = \
                    (*(obj.o.p.surface_color))(obj.o.p.upper_left, ray_pos);
                ht_out.shine = obj.o.p.shine;
                ht_out.surf_norm = n;
            } else {
                ht_out.miss = MISS;
            }
            break;
        }
        default:
            fprintf(stderr, "error in intersect: unrecognized tag\n");
            exit(1);
    }
    
    return ht_out;
}
コード例 #2
0
hit_test intersect_cylinder (ray r, cylinder c) {
  hit_test result;
  v3 rp = v3_expr(r.direction.x,0,r.direction.z);
  double mp = v3_mag(rp);
  v3 np = v3_norm(rp);
  double xbar = r.origin.x - c.center.x;
  double zbar = r.origin.z - c.center.z;
  double a = pow(np.x,2) + pow(np.z,2);
  double b = 2 * ( (xbar*np.x) + (zbar*np.z) );
  double c1 = pow(xbar,2) + pow(zbar,2) - pow(c.radius,2);
  double d = pow(b,2) - (4*a*c1);
  result.miss = MISS;
  if(d >= 0) {
    double t_front = (-b - sqrt(d)) / (2*a);
    double t_back = (-b + sqrt(d)) / (2*a);
    v3 p_front = ray_position(r, t_front/mp);
    v3 p_back = ray_position(r, t_back/mp);
    if( (t_front < t_back) &&
	(t_front > 0) &&
	(p_front.y >= c.center.y) && (on_cylinder(p_front, c))) {
      result.miss = HIT;
      result.t = (t_front/mp);
      result.hit_point = p_front;
      result.surf = c.surface_color(c.center, p_front);
      result.shine = c.shine;
      v3 c2 = v3_expr(c.center.x, p_front.y, c.center.z);
      result.surf_norm = v3_norm(v3_sub(p_front,c2));
    } else if( (t_back > 0) &&
	       (p_back.y >= c.center.y) &&
	       (on_cylinder(p_back, c)) ) {
      result.miss = HIT;
      result.t = (t_back/mp);
      result.hit_point = p_back;
      result.surf = c.surface_color(c.center, p_back);
      result.shine = c.shine;
      v3 c3 = v3_expr(c.center.x, p_back.y, c.center.z);
      result.surf_norm = v3_norm(v3_sub(c3,p_back));
    }
  }
  return result;
}
コード例 #3
0
hit_test intersect_poster (ray r, poster p)
{
  hit_test result = {0};
  v3 ro = r.origin;
  v3 rd = r.direction;
  v3 n = v3_expr(0, 0, -1);
  double d = p.upper_left.z;
  double t = -(v3_dot(ro, n) + d) / v3_dot(rd, n);
  result.miss = MISS;
  v3 intersection = ray_position(r, t);
  if (t>0 && within_poster(intersection, p)) {
    result.miss = HIT;
    result.t = t;
    result.hit_point = intersection;
    result.surf = p.surface_color(p.upper_left, intersection);
    result.shine = p.shine;
    result.surf_norm = n;
  }
  return result;
}