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; }
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); }
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); } } }
/******************************************************************************* * 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; }