Пример #1
0
static float8 calc_tanimoto_distance(float8* array1, float8* array2, int32 dimension)
{
    if( array1 == NULL || array2 == NULL )
    {
        elog(ERROR, "In %s, arrays should not be NULL", __FUNCTION__);
    }
    
    float8 dot_product = calc_dot_product(array1, array2, dimension);
    float8 array1_l2norm = calc_l2norm_val(array1, dimension);
    float8 array2_l2norm = calc_l2norm_val(array2, dimension);
    
    float8 denominator = array1_l2norm*array1_l2norm+
        array2_l2norm*array2_l2norm-dot_product;
    float8 distance = dot_product/denominator;

    if (distance > 1.0) 
    {
        distance = 1.0;
    }
    else if (distance < 0) 
    {
        distance = 0;
    }

    return 1. - distance;
}
Пример #2
0
static float8 calc_cosine_distance(float8* array1, float8* array2, int32 dimension)
{
    if( array1 == NULL || array2 == NULL )
    {
        elog(ERROR, "In %s, arrays should not be NULL", __FUNCTION__);
    }
    
    float8 dot_product = calc_dot_product(array1, array2, dimension);
    float8 array1_l2norm = calc_l2norm_val(array1, dimension);
    float8 array2_l2norm = calc_l2norm_val(array2, dimension);

    float8 distance = dot_product/(array1_l2norm*array2_l2norm);

    if (distance > 1.0) 
    {
        distance = 1.0;
    }
    else if (distance < -1.0) 
    {
        distance = -1.0;
    }

    return acos(distance);
}
Пример #3
0
void MeshObject::recursive_orient(int face_index, 
                    float * faces_normals, 
                    int * faces_indices, 
                    int ** vertex_in_faces,
                    bool * visited) {
    
              
    if(visited[face_index])
        return;
        
    //mark this face as visited
    visited[face_index] = true;
    
    //current_face normal
    float current_face_normal[3] = {
        faces_normals[(face_index * 3)],
        faces_normals[(face_index * 3) + 1],
        faces_normals[(face_index * 3) + 2]
    };
    
    //vertex indices that is connected to the current_face
    int vi1 = faces_indices[(face_index * 3)];
    int vi2 = faces_indices[(face_index * 3) + 1];
    int vi3 = faces_indices[(face_index * 3) + 2];
    
    int i;
    for(i = 0; i < 9; i++) {
        //the face indexes that is connected to the current_face
        int fi1 = vertex_in_faces[vi1][i];
        int fi2 = vertex_in_faces[vi2][i];
        int fi3 = vertex_in_faces[vi3][i];
        
        if(fi1 != -1 && fi1 != face_index && !visited[fi1]) {
            float nface_normal[3] = {
                faces_normals[(fi1 * 3)],
                faces_normals[(fi1 * 3) + 1],
                faces_normals[(fi1 * 3) + 2]  
            };
            if(calc_dot_product(nface_normal, current_face_normal) < -0.1) {
                
                faces_normals[(fi1 * 3)] = -1 * faces_normals[(fi1 * 3)];
                faces_normals[(fi1 * 3) + 1] = -1 * faces_normals[(fi1 * 3) + 1];
                faces_normals[(fi1 * 3) + 2] = -1 * faces_normals[(fi1 * 3) + 2];
            }
        }
        if(fi2 != -1 && fi2 != face_index && !visited[fi1]) {
            float nface_normal[3] = {
                faces_normals[(fi2 * 3)],
                faces_normals[(fi2 * 3) + 1],
                faces_normals[(fi2 * 3) + 2]
            };
            if(calc_dot_product(nface_normal, current_face_normal) < -0.1) {
                faces_normals[(fi2 * 3)] = -1 * faces_normals[(fi2 * 3)];
                faces_normals[(fi2 * 3) + 1] = -1 * faces_normals[(fi2 * 3) + 1];
                faces_normals[(fi2 * 3) + 2] = -1 * faces_normals[(fi2 * 3) + 2];
            }
        }
        if(fi3 != -1 && fi3 != face_index && !visited[fi1]) {
            float nface_normal[3] = {
                faces_normals[(fi3 * 3)],
                faces_normals[(fi3 * 3) + 1],
                faces_normals[(fi3 * 3) + 2]
            };
            if(calc_dot_product(nface_normal, current_face_normal) < -0.1) {  
                faces_normals[(fi3 * 3)] = -faces_normals[(fi3 * 3)];
                faces_normals[(fi3 * 3) + 1] = -faces_normals[(fi3 * 3) + 1];
                faces_normals[(fi3 * 3) + 2] = -faces_normals[(fi3 * 3) + 2];
            }
        }
        if(fi1 != -1) {
            recursive_orient(fi1, 
                    faces_normals, 
                    faces_indices, 
                    vertex_in_faces,
                    visited);
        }
        if(fi2 != -1) {           
            recursive_orient(fi2, 
                    faces_normals, 
                    faces_indices, 
                    vertex_in_faces,
                    visited);
        }
        if(fi3 != -1) {    
            recursive_orient(fi3, 
                    faces_normals, 
                    faces_indices, 
                    vertex_in_faces,
                    visited);
        }
    }
}
Пример #4
0
/*******************************************************************************
 * For each pixel we must generate a primary ray and test for intersection with
 * all of the objects in the scene. If there is more than one ray-object
 * intersection then we must choose the closest intersection (the smallest
 * positive value of t).To ensure that there are no objects intersected in
 * front of the image plane (this is called near plane clipping), we keep the
 * distance of the primary ray to the screen and test all intersections against
 * this distance. If the t value is less than this distance, then we ignore the
 * object.
 *
 * If there is an intersection then we must compute the shadow rays and the
 * reflection rays. */
color_t trace_ray(ray3_t* test_ray, int depth) {
  int    occluded = 0;
  ray3_t shadow_ray;
  ray3_t reflected_ray;
  color_t ray_color = { 0.0, 0.0, 0.0, 0.0 };
  color_t nul_color = {0.0, 0.0, 0.0, 1.0};
  light_t* light_ptr = 0;
  double intersect_ray_length_curr = 0.0;
  double intersect_ray_length_close = 0.0;
  int     intersection_exists = 0;
  colored_sphere_t* sphere_close_ptr = 0;
  vector3_t intersection;
  vector3_t intersection_vector;
  int sphere_index = 0;
  int light_index = 0;
  int shadow_index;
  color_t add_color;

  /* test ray against all objects in scene, search until closest intersection
   * is found. */
  for (sphere_index = 0; sphere_index < sphere_list_count; ++sphere_index) {
    colored_sphere_t* sphere_ptr = &sphere_list[sphere_index];

    /* test for intersection between ray and scene object */
    if (1 == find_ray_sphere_intersect(test_ray, &sphere_ptr->sphere, &intersect_ray_length_curr)) {
      if (intersect_ray_length_curr < 0.0)
        continue;

      if (0 == intersection_exists) {
        intersection_exists = 1;
        intersect_ray_length_close = intersect_ray_length_curr;
        sphere_close_ptr = sphere_ptr;
      }
      else if (intersect_ray_length_curr < intersect_ray_length_close) {
        intersect_ray_length_curr = intersect_ray_length_close;
        sphere_close_ptr = sphere_ptr;
      }
    }
  }

  if (1 == intersection_exists) {
    intersection.x = test_ray->origin.x + test_ray->vector.x * intersect_ray_length_close;
    intersection.y = test_ray->origin.y + test_ray->vector.y * intersect_ray_length_close;
    intersection.z = test_ray->origin.z + test_ray->vector.z * intersect_ray_length_close;

    shadow_ray.origin = intersection;

    /* Shadow rays are sent towards all light sources to determine if any objects occlude the intersection spot. */
    for (light_index = 0; light_index < light_list_count; ++light_index) {
      occluded = 0;
      light_ptr = &light_list[light_index];
      shadow_ray.vector.x = (light_ptr->origin.x - shadow_ray.origin.x);
      shadow_ray.vector.y = (light_ptr->origin.y - shadow_ray.origin.y);
      shadow_ray.vector.z = (light_ptr->origin.z - shadow_ray.origin.z);
      normalize_vector(&shadow_ray.vector);

      /* Test intersection to determine if ray is in occlusion. */
      for (shadow_index = 0; shadow_index < sphere_list_count; ++shadow_index) {
        if (1 == find_ray_sphere_intersect(&shadow_ray, &sphere_list[shadow_index].sphere, &intersect_ray_length_curr)) {
          occluded = 1;
          break;
        }
      }

      if (occluded == 0) {
        /* Calculate the total light intensity. */
        double light_intensity = calc_dot_product(&shadow_ray.vector, &test_ray->vector);
        if (light_intensity < 0.0) light_intensity = -light_intensity;

        ray_color = mix_colors(&nul_color, &sphere_close_ptr->color, light_intensity);

        if (depth < 4) {
          reflected_ray.origin.x = intersection.x;
          reflected_ray.origin.y = intersection.y;
          reflected_ray.origin.z = intersection.z;

          intersection_vector.x = (intersection.x - sphere_close_ptr->sphere.center.x);
          intersection_vector.y = (intersection.y - sphere_close_ptr->sphere.center.y);
          intersection_vector.z = (intersection.z - sphere_close_ptr->sphere.center.z);

          normalize_vector(&intersection_vector);
          calc_reflected_vector(&reflected_ray.vector, &test_ray->vector, &intersection_vector);

          add_color = trace_ray(&reflected_ray, ++depth);
          if ((add_color.r != 0x00) ||
              (add_color.g != 0x00) ||
              (add_color.b != 0x00)) {
            double mix_ratio = calc_dot_product(&reflected_ray.vector, &intersection_vector);
            if (mix_ratio < 0.0) mix_ratio = -mix_ratio;
            ray_color = mix_colors(&ray_color, &add_color, mix_ratio);
          }
        }
      }
    }
  }

  return ray_color;
}